Können Ruby-Exceptions außerhalb eines Thread :: handle_interrupt-Blocks asynchron verarbeitet werden?

9

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:

%Vor%

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:

%Vor%

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?

    
Kevin Bullaughey 15.01.2014, 20:29
quelle

1 Antwort

0

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).

    
Tom 27.10.2017 18:49
quelle