2009-07-23 5 views
3

Wir haben ein Design wie unten und ich würde Meinungen oder Protokollrichtlinien für das folgende Fehlerszenario erhalten.Protokollentwicklungsrichtlinien

Layer1             
---------------             
| ^^           
| (1) |(4) |(6) 
v  | |           Remote entity 
----------------          --------------- 

    Layer0-----------------(2)------------------------------->Layer0 
    Layer0<----------------(3)--------------------------------Layer0 
    Layer0<----------------(5)--------------------------------Layer0 


1. New session request to remote entity. 
2. Establish link + data(session request) 
3. Link Establishment ongoing 
4. Link Establishment pending 
5. Link Established + data (session accepted) 
6. session accepted. 

Wenn layer1 entscheidet, dass es nicht den Remote-Einheiten-Service zwischen Schritt benötigt 4 und 6 d.h Ereignis 4 empfangen wird und Ereignis 6 ist noch empfangen wird aufgrund eines Fehlers.

1) Sollte es für Ereignis 6 warten, um eine Sitzung Release oder
2) Layer1 sollte den Verbindungsaufbau Verfahren
sofort geschehen und initiieren Schicht 0 anweisen zu beenden.

Welcher ist der richtige Weg?

Das Problem mit (1) wird, obwohl wir wissen, dass wir die Sitzung beenden wegen eines Fehlers gehen, müssen wir andere Ereignisse behandeln, bevor EVENT6 kommt.

Antwort

7

Ich bin ein Fan von fail fast Designs. Sobald Sie wissen, dass Sie nicht fortfahren können, sollten Sie die andere Seite benachrichtigen und beenden.

Wenn Sie aus irgendeinem Grund überprüfen müssen, ob die andere Seite Ihre Beendigungsnachricht erhalten hat, reagiere ich lieber auf Anfragen mit einer UNABLE_TO_COMPLY Nachricht oder verwerfen die Ereignisse vollständig. Das Problem ist, dass Sie in einen halboffenen Zustand gelangen können.

Eine Möglichkeit, eine Situation zu behandeln, in der die andere Seite auf Antworten anderer Anfragen wartet, nachdem Sie die Fehlernachricht bereits gesendet haben, ist die Verwendung einer Prioritätswarteschlange. Anstatt die Anforderungen in der Reihenfolge zu bearbeiten, in der sie empfangen werden, können Sie angeben, dass einige Nachrichten sofort verarbeitet werden, unabhängig davon, wann sie empfangen werden. Die Nachrichten mit der höheren Priorität werden an der Vorderseite der Warteschlange eingefügt, sodass die Ereignisse quit_on_failure nicht durch andere Anforderungen blockiert werden, von denen Sie wissen, dass Sie sie nicht wirklich verarbeiten können.

Generell mag ich auch zeitbasierte Watchdogs nicht (weil die vom Entwickler gewählte Zeitlänge nie für alle Situationen korrekt ist), aber für diese Art von Protokollen muss man oft ein Worst-Case-Szenario definieren, bei dem die andere Seite nie reagiert zu Ihrer fail Nachricht. In diesen Situationen ist eine konfigurierbare Zeitüberschreitung in der Regel die einzige Möglichkeit zur Bereinigung. Timeouts sollten immer der letzte Ausweg sein, niemals der erste.

0

Gibt es 4 Nachrichten in einer Richtung (durch Schichten) ohne irgendeine Bestätigung von der empfangenden Seite? Wenn der Client Bestätigungsnachrichten wie SYN-ACK/RST-Pakete in TCP sendet, würde er sich automatisch um das betreffende Szenario kümmern und auch bei anderen Fehlermodi helfen (wenn Client oder Netzwerk ausfällt).

1

Sie sollten in Ihrem Protokoll eine Art von (Nicht-) Bestätigungsmeldungen und entsprechende Timeouts hinzufügen. Dann kann eine Anforderung durch die Schicht 1, eine ausstehende Sitzung abzubrechen, entweder durch eine Meldung an die nächste Nachricht von Ihrer Fernsitzung oder einfach durch den Ausfall Ihres Clients, überhaupt auf eine Antwort von der Fernsitzung und dem Fernsitzungstiming reagiert werden aufgrund der Inaktivität.

Wie ein vorheriges Poster korrekt angibt, können Sie kein vollständiges Protokoll ohne Timeout-Behandlung haben, da dies ein guter Weg ist, um zugrundeliegende Transportfehler zu erfassen. Ob Sie sich nur auf Timeouts verlassen, um die "Beendigung des Protokolls" zu signalisieren, ist eine Designentscheidung. Ich würde normalerweise versuchen, eine Nack oder Abbrechen in dem Protokoll zu senden, um zumindest zu versuchen und das Protokoll an beiden Enden rechtzeitig zu beenden. Aber du brauchst auch die Zeitüberschreitung.

0

1) Sollte es für Ereignis 6 warten, um eine Sitzung Release

IMHO passieren und initiieren Sie den Client auf einem Beendigungsanforderung nicht immer blockieren sollen. Es kann sein, dass eine Anwendung geschlossen werden muss, weil das System heruntergefahren wird. Sie können es in Wirklichkeit sowieso nicht machen, der Admin hat die Kontrolle über den Netzschalter auf der untersten Ebene. Wenn du diese Realität nicht akzeptierst, verdienst du, dass Produkte, die auf deinem Protokoll aufbauen, den Ruf haben, nervig zu sein.

2) Layer1 sollte 0 anweisen Schicht, die den Verbindungsaufbauvorgang

Ja zu beenden.

Ich stelle fest, dass die Schicht 1 kann auch nach jeder Zeit abbrechen müssen Schritt 1, und nicht nur nach dem Schritt 4.

Es ist wie jederzeit sieht nach dem Schritt 2, es kann ein gewisses Maß an ‚Abwickeln‘ nehmen zu beenden .

Die lokalen und entfernten Einheiten haben eine Netzwerkverzögerung zwischen ihnen und können unterschiedliche Wahrnehmungen davon haben, in welchen Zustand sich die Dinge gerade befinden. Zum Beispiel können Sie Schritt 2 lokal abgeschlossen haben, während die entfernte Entität glaubt, dass er Schritt 5 abgeschlossen hat. Wenn Nachrichten außerhalb der Reihenfolge (z. B. UDP) ankommen können, ergeben sich noch mehr Möglichkeiten.

Die "Terminierung" kann oder kann nicht in unterschiedlichem Maße erfolgreich sein. Was passiert, wenn Sie Schritt 2, dann eine Beendigung senden, aber nie von der entfernten Einheit zurück hören?

Übergeordnete Clients können zusätzliche Anforderungen stellen. Zum Beispiel unterscheidet sich die Stornierung nach Schritt 5 anders als nach Schritt 2? Stellen die Schritte 3 und 5 eine persistente Änderung an der entfernten Entität dar (wie bei einem Datenbank-Commit)? Muss der übergeordnete Client wissen, wie weit die Dinge tatsächlich fortgeschritten sind, bevor seine Beendigungsanfrage verarbeitet wurde?

Erarbeiten Sie alle möglichen Kombinationen und treffen Sie gute Entscheidungen, indem Sie sich in die Lage des Benutzers versetzen. Der Benutzer hier kann ein Ingenieur sein, der versucht, auf Ihrem Protokoll aufzubauen, damit es für seine eigenen Benutzer "einfach funktioniert". Nachdem Sie dies getan haben, überlegen Sie, was passiert, wenn jede Nachricht verloren geht oder verzögert wird, insbesondere während des Abwicklungsvorgangs.

Dann betrachten Sie es aus der Sicht der Remote-Entität. Sein Administrator muss in der Lage sein, ihn manchmal auszuschalten, und so wird auch eine Möglichkeit benötigt, um die Verbindung von jedem Zustand effizient zu beenden.

0

Können Sie mir sagen, welchen Vorteil gibt es im Warten? Sie haben bereits darauf hingewiesen, dass es Probleme mit diesem Ansatz gibt und es klingt für mich so, als ob Sie bereits entdeckt hätten, dass Option 2 der beste Weg ist. Korrektheit ist nur eine Frage der Meinung, aber ich würde Option 2 sagen.

Schicht 1 sollte Schicht 0 anweisen, den Verbindungsprozess zu beenden. Diese Prozedur sollte Schicht 0 auch anweisen, dass sie nicht mehr daran interessiert ist, Ereignisse zu empfangen. Schicht 1 kann dann im getrennten Zustand weiterarbeiten.

Für mich ist das die einfachste und offensichtlichste Sache und am wenigsten problematisch. Wie Sie bereits gesagt haben, müssen Sie keinen weiteren Status in Schicht 1 verarbeiten, da diese anderen Nachrichten nicht erwartet werden, wenn Sie die Verbindung bereits geschlossen haben.