Entwickeln einer flexiblen Erlang-Protokollstapel-Erstellungs-API

8

Unzufrieden mit meiner derzeitigen Herangehensweise versuche ich nur, die Art, wie ich Protokollstacks in Erlang baue, neu zu gestalten. Die nach Wichtigkeit sortierte Funktion:

  1. Leistung

  2. Flexibilität und Implementierungsgeschwindigkeit beim Hinzufügen neuer Protokollvarianten

  3. Es würde der Entwicklung helfen, die Protokollvarianten von der Shell aus zu erkunden

Mein aktuelles Modell ( bereits beschrieben in diese Frage ) kommt neben der hässlichen Asymmetrie von send () durch den Funktionsaufruf und den Empfang per Nachricht an ihre Grenzen.

Das Gesamtbild der gesamten Protokoll-Engine sieht folgendermaßen aus:

Unterer Teil:

  • Es gibt mehrere Ports oder vielleicht auch ein gen_tcp am unteren Ende jedes Stacks (es gibt mehrere identische Stacks für unabhängige Kanäle, also können wir hier nicht zu statisch sein, nur Prozesse registrieren, müssen überall PIDs übergeben).

  • Oben auf den Ports befinden sich einige Module, die vom Supervisor verwaltet werden (gestartet mit dem System und ohne Fehler während der gesamten Lebensdauer).

Oberer Teil:

  • Ausgelöst durch das Auftreten von Ereignissen (im allgemeinen Sinne nicht im Sinne von event_handler) enden die verbindungsorientierten Protokolle (z. B. mit connect() und close() Semantik.

  • Das obere Ende des Protokollstapels kann wahrscheinlich nur dynamisch gestartet werden, da die übereinander gestapelten Module zur Bildung des Stapels dynamisch konfigurierbar sind und sich möglicherweise von Verbindung zu Verbindung ändern.

  • Derzeit geplant wäre die Übergabe einer Liste von Modulnamen + optionalen Parametern aus der Toplevel, die konsumiert werden, während connect() im Stack aufgerufen wird.

  • Toplevel-Prozesse werden verknüpft, wenn etwas schief geht, schlägt die gesamte Verbindung fehl.

Arten von Modulen und Arten der Kommunikation zwischen ihnen

Es gibt verschiedene Arten von Modulen, die bisher gefunden wurden:

  • Stateless Filtermodule

  • Module mit Status, einige passen gen_server, einige gen_fsm, aber die meisten werden wahrscheinlich einfache Server-Schleifen sein, da selektives Empfangen nützlich sein und den Code ziemlich oft vereinfachen wird.

Arten der Kommunikation zwischen den Schichten:

  • Unabhängiges Senden und Empfangen von Paketen (unabhängig von außen)

  • Synchrone Aufrufe, die etwas senden, blockieren, bis eine Antwort vorliegt, und das Ergebnis als Rückgabewert zurückgeben.

  • Multiplexer, die mehrere Module sprechen (das ist meine Definition hier, um die Diskussion zu erleichtern)

  • Demultiplexer mit unterschiedlichen Befestigungspunkten (die derzeit von Atomen benannt werden) können mit nach oben gerichteten Modulen kommunizieren.

Momentan befinden sich meine einzigen Demultiplexer im statischen unteren Teil des Stapels und nicht im dynamisch erzeugten oberen Teil. Multiplexer sind derzeit nur im oberen Teil.

In den Antworten und Kommentaren meiner verknüpften vorherigen Fragenbehandlung habe ich gehört, dass die API im Allgemeinen nur aus Funktionen und nicht aus Nachrichten bestehen sollte, und stimme dieser zu, es sei denn, es wurde etwas anderes behauptet.

Bitte entschuldigen Sie die langwierige Erklärung des Problems, aber ich denke, es ist immer noch von allgemeiner Bedeutung für alle Arten von Protokollimplementierungen.

Ich werde das, was ich bisher geplant habe, in die Antworten schreiben und werde auch die daraus resultierende Implementierung und meine Erfahrungen damit später erklären, um etwas allgemein Nützliches hier zu erreichen.

    
Peer Stritzinger 30.10.2010, 17:10
quelle

1 Antwort

1

Ich werfe ein, was ich bisher als Teil der Antworten geplant habe:

  • connect wird an eine Liste von zu stapelenden Modulen übergeben, die im Fall von Parametern wie beispielsweise einer Proplist aussehen:

    %Vor%

    Jede Schicht streift den Kopf ab und ruft die nächsten Ebenen auf.

  • connect() "irgendwie" übergibt lustige Referenzen nach oben und / oder unten die Ebenen

    • send async, das den Stapel nach unten sendet, wird von der unteren Ebene connect
    • zurückgegeben
    • recv für Async beim Aufrufen des Stacks wird als Parameter an die untere Ebene connect
    • übergeben
    • Aufruf für die Synchronisierung senden und warten auf eine Antwort zurückgegeben - nicht sicher, wie sie behandelt werden, wahrscheinlich auch von der unteren Ebene zurückgegeben connect
  • Multiplexer-Routing-Listen könnten wie diese aussehen

    %Vor%

Momentan habe ich entschieden, dass es keine zusätzliche Funktion für synchrone Anrufe geben wird, ich benutze nur send dafür.

Es gibt ein Implementierungsbeispiel der Idee in diesem Fall für ein Modul, das zustandslos ist: encode/1 und decode/1 machen einige für und rücktransformation an Paketen, z.B. binäre Darstellung in einen Datensatz und zurück analysieren:

%Vor%

Sobald ich ein Stateful Beispiel habe, werde ich es auch veröffentlichen.

    
Peer Stritzinger 30.10.2010, 17:27
quelle

Tags und Links