Ich habe eine Anwendung, die auf Nachrichten reagiert, die von Clients gesendet werden. Eine Nachricht ist reload_credentials
, die die Anwendung erhält, wenn ein neuer Client registriert wird. Diese Nachricht stellt dann eine Verbindung zu einer PostgreSQL-Datenbank her, führt eine Abfrage für alle Anmeldeinformationen durch und speichert sie dann in einem regulären Ruby-Hash (client_id = & gt; client_token).
Einige andere Nachrichten, die die Anwendung möglicherweise erhält, sind start
, stop
, pause
, die verwendet werden, um einige Sitzungszeiten zu verfolgen. Mein Punkt ist, dass ich mir die Anwendung auf folgende Weise vorstellen kann:
Allerdings möchte ich zum Beispiel den Reaktor nicht blockieren. Stellen wir uns außerdem vor, dass ich eine Nachricht reload_credentials
habe, die als nächstes in der Warteschlange ist. Ich möchte nicht, dass eine andere Nachricht aus der Warteschlange verarbeitet wird, bis die Anmeldeinformationen von der Datenbank neu geladen werden. Während ich eine bestimmte Nachricht verarbeite (zum Beispiel das Warten auf die Beendigung der Anmeldeinformationen-Abfrage), möchte ich zulassen, dass andere Nachrichten in die Warteschlange eingereiht werden.
Könnten Sie mir bitte helfen, ein solches Problem zu lösen? Ich denke, ich muss em-synchrony
verwenden, aber ich bin mir nicht sicher.
Verwenden Sie einen der Postgresql-EM-Treiber oder EM.defer, damit Sie den Reaktor nicht blockieren.
Wenn Sie die Nachricht "reload_credentials" erhalten, drehen Sie einfach ein Flag, das bewirkt, dass alle nachfolgenden Nachrichten in die Warteschlange eingereiht werden. Sobald die 'reload_credentials' beendet ist, verarbeiten Sie alle Nachrichten aus der Warteschlange. Nachdem die Warteschlange leer ist, klappen Sie das Flag um, damit Nachrichten beim Empfang verarbeitet werden.
EM-Treiber für Postgresql sind hier aufgelistet: Ссылка
%Vor%Wenn Sie möchten, dass alle Verbindungen Nachrichten in die Warteschlange stellen, wenn eine Verbindung eine 'reload_connections'-Nachricht erhält, müssen Sie über die Eigenklasse koordinieren.
Ich nehme an, so etwas wie Ihre aktuelle Implementierung:
%Vor%Das obige Problem, wenn ich Sie richtig verstehe, ist, dass Sie nicht wollen, dass Mitarbeiter an neuen Jobs arbeiten (Jobs, die früher in der Producer-Zeitleiste angekommen sind) als Jobs mit reload_credentials. Folgendes sollte dies tun (zusätzliche Worte der Vorsicht am Ende).
%Vor% Also kommt die Eingabe in das erste System in q
, aber in diesem neuen System kommt es auf channel
. Das queue
wird immer noch für die Arbeitsverteilung unter Arbeitern verwendet, aber das queue
wird nicht ausgefüllt, während eine Aktualisierung der Anmeldeinformationen ausgeführt wird. Leider habe ich, da ich nicht mehr Zeit brauchte, das LockingDispatcher
nicht verallgemeinert, so dass es nicht mit dem Artikeltyp und dem Code für den Versand von CredentialsReloader
gekoppelt ist. Das überlasse ich dir.
Sie sollten hier anmerken, dass während dieser Dienstleistungen, was ich von Ihrer ursprünglichen Anfrage verstehe, es im Allgemeinen besser ist, diese Art von Anforderung zu entspannen. Es gibt mehrere offene Probleme, die ohne Änderung dieser Anforderung im Wesentlichen nicht beseitigt werden können:
Es klingt tatsächlich so, als hätten Sie eine Vorstellung von einer Benutzer-ID im System. Wenn Sie Ihre Anforderungen durchdenken, ist es wahrscheinlich möglich, dass Sie nur Elemente zurücksetzen müssen, die sich auf eine Benutzer-ID beziehen, deren Anmeldeinformationen sich in einem Aktualisierungszustand befinden. Dies ist ein anderes Problem, das eine andere Art des Versands beinhaltet. Probieren Sie einen Hash der gesperrten Rückstände für diese Benutzer aus, mit einem Callback für die Vollendung der Anmeldeinformationen, um diese Rückstände in die Worker oder eine ähnliche Anordnung zu löschen.
Viel Glück!
Tags und Links ruby eventmachine