Unzufrieden mit meinem derzeitigen Ansatz versuche ich gerade, die Art und Weise, wie ich Protokollstapel in Erlang aufbaue, neu zu gestalten. Die Funktion nach Wichtigkeit geordnet:
-
Leistung
-
Flexibilität und Implementierungsgeschwindigkeit beim Hinzufügen neuer Protokollvarianten
-
Es würde der Entwicklung helfen, die Protokollvarianten von der Shell aus zu erkunden
Mein derzeitiges Modell ( wie in dieser Frage bereits beschrieben ) an seine Grenzen stößt, abgesehen von der hässlichen Asymmetrie von Senden() per Funktionsaufruf und Empfangen per Nachricht.
Das Gesamtbild der gesamten Protokollmaschine sieht folgendermaßen aus:
Unterer Teil:
-
Es gibt mehrere Ports oder vielleicht auch manchmal ein gen_tcp am Ende jedes Stacks (es gibt mehrere identische Stacks für unabhängige Kanäle, also können wir hier nicht zu statisch sein und nur Prozesse registrieren, wir müssen überall Pids übergeben.
-
Zusätzlich zu den Ports gibt es einige Module, die von einem Supervisor verwaltet werden (der mit dem System gestartet wird und bei Abwesenheit von Fehlern die ganze Lebensdauer über erhalten bleibt).
Oberer Teil:
-
Ausgelöst durch das Auftreten von Ereignissen (im allgemeinen Sinn, nicht im event_handler-Sinn) sind verbindungsorientierte Protokollenden (z. B. mit
connect()
yclose()
Semantik. -
Das obere Ende des Protokollstapels kann wahrscheinlich nur dynamisch gestartet werden, da die übereinander gestapelten Module, die den Stapel bilden, dynamisch konfigurierbar sind und sich von Verbindung zu Verbindung ändern können.
-
Derzeit geplant wäre die Übergabe einer Liste von Modulnamen + optionalen Parametern aus der Toplevel, die beim
connect()
auf dem Stapel aufgerufen wird. -
Die Prozesse auf der obersten Ebene werden miteinander verknüpft, so dass, wenn hier etwas schief geht, die gesamte Verbindung ausfällt.
Arten von Modulen und Arten der Kommunikation zwischen ihnen
Es gibt verschiedene Arten von Modulen, die bisher gefunden wurden:
-
Zustandslose Filtermodule
-
Module mit Status, einige passen zu gen_server, einige zu gen_fsm, aber die meisten werden wahrscheinlich einfache Serverschleifen sein, da selektiver Empfang oft nützlich ist und den Code vereinfacht.
Arten der Kommunikation zwischen Schichten:
-
Unabhängiges Senden und Empfangen von Paketen (von außen gesehen unabhängig)
-
Synchrone Aufrufe, die etwas senden, blockieren, bis eine Antwort erfolgt, und dann das Ergebnis als Rückgabewert zurückgeben.
-
Multiplexer, die mehrere Module ansprechen (das ist meine Definition, um die Diskussion zu erleichtern)
-
Demultiplexer, die verschiedene Befestigungspunkte (derzeit nach Atomen benannt) haben, um mit nach oben gerichteten Modulen zu kommunizieren.
Derzeit befinden sich meine einzigen Demultiplexer im statischen unteren Teil des Stapels und nicht im dynamisch erzeugten oberen Teil. Multiplexer befinden sich derzeit nur im oberen Teil.
In den Antworten und Kommentaren zu der von mir verlinkten Frage habe ich gehört, dass die API im Allgemeinen nur aus Funktionen und nicht aus Nachrichten bestehen sollte, und ich stimme dem zu, sofern ich nicht vom Gegenteil überzeugt bin.
Bitte entschuldigen Sie die langatmige Erklärung des Problems, aber ich denke, es ist immer noch von allgemeinem Nutzen für alle Arten von Protokollimplementierungen.
Ich werde in den Antworten schreiben, was ich bisher geplant habe und auch die daraus resultierende Implementierung und meine Erfahrungen damit später erläutern, um hier etwas allgemein Nützliches zu erreichen.