Seite 1 von 1

Ein Beispiel für Datenstreaming mit TML (The Missing Link)

Verfasst: Montag 7. Juli 2014, 09:04
von maik_tml
Hi,

Bei der Entwicklung von Peer2Peer Netzwerken, die dazu eingerichtet werden, um große Mengen von Daten zu verarbeiten (Cluster), muss neben der Kommunikation der Knoten auch die Übertragung grosser Datenmengen sicher gestellt werden. Auch bei einfachen Anwendungen, wie (mein lieblingsbeispiel) einem Chat in dem Dateien ausgetauscht werden, sollte das verwendete Protokoll Streaming zur Verfügung stellen, um ein zweites Protokoll für die Dateiübertragung zu vermeiden.

Aus diesem Grund haben wir im TML (The Missing Link) Protokoll auch eine Streaming API implementiert. In Python kann diese mit eigenen von einer Basisklasse abgeleiteten Objekten verwendet werden.

Hier ein Beispiel für eine Funktion, die eine Datei von einem anderen Peer speichert.

Code: Alles auswählen

def save_file(self, afilename, chunksize=1024):
   sfile = open(afilename, 'wb')

   chunks = int(self.size/chunksize)+1
   assert chunks*chunksize >= self.size, "download calculation invalid"

   self.seek(0, tml.constants.SO_FROM_BEGINNING)
   for c in range(0, chunks):
       buffer = self.read(chunksize)
       sfile.write(buffer)

   sfile.close()
Eine Ausfürliche Beschreibung dieses Beispiels findet ihr hier: https://www.tml-software.com/knowledgeb ... cle/20/86/

Re: Ein Beispiel für Datenstreaming mit TML (The Missing Lin

Verfasst: Mittwoch 9. Juli 2014, 15:41
von darktrym
Schön und gut das du hier Werbung für deinen Arbeitgeber machst, aber könnte der Code nicht wesentlich schicker sein?

Es fängt schon damit an, das range(0, BLUB) identisch mit range(BLUB) ist. Int ist unnötig wenn man // verwendet und with statt close. Und warum verwendet man die Variable buffer? Dazu noch eigene Konstanten verwenden statt die Standardwerte.

SO_FROM_BEGINNING = 0
SO_FROM_CURRENT = 1
SO_FROM_END = 2

Re: Ein Beispiel für Datenstreaming mit TML (The Missing Lin

Verfasst: Mittwoch 9. Juli 2014, 23:10
von BlackJack
Was soll `sfile` bedeuten? Ich hätte ja auf `source_file` getippt, aber es scheint ja das Ziel zu sein. Das sollte man mit dem `shutil`-Modul etwas kompakter schreiben können:

Code: Alles auswählen

    def save_file(self, filename, chunksize=1024):
        with open(filename, 'wb') as target_file:
            self.seek(0, tml.constants.SO_FROM_BEGINNING)
            shutil.copyfileobj(self, target_file, chunksize)

Re: Ein Beispiel für Datenstreaming mit TML (The Missing Lin

Verfasst: Donnerstag 10. Juli 2014, 07:07
von Sirius3
Der Name ist irgendwie unpassend. Es wird ja kein File gespeichert, sondern das Objekt in eine Datei, also entweder nur 'save' oder 'save_to_file'. Das seek scheint mir auch seltsam, wenn nicht sogar gefährlich. Bei einer Methode die etwas speichert (also eine Ausgabe-Methode), erwarte ich nicht, dass sich gleichzeitig ihr interner Zustand ändert. Also richtigerweise:

Code: Alles auswählen

    def save_file(self, filename, chunksize=1024):
        current_position = self.tell()
        self.seek(0, tml.constants.SO_FROM_BEGINNING)
        with open(filename, 'wb') as target_file:
            shutil.copyfileobj(self, target_file, chunksize)
        self.seek(current_position, tml.constants.SO_FROM_BEGINNING)

Re: Ein Beispiel für Datenstreaming mit TML (The Missing Lin

Verfasst: Donnerstag 10. Juli 2014, 07:34
von BlackJack
Da würde ich das zurücksetzen noch durch ein ``try``/``finally`` absichern:

Code: Alles auswählen

    def save_file(self, filename, chunksize=1024):
        current_position = self.tell()
        try:
            self.seek(0, tml.constants.SO_FROM_BEGINNING)
            with open(filename, 'wb') as target_file:
                shutil.copyfileobj(self, target_file, chunksize)
        finally:
            self.seek(current_position, tml.constants.SO_FROM_BEGINNING) 
Oder falls man das bei der API öfter brauchen sollte, einen Kontextmanager schreiben und ``with`` verwenden:

Code: Alles auswählen

from contextlib import contextmanager

@contextmanager
def saved_position(seekable):
    current_position = seekable.tell()
    yield seekable
    seekable.seek(current_position, tml.constants.SO_FROM_BEGINNING)

# ...

    def save_file(self, filename, chunksize=1024):
        with saved_position(self):
            self.seek(0, tml.constants.SO_FROM_BEGINNING)
            with open(filename, 'wb') as target_file:
                shutil.copyfileobj(self, target_file, chunksize)

Re: Ein Beispiel für Datenstreaming mit TML (The Missing Lin

Verfasst: Samstag 30. August 2014, 17:37
von Pethi
Was soll das sfile aussagen?