2012-10-30 12 views
5

Mam przypadek użycia publikowania subskrypcji, w którym chciałbym zablokować publikowanie, dopóki każdy z subskrybentów nie potwierdzi, że ukończył obsługę wiadomości wysłanej przez wydawcę.Dlaczego nie blokuje Channel.waitForConfirmsOrDie?

I (niepoprawnie?) Założyłem, że mogę użyć RabbitMQ i jego metody Channel.waitForConfirmsOrDie klienta Java jako części mojego rozwiązania. Problem polega na tym, że nie znalazłem przypadku, w którym waitForConfirmsOrDie faktycznie zablokuje.

Według javadocs, waitForConfirmsOrDie ma:

poczekać, aż wszystkie komunikaty publikowane od ostatniego połączenia zostały albo ack'd lub nack'd przez brokera. Jeśli którykolwiek z komunikatów został nack'd, waitForConfirmsOrDie wygeneruje wyjątek IOException. Po wywołaniu kanału, który nie jest potwierdzany, natychmiast powróci.

Aby sprawdzić, czy ta metoda naprawdę działa, zacząłem od this example code from the RabbitMQ website.

Przykładowy kod tworzy wydawcy i konsumenta, każdy w osobnym wątku. Następnie wydawca wysyła komunikaty do giełdy, gdy konsument zużywa wiadomości. Wydaje się, że wydawca ma zablokować, dopóki wszystkie wiadomości nie zostaną przekierowane przez wywołanie waitForConfirmsOrDie().

Ten przykładowy kod wydawał się idealnie pasować do tego, co próbowałem zrobić. Ale wydaje się, że nie działa tak, jak myślałem. W rzeczywistości, jeśli w wątku konsumenckim wyłączam automatyczne wiadomości, to waitForConfirmsOrDie() nadal zwraca natychmiast.

Wyłączyłem auto ACK tylko przez zmianę jednego false na true: ch.queueDeclare(QUEUE_NAME, false, false, false, null); staje ch.queueDeclare(QUEUE_NAME, true, false, false, null); (2 arg fałszywe zamiast true). Sądzę, że oznacza to, że opakowania nie powinny już być wysyłane przez konsumenta.

Co właściwie robi funkcja waitForConfirmsOrDie()? Kiedy to zablokuje?

Jeśli waitForCirfirmsOrDie nie robi, co chcę, czy istnieje sposób, aby wydawca poczekał, aż wszyscy subskrybenci potwierdzą wiadomość przed kontynuowaniem?

Odpowiedz

7

O ile rozumiem, połączenia te nie powinny czekać na potwierdzenie od konsumenta. Celem metod waitForConfirms* jest upewnienie się, że wiadomość została dostarczona do brokera i dostarczenie podstawowego powiadomienia dostarczonego/nieudanego. Innymi słowy, komunikat nie zniknie bez powiadomienia w przypadku, gdy jeden z węzłów rmq (lub nawet wszystkie węzły) zakończy się niepowodzeniem/nie będzie dostępny.

Ten wyjątek można zobaczyć w akcji po odłączeniu lub wyłączeniu rmq przed wywołaniem basicPublish.

Powiązane problemy