Decouple Programme mit Warteschlangen

8

In seinem Gespräch in der 54:53 Minuten-Minute redet Rich Hickey über die Verwendung von Queues als Mittel, um abhängige Programmteile zu entkoppeln. Können Sie mir ein Beispiel geben, wie Sie den folgenden Java-Pseudo-Code entkoppeln können, um das Design und / oder die Flexibilität zu verbessern:

%Vor%

saveObjectToDatabase und saveObjectToDatabase können als eine Methode mit Nebeneffekten angesehen werden, während computeB und computeC nur von a abhängen.

Ich weiß, dass diese Frage ziemlich vage / breit ist. Ich möchte ein Gefühl dafür bekommen, wie man Warteschlangenmechanismen ausnutzt, ohne mein Programm massiv zu verkomplizieren und trotzdem sicherzustellen, dass es das Richtige in der richtigen Reihenfolge tut. Alle Hinweise in die richtige Richtung werden geschätzt.

    
Matt 04.01.2012, 12:25
quelle

4 Antworten

3

Nun, es ist kein sehr gutes Beispiel, aber (im einfachsten Fall) haben Sie grundsätzlich zwei Warteschlangen und (abhängig von der Menge der beteiligten Daten) könnten Sie die Datenbank weglassen.

Ein erster Prozess würde Ihre a -Objekte von der "Außenwelt" erhalten und sie in die Warteschlange 1 einreihen. Ein zweiter Prozess würde Objekte aus der Warteschlange 1 herausnehmen, computeB ausführen und die Ergebnisse in die Warteschlange 2 einreihen Der dritte Prozess würde Objekte aus der Warteschlange 2 herausnehmen, computeC ausführen und das Ergebnis oder was auch immer protokollieren.

Abhängig von der Menge der beteiligten Daten (und vielleicht ein paar anderen Faktoren) können die in den Warteschlangen übergebenen "Objekte" entweder Ihre tatsächlichen a und b Objekte oder auch nur Token / Schlüssel sein um die Daten in der Datenbank zu finden.

Die Warteschlangen selbst könnten auf verschiedene Arten implementiert werden. Es ist möglich, eine Warteschlange mit einer Datenbank zu implementieren, zB wenn die Details irgendwie unordentlich werden. Die "Prozesse" könnten Java-Aufgaben innerhalb eines einzelnen Java-Prozesses sein oder separate Betriebssystemprozesse, möglicherweise sogar auf separaten Maschinen.

Wenn Sie "pipes" unter Unix verwenden, verwenden Sie Warteschlangen auf diese Weise.

    
Hot Licks 04.01.2012, 12:41
quelle
1

Dies ist genau das Prinzip, das von einer Java-Bibliothek verwendet wird, die ich verwende. Die Idee ist, Komponenten den einzelnen Aufgaben in den Programmen zuzuordnen (der Logger ist ein perfektes Beispiel). Jetzt muss jede Komponente unabhängig von den anderen ausgeführt werden, entweder als Thread oder als Event-Handler.

Im Falle von ereignisgesteuerten Ereignissen teilt jede Komponente mit, welche Arten von Ereignissen \ Nachrichten sie hören möchte. Sie haben einen Dispatcher, der eingehende Nachrichten sammelt und sie in die Warteschlange der Empfänger einfügt. Der Empfängerprozess und schließlich generieren neue Nachrichten. Und Etc ...

In Ihrem Fall, etwa so:

%Vor%

};

Die fragliche Bibliothek ist SEDA .

    
UmNyobe 04.01.2012 12:46
quelle
0

Ich fürchte, bei saveObject-Methoden mit Nebeneffekt kann man sie nicht gut oder zumindest nicht so einfach entkoppeln.

Aber sagen wir, Sie müssen einige Objekte schnell in die Datenbank schreiben. Meiner Meinung nach sollte der schnellste Weg mit der relationalen Datenbank darin bestehen, die Objekte durch mehrere Clients in einer Warteschlange zu speichern und dann von einem oder zwei ziemlich schnellen Autoren aufzunehmen, die die Daten so schnell wie möglich in die Datenbank pushen.

    
Rostislav Matl 04.01.2012 17:27
quelle
0

Der Vollständigkeit halber möchte ich der Antwort von Hot Licks noch weitere Informationen hinzufügen:

Ich habe mehr über dieses Thema geforscht und bin schließlich zu dem Schluss gekommen, dass das Entwirren der Methode der richtige Weg ist. Ich werde die Kafka-Terminologie von Produzenten / Konsumenten / Themen verwenden. Weitere Informationen finden Sie unter The Log : Was jeder Softwareentwickler über die vereinheitlichende Abstraktion von Echtzeitdaten wissen sollte und insbesondere diese Grafik:

In Bezug auf meine spezifische Frage des veröffentlichten Beispiels gibt es zwei Möglichkeiten, es zu lösen:

Lösung 1

  • Verbraucher 1:
    • konsumiere vom Thema a
    • in Datenbank speichern.
  • Verbraucher 2:
    • konsumiere vom Thema a
    • berechnen b
    • in Datenbank speichern.
  • Consumer 3: konsumieren von Thema a
    • berechnen b
    • berechnen c
    • in Datenbank speichern

Dies hat den Nachteil, dass b doppelt berechnet wird. Im Pseudocode:

%Vor%

Lösung 2

  • Verbraucher 1:
    • konsumiere vom Thema a
    • in Datenbank speichern.
  • Verbraucher 2:
    • konsumiere vom Thema a
    • compute b , in Datenbank speichern
    • Veröffentlichen Sie b in einem separaten Thema b .
  • Verbraucher 3:
    • konsumiere vom Thema b
    • berechnen c
    • logToFile c

Im Pseudocode:

%Vor%     
Matt 17.05.2016 15:39
quelle