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?