1. Das Debuggen wird schwer.
Egal, ob ich die Doku von einer Standardoperation nicht richtig
verstanden habe oder einfach einen Fehler in meinem Flow habe oder
gar ein Fehler in der Runtime existiert.
Ich muss (vermutlich; habe ich in diesem Fall noch nicht
verifiziert) durch die Runtime debuggen um den Fehler aufspueren zu
koennen.
Das ist sehr viel Code, den ich vorher noch nie gesehen geschweige
denn geschrieben habe. Die meisten Entwickler geben da nach kurzer
Zeit auf.
2. Die Operationen koennen nicht beliebig klein sein.
Spaetestens, wenn sie die Groesse des Runtime-Overheads erreicht
haben ist Schluss.
Persoenlich bevorzuge ich moeglichst kleine und generische
Operationen.
Eine "Standard-DSL" waere eine tolle Sache.
Das ist ein interessanter Punkt, den ich noch nicht durchdacht
habe. Allerdings vermute ich, dass es auch ohne geht.
Mit einer Runtime kann Einfluss auf die Ausführung zur Laufzeit
genommen werden.
Zur Laufzeit Konfiguration oder Code nachladen geht doch auch.
> Mit einer Runtime müssen Flows nicht mehr in umständlicher Event-
> Verdrahtung codiert werden.
Mit einem guten Designtool/Compiler/IDE-Integration aber auch nicht.
Momentan bin ich ganz Happy mit meinem Compiler, der mir aus Dia-Files
zunächst eine Art Flow-AST und hernach C#-Code generiert.
Dazu kommt dann noch in diesem Sommer ein kleiner Server, der mir
dabei helfen soll, Änderungen im Diagramm bzw. Code synchron zu halten
bzw. mir Boilerplate-Code Generierung abnimmt.
Dass du das Thema Debuggen aufwirfst, ist verständlich. Und ich habe dazu auch nicht alle antworten. Deshalb aber gleich so eine Runtime abzutun, finde ich vorschnell. Warum nicht versuchen, die Herausforderungen anzunehmen und Lösungen zu finden?
Zu deinen Punkten:-Wenn die Runtime einen Fehler hat, dann ist das kein anderes Problem als wenn die CLR einen Fehler hätte. Ich debugge nicht in die CLR oder den .NET Fx. Wäre ja noch schöner. Ich hab andere Sachen zu tun. Solches Zeugs muss korrekt sein. So korrekt zumindest, dass ich mir 99,999% meiner Zeit darüber keine Gedanken machen muss. Und das ist es. Und eine Flow Runtime muss auch das Level erreichen.
-Dasselbe gilt für Standardoperationen. Du musst .NET Fx Klassen verstehen und du musst Flow Standard Ops verstehen. Auch kein Unterschied. Wer sie falsch anwendet, der hat ein Problem. Das taucht dann in deinem Code auf. Deshalb musst du nicht in Standard Ops reindebuggen.
-Also deinen Code debuggen. Ja, das ist irgendwie merkwürdig, wenn du nur noch Operationen schreibst, die über Flows zusammengehängt werden. Es gibt keinen Call Stack mehr. Der Zusammenhang ist irgendwie nicht mehr so gut zu sehen, wenn du auf einen Breakpoint in einer Op läufst.
Was tun? Hinschmeißen? Wieder zurück zu EBC?
Ne, die Situation verbessern:
1. Debuggen war noch nicht eine gute Sache. Ich debugge auch nur noch selten. Stattdessen schreibe ich Tests. Und das wird mit FD eben einfacher. Weil da Unit Tests auf Operationen wirkliche Unit Tests sind, ohne Abhängigkeiten. Das Debuggen hat bei FD Implementierungen mit oder ohne Runtime einen anderen Stellenwert.
2. Das Testen von Flows ist natürlich so eine Sache, besonders wenn die nicht mehr in einer 3GL geschrieben werden, sondern als Liste. Da können wir alle noch forschen. Mehr Review ist sicherlich angezeigt. Aber einzelne Flows testen, das geht schon. Dafür darf es gern ein Testwerkzeug geben. Müssen wir mal drüber nachdenken.
3. Wenn ich denn aber nicht umhin komme und in einer Operation auf einem Breakpoint stehe, während sie in einem Flow ausgeführt wird, wie kann ich dann den Kontext sehen, den Weg, den die Daten bis dahin genommen haben? Gute Frage. Wie wäre es mit einem Trace von Nachrichten? Nichts anderes ist ja ein Call Stack. So ein Trace ist leicht aufzusetzen, sogar mit Filtern. Du tracet Nachrichten und schaust darauf, wenn du auf einem Breakpoint in einer Op stehst. (Da darf natürlich ein Tool gern helfen, so einen Trace irgendwie zu visualisieren.)
Also: Ich sehe einen Runtime mit ihren Vorteilen nicht verloren, nur weil das Debugging irgendwie anders ist also sonst. Mit EBC war es auch nicht mehr so flauschig wie früher.
Und wir sollten klar sehen: Wenn wir Strukturen favorisieren, weil sie leicht zu debuggen sind, dann machen wir den Bock zum Gärtner. Ich will Strukturen, die leicht zu evolvieren und zu testen sind. Das halte ich für wichtiger.
Niemand soll durch die Runtime debuggen. Das ist doch klar. Das tust du mit dem .NET Fx auch nicht.Man muss einfach ein anderes Vorgehen lernen. Flow ist ein neues Denken - auch beim Debuggen.
2. Die Operationen koennen nicht beliebig klein sein.
Spaetestens, wenn sie die Groesse des Runtime-Overheads erreicht
haben ist Schluss.
Persoenlich bevorzuge ich moeglichst kleine und generische
Operationen.Ich sag mal: Versuch mach kluch. Nicht spekulieren, sondern ausprobieren. Wenn du gegen eine Performancewand läufst, dann melde dich.
Wir haben heute GC und virtuelle Methoden und deklarative Security usw. Wenn wir mit Funktionsgrößen argumentiert hätten vor 10 oder 20 Jahren, dann wären wir immer noch bei C.
Der Spruch ist ja schon alt: Jedes Problem in der Informatik lässt sich durch eine weitere Indirektion lösen.Stimmt :-) Deshalb haben wir Compiler, deshalb haben wir Managed Code. Und deshalb lohnt am Ende auch eine Execution Engine für Flows.
Eine "Standard-DSL" waere eine tolle Sache.Da habe ich schon eine konkrete Aufgabe für dich (und alle, die mittun wollen). Ist ganz, ganz einfach :-)
...
Ich wünsche mir nun einen kleinen "Normalisierer", der eine Liste von Flows nimmt und daraus einen Flow bastelt. Das wäre eine gute Grundlage, um darauf einen Designer zu setzen. Denn in dem will ich mit Subflows arbeiten.
Wie später mal eine DSL aussehen kann... das ist eine andere Frage. Die finde ich noch nicht so wichtig.Viel wäre gewonnen, wenn wir Flows als Listen notieren könnten und Subflows nebeneinander stellen könnten.
Irgendwie gehen tut ja immer alles. Aber wie einfach? EBCs einfach parallelisieren? Ne, das sehe ich nicht.
Mit einer Runtime kann Einfluss auf die Ausführung zur Laufzeit
genommen werden.
Zur Laufzeit Konfiguration oder Code nachladen geht doch auch.Und wie machst du das in einem EBC-System? Wie hältst du da die Ausführung an?
Ich tausche den obersten Flow einfach aus. In Java geht das mit volatile-Variablen ganz gut. Dann nimmt die eine Ausfuehrung des Flows noch die alte Implementierung und ab der naechsten wird die neue Implementierung genommen. Dazu braucht jede Implementierung natuerlich auch ihren eigenen ClassLoader. In meinen Tests ging das ganz gut.
muss korrekt sein. So korrekt zumindest, dass ich mir 99,999% meiner Zeit darüber keine Gedanken machen muss. Und das ist es. Und eine Flow Runtime muss auch das Level erreichen.Das ist natuerlich eine echte Herausforderung. Zumal dann ja auch ein eigener Debugger etc. gebraucht wird.Das ist am Ende ein ziemlich dickes Brett. Ich hoffe sehr, dass Du das (mit moeglichst viel Unterstuetzung natuerlich) hinbekommst.
Ich habe viele Java-Standardbibliotheken erst durch debuggen wirklich richtig verstanden.Ist sicher nicht mein groesstes Hobby und mache ich auch nur noch selten.Aber am Anfang muss ich da (leider) fast immer einmal durch.Geht mir auch mit Webframeworks etc. so.
-Also deinen Code debuggen. Ja, das ist irgendwie merkwürdig, wenn du nur noch Operationen schreibst, die über Flows zusammengehängt werden. Es gibt keinen Call Stack mehr. Der Zusammenhang ist irgendwie nicht mehr so gut zu sehen, wenn du auf einen Breakpoint in einer Op läufst.Da waere jetzt ein eigener Debugger mit eigenem "Call Stack" (oder besser "Flow History"?) perfekt.
Das laesst sich vermutlich auch mit .Net nutzen.Ist auf jeden Fall ziemlich einfach aufzusetzen. Und funktioniert recht prima.In dem Wiki kann man dann auch die Flow-DSL unterbringen und schon hat man eine halbe Entwicklungsumgebung (aber natuerlich ohne Debugger).
Am Ende also ein eigener Flow-Debugger.Finde ich auch eine Supersache. Ist mir momentan allerdings zu aufwendig.
Davon ist vieles durch eine Runtime stark im Wert gemindert (debuggen, refaktoren, ...).
Das ist zumindest meine Beobachtung, wenn ich sehe, wie mit "aehnlichem" wie zum Beispiel Apache Camel und Activiti (http://activiti.org/) gearbeitet wird.Du machst Da hoffentlich mehr draus!
Ich bin an diesen Listen bisher nicht interessiert.Und habe deren Sinn auch noch nicht verstanden.Sie enthalten fuer mich eh nur einen Bruchteil der benoetigten Informationen.Ausserdem sind sie nicht sehr menschenfreundlich zu lesen.Eine DSL ist mir da wesentlich lieber.
Wie später mal eine DSL aussehen kann... das ist eine andere Frage. Die finde ich noch nicht so wichtig.Viel wäre gewonnen, wenn wir Flows als Listen notieren könnten und Subflows nebeneinander stellen könnten.Viel waere gewonnen, wenn wir uns auf eine DSL und Standardoperationen einigen koennten.Dann koennte ein Flow (relativ) leicht von einer Implementation zur anderen migriert werden.
Scala ist da mit seiner Actors-Bibliothek sehr viel(-versprechend) weiter und für mich die prädestinierte Sprache um Flow-Designs mit geringst möglichem Aufwand und größtmöglicher Ähnlichkeit zum Flow-Design-Prinzip selbst zu implementieren. Und ich sehe, aus dem Lesen der Artikel zu NPantharei, viele Ähnlichkeiten zwischen der Implementierung von NPantharei und den Prinzipien der Actors-Bibliothek (wer zu Scala-Actors mehr lesen will, der kann hier nach lesen: http://lamp.epfl.ch/%7Ephaller/doc/haller07coord.pdf).
Meine damalige DSL basierte auf einer Diskussion hier in dieser Gruppe. Heute würde ich Ralfs Vorschlag einer Liste von Flows folgen, die der Xtext-Generator dann zu einem Flow normalisiert.
Ralf, ich habe mir Deinen Code noch nicht angesehen. Ich nehme mal an, das Design ist mit konkreten Flow-Design-Diagrammen dokumentiert. Ich habe festgestellt, dass wie bei anderen Diagrammen auch Flow-Design-Diagramme nicht ohne erläuternde Prosa auskommen. Ich denke, das liegt eher daran, das Namen für FEs immer zu kurz und zu mehrdeutig sind, egal, wie lang man sie wählt, und das dies eher an der Mehrdeutigkeit der natürlichen Sprache selbst liegt. Jetzt meine Frage: Sind die von Dir oben genannten Artikel als Erläuterungen zu den FD-Diagrammen der Implementierung anzusehen, oder gibt es bei den Flow-Diagrammen des NPantharei noch mal zusätzlichen Erläuterungen?
Gruß, Denis
Am Dienstag, 8. Mai 2012 13:16:41 UTC+2 schrieb Ralf Westphal:Am 8. Mai 2012 13:10 schrieb Patrick Bédat <pbe...@googlemail.com>:
> Mit einer Runtime müssen Flows nicht mehr in umständlicher Event-
> Verdrahtung codiert werden.
Mit einem guten Designtool/Compiler/IDE-Integration aber auch nicht.
Momentan bin ich ganz Happy mit meinem Compiler, der mir aus Dia-Files
zunächst eine Art Flow-AST und hernach C#-Code generiert.
Dazu kommt dann noch in diesem Sommer ein kleiner Server, der mir
dabei helfen soll, Änderungen im Diagramm bzw. Code synchron zu halten
bzw. mir Boilerplate-Code Generierung abnimmt.Machbar ist ja alles. Habe an diesen Ansatz auch lange geglaubt.Aber auch wenn ein Compiler das machen kann - am Ende ist das Ergebnis einfach weniger flexibel. Allemal zur Laufzeit.Für mich sieht der bessere Ansatz so aus: Mit einem Designer eine interpretierbare Flow-Repräsentation erzeugen. Derzeit eben eine Liste von Streams. Einfacher kann es kaum gehen.Noch ein Vorteil: so eine Liste von Streams kann man in ein C#-Projekt einbetten. Die Liste wird zur Laufzeit interpretiert. Aber man kann sie auch überall auslesen und daraus den Flow re-generieren. Code und Diagramm müssen also nicht mehr künstlich synchron gehalten werden, da das Diagramm (in textueller Form) der Code ist.
Scala mag es einfach machen, Flows zu implementieren.Wenn aber eine Runtime in Spiel kommt, dann ist genau das ja eben recht egal. Weil die Runtime den Flow interpretiert und der ihr in irgendeiner DSL mitgeteilt wird. Dann sind die Sprachfeatures einer 3GL einerlei, solange man bei der Runtime Operationen irgendwie registrieren kann. (Funktionszeiger/Delegaten helfen allerdings, eine Runtime mit einem netten API und Operationen zu implementieren.)
Meine damalige DSL basierte auf einer Diskussion hier in dieser Gruppe. Heute würde ich Ralfs Vorschlag einer Liste von Flows folgen, die der Xtext-Generator dann zu einem Flow normalisiert.Dafür braucht es doch aber keinen DSL Werkzeugkasten. Wenn in einer Datei eine Hierarchie von Flows steht, dann kann man mit einem Batchprogramm daraus eine flache Liste von Streams machen.(Wie die Hierarchie von Flows in die Datei kommt, ist eine andere Frage ;-)
NPantaRhei ist natürlich mit FD modelliert und mit EBC implementiert.Es gibt dazu im Repository auch Diagramme - doch die sind veraltet. Am Ende habe ich gemerkt, dass ich sie einfach nicht brauche. Für einen Einsteiger sind sie aber hilfreich ;-) Ich habe die Flows aus dem EBC-Verdrahtungscode ausgelesen und sie darin direkt verändert während der Arbeit.
Da bin ich jetzt aber enttäuscht ;-)
Aber mal im Ernst: Bei vielen Open-Source-Projekten is es ja gerade deswegen so schwer reinzukommen, um z.B. mal eine kleine Erweiterung zu machen, da man sich die Architektur aus dem Code erarbeiten muss. Mit FD sollte doch gerade das anders sein. Aber wenn die FD-Diagramme veraltet oder nicht vorhanden sind, dann ist NPantharei da diesbzgl. nicht anders...
Es gibt dazu im Repository auch Diagramme - doch die sind veraltet. Am Ende habe ich gemerkt, dass ich sie einfach nicht brauche. Für einen Einsteiger sind sie aber hilfreich ;-) Ich habe die Flows aus dem EBC-Verdrahtungscode ausgelesen und sie darin direkt verändert während der Arbeit.
Aber das birgt eine Gefahr! Wenn man aus dem Projekt herausgerissen wird und zwei Tage lang nicht an dem Projekt arbeiten kann, dann ist der Einstieg nicht mehr so leicht. Dann sind die Namen doch nicht mehr so eindeutig, wie zuerst gedacht. Und die Karte im Kopf ist dann schon ein wenig verblasst.
Bei mir kommt noch hinzu, dass wir zu zweit an der Software arbeiten und der Kollege noch kein "EBC" Profi ist. Ihm fällt es deutlich schwerer die Diagramme im Kopf zu erstellen. Daher ist es aus meiner Sicht wichtig die Flow Diagramme aktuell zu halten.