% 0:01:47 J2: Wir haben heute hier einen Task, hier am NewsPlugin etwas zu machen. Im großen Ganzen geht’s um Refactoring von den ganzen Klassen, weil die schon relativ alt sind. Du weißt ja, wie bei mir normalerweise alte Klassen aussehen (!!...!!) J1: richtig ja. J2: die etwas älter sind. Es geht zum einen um Refactoring zum anderen würde ich gerne diese Samba-File-Geschichte loskriegen, das heißt Zugriff auf das DFS via Samba. J1: M-hm. J2: Und ersetzen durch Zugriffe auf’s lokale Dateisystem mit Linux-Freigaben. J1: M-hm. J2: Weil das einfach die Stabilität deutlich verbessert. J1: Ja klar. % 0:02:29 J2: Kennst du das NewsPlugin, oder kennst du das nicht? J1: zeig’s mir einfach noch mal. J2: Das mit dem Nachrichten-Mitschnitt, ich glaube wir sharen mal. % 0:02:38 % Das Paar startet eine Saros-Sitzung. % 0:04:09 J2: OK, aber ich kann dir ja schon mal sagen, was dieses Plugin im Großen und Ganzen tut. J1: Ja % 0:04:15 J2: Also hinten raus ploppt der Nachrichten-Mitschnitt von jeder Stunde. J1: M-hm. J2: Die Vorgehensweise ist so, es gibt mehrere (.) Processors, also es gibt das zentrale Plugin, dann gibt es mehrere Processors, die sich alle um eine Welle jeweils kümmern. J1: <*nickt*> J2: Ähm. (.) Bei den meisten ist es so, dass kurz nach der vollen Stunde geprüft wird, ob auf dem Share ein, oder, ob es auf dem entfernten Share eben eine neue Datei vorliegt. Wenn ja, (.) äh wird die letzte Datei ausgewählt und es wird angefangen zu prüfen, wie die sich in ihrer Größe sich noch verändert. J1: <*hört auf zu nicken, schaut nach rechts oben*> J2: Das heißt, es wird so lange geguckt, bis die Datei nicht mehr größer wird, dann ist sie wohl fertig. J1: M-hm J2: Und dann wird sie abgeholt und zur Transkodierung gegeben. % 0:05:00 J1: In was für nem Zeitfenster wird dann geguckt? % 0:05:03 J2: Ich fange an zu gucken um zwei Minuten nach der vollen Stunde, weil da garantiert ist, dass dann Nachrichtendateien vorliegen wenn welche vorliegen. J1: OK J2: Und monitor’ dann eben so lange diese Datei bis sie fertig ist. Das kann bis zu sieben Minuten dauern, je nach Welle. % 0:05:19 J1: Hm genau, aber mh, also das Zeitfenster für die Veränderung? J2: Ja genau, das ist, äh, Zeitfenster für die Veränderung, das ist variabel, je nachdem wie die Nachrichten gehen. Das weiß ich ja nicht. Also es ist so, dass, die legen automatisch immer ne neue Datei an. Wenn die Nachrichten zu Ende sind, wird wieder ne Datei angelegt. Das heißt, ich hab quasi nie mehr als die Nachrichten. J1: Ja, nee, ich mein jetzt nur weil du sagst, du guckst halt so lange, ähm, äh, bis die Größe aufhört sich zu ändern, ja? % 0:05:48 J2: M-hm J1: Musst du ja noch ’nen gewisses Zeitfenster noch einplanen, in der immer noch ’ne Verände- rung stattfinden könnte. J2: Ja gut, bis maximal fünf vor der neuen Stunde. Also, ich warte wirklich lange. % 0:06:00 J1: Nee, ich mein tatsächlich die Größe jetzt, die Größe des Zeitfensters, also (.) du wartest 10 Sekunden, dann nach 10 Sekunden entscheidest du, in den 10 Sekunden hat sich jetzt nichts mehr verändert, dann ist die Datei wohl fertig. J2: Achso, das meinst du, nee 30 Sekunden. J1: 30 Sekunden, das wollt ich wissen. % 0:06:12 J2: Das ist 30 Sekunden lang das Zeitfenster. Jetzt hab ich dich verstanden. % 0:06:15 J2: Aber kann ich dir gleich zeigen. J1: Ja. Und das NewsPlugin macht jetzt in dieser ganzen Sache was davon? Also, genau dieses Monitoring und dann die Delegation an die einzelnen Wellen-Plugins, oder? J2: Nee. Das NewsPlugin kümmert sich eigentlich nur darum (!...!) das wird eben periodisch aufgerufen vom Cron-Server [...] % 0:06:33 % 0:08:27 J2: Die Funktion ist extrem lang, aber die lässt sich eigentlich ganz gut auch aufspalten, denke ich. Also da sollten wir nachher im Zuge des (!...!) oder jetzt im Zuge des Refactorings vielleicht mal drübergehen. Weil ich denke, dass vor allem nachher, wenn wir die Dateien austauschen wollen, oder den Zugriff auf die Dateien austauschen wollen, wir (!...!) das in kleinen Bröckchen irgendwie besser geht, also wenn wir da ne bessere Übersicht haben. J1: Ja. J2: Teilst du meine Ansicht? J1: Ja. Ähm, gibts, können, gnah. J2: Wenn können auch gerne durchgehen, wenn du magst. J1: (.) Ja? (....) Ähm, wie isses denn (!...!) ja, lass’ uns mal durchgehen. J2: Also, wir haben hier [...] % 0:09:19 % 0:09:32 J1: Wir gehen rein mit der currentTime. J2: Genau, currentTime, das ist der aktuelle Zeitstempel beim Aufruf. J1: Beim Aufruf, wozu braucht er die (von außen)? J2: Brauch ich noch öfters zum Beispiel hier bei getLastFile<*selektiert Statement*>, wenn er sich die (!...!) damit er ne Vergleichszeit hat, ne? J1: Ja, nee, ich meine, warum muss das von außen reingegeben werden? Also, die Funktion weiß doch eigentlich auch selber wie viel Uhr wir haben. J2: Dass jeder Processor die gleiche Zeit kriegt. J1: OK (.) ja. % 0:10:01 J2: <*öffnet Datei*> Also wir haben hier, siehste ja, Zeile 85 <*markiert diese Zeile*>, dass wir die currentTime hier speichern und dann kriegt jeder dieselbe. Also das ist die Zeit beim Aufruf. Deswegen habe ich die von außen reingegeben. Aber du hast Recht, wir können nachher mal prüfen, inwiefern wir die da dringend brauchen, also dass jeder dieselbe Zeit hat. Weil dann könnten wir das auch nach innen verlagern, weil es ist natürlich schon ein bisschen komisch, warum man die currentTimehier braucht. J1: Das wäre jetzt halt meine nächste Frage gewesen, warum die halt (!...!) % 0:10:31 J1: Gibt’s nen zwingenden Grund, dass alle NewsProcessors die gleiche (Zeit)? % 0:10:39 % 0:13:15 J2: Und setzt aber dafür das remoteNewsFile. Und zwar kriegt er das aus der Funktion getLastFile. Das wäre ne Funktion, die es nachher auch zu ersetzen gilt. [...] Sollen wir in die Funktion reingehen, oder? J1: Nee, erstmal nicht bitte. J2: Erstmal nicht, ok. % 0:13:43 % 0:14:15 J1: Kann das (!!...!!) Ist das nen erwarteter Fall, also kann das passieren? J2: Also das ist der Fall wenn er nichts gefunden hat. J1: Aber sollte das passieren? Das sollte eigentlich nicht passieren, gell? J2: So, und wenn die Minute nicht (!...!) wenn es nicht zwei nach der vollen Stunde ist, dann NOOP, macht er halt nix. J1: <**J2s Name**>? Hörst du mich? J2: Ja. J1: OK. % 0:14:35 J1: In diesen Fall hier mit dem Error sollte er eigentlich niemals reinrutschen, wenn alles glatt läuft, richtig? J2: Wenn alles glatt läuft, nie reinrutschen, genau. J1: (OK) J2: Also wenn er ne Datei gefunden hat, dann rutscht er da auch nicht rein. Ja? <*selektiert return-Statement im default-Fall*> Weil dann ist er ja in diesem FileTracking-Modus. (..) Ja? (.) Oder nein? Warum sagst du nix? % 0:14:58 % 0:19:13 J2: Ok, dann haben wir hier (!...!) öh, ja, es wird halt kopiert. Siehst du ja hier, Zeile 101 <*setzt Cursor in Zeile 101*>. Und zwar in die Datei localNewsFile <*selektiert this.localNewsFile in Zeile 101*>. (..) <*setzt Cursor in Zeile 102*> kopiert er das hier (!!Moment!!) ähm J1: Momentmomentmoment J2: Hm? J1: Kurz gucken. J2: (....) Was meinst? J1: OK. Ne, ich hab die Zeile nur nicht gelesen gehabt. J2: OK. J1: (..) OK, ja. % 0:19:39 % 0:22:59 J1: Weil du die in ner Klassenvariable gespeichert hast [...] Warum muss remoteNewsFile in der Klasse selbst definiert sein? Warum reicht das nicht, das in der Methode zu machen? J2: Ähm, das remoteNewsFile? Du meinst, warum es hier nicht reicht? J1: Ja, das remoteNewsFile. J2: Lass mal überlegen, ob der <**J1s Name**> da recht hat. <*beginnt zu scrollen*> J1: <*liest im Code*> Es gibt ein Aufreten [...] % 0:23:48 % 0:24:16 J2: Ja, also diese (!...!) man sollte es vielleicht so sagen: Die muss ich mir merken, denn diese execute-Methode, <**J1s Name**>, die wird alle 30 Sekunden aufgerufen. J1: Ja? J2: Das heißt, ich muss mir ja den Status speichern. Wenn ich mir die Datei von remote geholt habe und dann das FileTracking mache, muss ich mir ja ne Referenz darauf speichern. (..) Ich will’s ja nicht jedes Mal (..) neu anlegen. Kann ich ja gar nicht. % 0:24:44 % 0:27:47 J1: Das heißt, die gesamte Funktionalität hier oben ist eigentlich über alle anderen News-Plugins, also die Unter-News-Plugins, gleich. Sehe ich das richtig, oder? J2: Nee, das ist nicht korrekt. Denn, die sind alle so’n bisschen unterschiedlich. J1: ‘So’n bisschen unterschiedlich’, ok? J2: Ja, es ist etwas problematisch hier [...] J1: Das heißt, jede einzelne Klasse mit ‘_News’ am Ende macht was eigenes in der execute-Methode. J2: Ja, die wird überschrieben. Siehst du ja auch hier (!!...!!) J1: Jaja, das sehe ich. Aber, äh, das, womit es überschrieben wird, ist halt wirklich, also, wenn du zwei beliebige Dateien nimmst und die vergleichst, sind die immer irgendwie unterschiedlich. J2: Die sind unterschiedlich, ja! % 0:28:44 J2: Das ist gleich für <**Alpha**> und <**Beta**>. [...] J1: Und deswegen ist es in AlphaNews. J2: Warte mal, wenn du jetzt (!!...!!) J1: Also wenn ich jetzt Alpha_Newsund Beta_Newsvergleichen würde, dann wäre es nicht unterschiedlich. % 0:28:57 J2: Ja, dann guck dir bitte mal Beta_News an. <*öffnet Beta_News, scrollt in die Mitte der Datei*> Ich hab sie gerade offen. Du siehst, hier gibt es keine execute-Methode. J1: <*springt zu J2s Position*> Da gibt es tatsächlich keine execute-Methode. J2: Nein, weil für die beiden ist es gleich. J1: Und das heißt? J2: Wie, ‘das heißt’? % 0:29:18 J1: Das heißt, äh, wo ist denn die execute-Methode für <**Beta**>? J2: Ja die execute-Methode von <**Beta**> entspricht der von <**Alpha**>. J1: Ja, klar. Aber da muss ja irgendwo eine Verbindung hergestellt werden. [...] J2: Ich verstehe die Frage nicht. Es tut mir leid. [...] J1: [...] ach (#extends Alpha_News#) % 0:29:47 % 0:40:29 J1: <*hat Code-Block selektiert, ruft Refactoring “Extract Method” auf*> Was macht das alles? J2: Also es guckt eigentlich nur nach der Dateigröße [...] und lädt sie runter. J1: <*tippt den Methodennamen “downloadRemoteFile”, klickt “Extract”*> J2: Deswegen wollt ich nämlich hier oben dann <*selektiert einige Zeilen*>, damit wir das irgendwie unterteilen könnten (!!...!!) J1: <*Fehlermeldung geht auf*> Funktioniert so noch nicht. J2: Also hier (!!...!!) J1: <*schließt Fehlermeldung, liest Quellcode*> Stimmt, ja der macht ja nen return, genau. J2: Also (!!...!!) J1: Das funktioniert noch nicht. % 0:40:42 % 0:53:56 J1: Ahja, das heißt diesen <*selektiert Zeilen 88 bis 105*> (!...!) das heißt diesen Fall können wir eigentlich mal in das try [Zeilen 76 bis 79] reinziehen, oder? J2: Das können wir ( , , ) das, nein! Nein-nein-nein-nein-nein-nein-nein. Können wir nicht, weil <*Cursor zu Zeile 51, selektiert if-Schlüsselwort für J1*> bedenke bitte in Zeile einundfünfzig <*selektiert ganzes if-Statement für J1*> das localNewsFile J1: Zeile einundfünfzig, was? J2: Das können wir können wir nicht machen. J1: Achso, du meinst <*scrollt nach oben*> dass wir (!...!) J2: Was wir aber machen können (!!...!!) J1: Aargh-ha-ha-ha urgh , oh Gott. Ja, du hast recht, du hast recht. % 0:54:34 % 0:58:23 J2: Wo fang ich an zu erklären? Das ist nämlich etwas komplizierter wie du denkst. J1: Sicherlich. J2: Weil wenn <**Welle Alpha**> oder <**Welle Beta**> keine eigenen Nachrichten haben, wenn das bei denen irgendwie ausfallen sollte, dann übernehmen sie diese <**fallback**>-Nachrichten. Und je nach dem, wenn es ihre eigenen sind, also wenn das Konstrukt hier hinten true ist <*zeigt auf Code*>, dann sind es ihre eigenen Nachrichten-Dateien, dann soll er sie löschen. Wenn es die <**fallback**>-News sind, soll er sie natürlich nicht löschen, weil es ja noch eventuell noch andere gibt, die die auch noch benötigen. Ja? Aber das kann man in Zukunft alles etwas anders gestalten (!!...!!) J1: <*schüttelt den Kopf*> Andere Baustelle, andere Baustelle, das ist (!!...!!) J2: Ja, das ist ist noch ne andere Baustelle. Das habe ich nur deswegen gemacht, weil der Download immer so lange gedauert hat, von so ner blöden Nachrichten-Datei. Da habe ich mir gedacht, da muss es nicht noch länger dauern, dann verwende ich für alle dieselbe. Wenn das nachher auf dem lokalen Dateisystem läuft, dann geht das natürlich bedeutend schneller und dann kann man die auch zweimal runterladen. % 0:59:32