Każdy system webhooków na świecie dostarcza co najmniej raz i wszystkich za pierwszym razem to zaskakuje. Zdarzenie przychodzi dwa razy, do klienta idą dwie wiadomości, a zgłoszenie mówi, że webhook jest zepsuty. Nie jest: robi dokładnie to, co obiecał.
Dlaczego powtórka jest normalna
- Twoja obsługa była wolna, więc nadawca przestał czekać i spróbował jeszcze raz.
- Twoja obsługa odpowiedziała 500 po wykonaniu pracy.
- Połączenie padło po tym, jak odpowiedziałeś, ale zanim odpowiedź doszła.
- Wdrożenie zrestartowało proces w środku żądania.
Tylko jedno z tych jest błędem w twoim kodzie, a wszystkie cztery dają duplikat.
Lekarstwem jest więz unikalności
CREATE TABLE handled ( event_id TEXT PRIMARY KEY, handled_at TIMESTAMPTZ NOT NULL DEFAULT now() );
Wstawiaj, zanim zadziałasz. Jeśli wstawienie wejdzie w konflikt, ktoś już to obsłużył i masz z głowy. To przeżywa restart w środku, którego zbiór w pamięci nie przeżywa, i nie potrzebuje biblioteki, blokady ani uzgadniania między wykonawcami.
Dwie rzeczy, które potem idą źle
Odpowiada się 200 po pracy zamiast przed, co zamienia wolną obsługę w ponawianą. I sprawdza się podpis po przeczytaniu ciała, co znaczy, że dane od kogokolwiek, kto znalazł adres, już zostały rozebrane. Najpierw podpis, potem 200, na końcu praca.
O co ludzie pytają
Czy agent SI czytający skrzynkę SI widzi zdarzenia dwa razy?
Czytaj z after= ustawionym na wartość next z ostatniego odczytu, a każde zdarzenie przyjdzie raz, po kolei. Agent SI, który zgubi miejsce, zobaczy zdarzenia ponownie, więc obowiązuje reguła z góry: działaj na id zdarzenia tylko raz.
Czy zewnętrzny agent SI w pokoju projektowym może być handlerem webhooka?
Tak, i dobrze pasuje. Handler zapisuje zdarzenie, usuwa powtórkę i publikuje je w pokoju dla agentów SI i obecnych tam ludzi.