Moim zdaniem Gearman stosuje podejście "to nie moja sprawa" - np. Nie ingeruje w wykonywane zadania, chyba że pracownicy się zawiesią. Wszelkie komunikaty o sukcesie/niepowodzeniach powinny być obsługiwane przez klienta, a nie sam serwer Gearman.
W planie pracy, oznacza to, że wszystko sendFail()
/sendException()
i inne send*()
są skierowane do klienta i to do klienta, aby zdecydować, czy ponowić ofertę lub nie. Ma to sens, ponieważ czasami nie trzeba się ponownie próbować.
W pracy w tle wszystkie funkcje send*()
tracą znaczenie, ponieważ nie ma klienta, który będzie słuchał wywołań zwrotnych. W rezultacie wysłane wiadomości zostaną po prostu zignorowane przez Gearmana. Jedyny warunek, w którym zadanie zostanie ponowione, to sytuacja, w której pracownik ulega awarii (co można naśladować komendą exit(XX)
, gdzie XX
ma wartość niezerową). To oczywiście nie jest coś, co chcesz robić, ponieważ pracownicy zazwyczaj mają być długotrwałymi procesami, a nie tymi, które muszą być ponownie uruchomione po każdej nieudanej pracy.
Osobiście rozwiązałem ten problem poprzez rozszerzenie domyślnej klasy GearmanJob, w której przechwytywam wywołania funkcji send*()
, a następnie wdrażam mechanizm ponawiania. Zasadniczo przekazuję wszystkie dane związane z ponownym przetwarzaniem (maksymalna liczba ponownych prób, czasy, które zostały już ponownie sprawdzone) wraz z obciążeniem, a następnie przetwarzam wszystko samodzielnie. Jest to trochę kłopotliwe, ale rozumiem, dlaczego Gearman działa w ten sposób - po prostu pozwala obsłużyć całą logikę aplikacji.
Wreszcie, jeśli chodzi o możliwość ponawiania zadań z wykładniczym limitem czasu (lub z jakimkolwiek przekroczeniem limitu czasu). Gearman ma funkcję dodawania opóźnionych zadań (poszukaj SUBMIT_JOB_EPOCH
w protocol documentation), ale nie jestem pewien co do jej statusu - rozszerzenia PHP i, jak sądzę, moduł Pythona go nie obsługuje, a doktorzy mówią, że można go usunąć w przyszłość. Ale rozumiem, że działa to w tej chwili - wystarczy, że przekażesz Gearmanowi żądania surowych gniazdek, aby to się stało (a część wykładnicza powinna zostać zaimplementowana również po twojej stronie).
Jednak this blog post twierdzi, że implementacja SUBMIT_JOB_EPOCH nie jest skalowalna. Korzysta z node.js i setTimeout()
, aby działało, widziałem, jak inni używają narzędzia unixowego at
, aby zrobić to samo. W jakikolwiek sposób - Gearman nie zrobi tego za ciebie. Skoncentruje się na niezawodności, ale pozwoli ci skupić się na całej logice.
sys.exit() jest złym pomysłem dla Gearmana - zazwyczaj będzie ponawiał każdą taką pracę na zawsze (chyba że masz ustawione Retrole zadań podczas uruchamiania demona). Po prostu wykonaj 'return stringvar' z dowolnym statusem/wynikami z zadania (np. Klucz do wiersza DB lub pamięci podręcznej z prawdziwymi informacjami). – RichVel