Bunny を使用して簡単に行う方法が見つかりませんでした。ここで提案する方法は、タイムアウトなしでブロックします。ただし、呼び出しセマンティクスごとに 1 つのメッセージを取得することはサポートしています。Bunny が内部的にスレッド プールを使用してメッセージを受信することを考えると、Ruby のQueue
クラスなどのブロッキング キューを使用して、Bunny のスレッド プールから呼び出しスレッドにメッセージを転送するのがより簡単な方法であると考えました。次のようなもの:
# Set up your internal queue somewhere (in your class's initialize maybe?)
@internal_queue = Queue.new
# In the main thread that needs to block
...
# the call to subscribe is non-blocking
queue.subscribe do |delivery_info, properties, payload|
@internal_queue.enq(payload) # this runs inside Bunny's pool
end
# the call to deq is blocking
response = @internal_queue.deq # this blocks the main thread till a
# message is pushed to the internal_q
リッスンする必要がある AMQP チャネルごとに 1 つの @internal_queue を維持できます。これらの部分を個別のメソッドに分割して、一度に 1 つのメッセージを返す適切なブロッキング API を作成できます。
後で、モニター MonitorMixin で拡張された単純な配列をラップし、ミューテックス + 条件変数セマンティクスを使用する TimedWaitableQueue クラスを作成しました。これにより、タイムアウトのあるデキュー呼び出しでのブロックが可能になりました。