Auf den ersten Blick dachte ich, der neue Ruby 2.0 Thread.handle_interrupt
würde alle meine asynchronen Interrupt-Probleme lösen, aber wenn ich mich nicht täusche, kann ich nicht erreichen, dass ich das mache, was ich will (meine Frage ist am Ende und im Titel).
Aus der Dokumentation kann ich sehen, wie ich es vermeiden kann, Interrupts in einem bestimmten Block zu empfangen und sie auf einen anderen Block zu verschieben. Hier ist ein Beispielprogramm:
%Vor% Wenn es mit dem Argument 2
ausgeführt wird, wird etwas wie folgt ausgegeben:
Das heißt, der Haupt-Thread sendet nach zwei Sekunden einen RuntimeError
an den anderen Thread, aber dieser Thread behandelt ihn nicht, bis er in den inneren Thread.handle_interrupt
-Block gelangt.
Leider sehe ich nicht, wie mir das helfen kann, wenn ich nicht weiß, wo mein Thread erstellt wird, weil ich nicht alles, was er tut, in einen Block einbinden kann. In Rails zum Beispiel würde ich die Blöcke Thread.handle_interrupt
oder begin...rescue...end
umschließen? Und würde das nicht davon abhängen, welcher Webserver läuft?
Was ich mir erhofft habe, ist eine Möglichkeit, einen Handler zu registrieren, so wie Kernel.trap
funktioniert. Nämlich, ich möchte einen Code angeben, der kontextunabhängig ist und alle Ausnahmen eines bestimmten Typs behandelt:
Was diese Frage ausgelöst hat, war, wie das RabbitMQ-Juwel bunny
Fehler auf Verbindungsebene an den Thread sendet, der Bunny::Session
mit Thread#raise
geöffnet hat. Diese Ausnahmen könnten irgendwo enden und alles, was ich tun möchte, ist, sie zu protokollieren, zu melden, dass die Verbindung nicht verfügbar ist, und weiter auf meinem Weg zu bleiben.
Ideen?
Ruby sorgt dafür mit dem Ruby-Objekt Queue
(nicht zu verwechseln mit einer AMQP-Warteschlange). Es wäre schön, wenn Bunny vor dem Öffnen von Queue
einen Ruby Bunny::Session
erstellen und dieses Queue-Objekt übergeben würde, an das es Fehler auf Verbindungsebene senden würde, anstatt Thread#raise
zu verwenden, um es zurückzusenden wo auch immer. Sie können dann einfach Ihre eigene Thread
angeben, um Nachrichten über die Warteschlange zu konsumieren.
Es könnte sich lohnen, in den RabbitMQ-Edelstein-Code zu schauen, um zu sehen, ob Sie das tun könnten, oder die Betreuer dieses Edelsteins danach zu fragen.
In Rails ist dies wahrscheinlich nicht möglich, es sei denn, Sie können einen serverweiten Thread erstellen, der von der Ruby-Warteschlange verwendet wird, die natürlich Webserver-spezifisch ist. Ich sehe nicht, wie Sie das aus einem kurzlebigen Objekt, z. Code für eine Rails-Ansicht, in der die Threads wiederverwendet werden, aber Bunny weiß das nicht (oder Vorsicht).
Tags und Links ruby multithreading ruby-on-rails rabbitmq