KamoCRM

A conversation loads and a message sends on the first try

FixMediaService
Spegnimento
27 settembre 2026 alle ore 06:14 UTC
Autore
Kamo
Impegno
279a389

Chat has been failing in two ways a member notices at once: opening a conversation showed "Couldn't load messages" until Retry was pressed, and a sent message sometimes never arrived. Both were MediaService answering 500 with YugabyteDB SQLState 40001, "Restart read required" — logged daily on both pods, and every 500 the web BFF recorded this week lines up with one. Yugabyte restarts a read for free only when it is the FIRST statement of its transaction. The history load checks access on its third statement by reading the caller's membership row — the row that opening the conversation marks read in the same instant. A send writes the message and then reads the roster and the org's domain in the same transaction. Either read meeting a row written a moment earlier failed the whole request; a moment later the write had settled, which is why Retry always worked. - The chat window's requests (send, history, mark-read, chat list, edit, faces, members, receipts) carry @RetryOnDbConflict, and their catch-alls let a conflict out **************** so the advisor can re-run it in a NEW transaction. Swallowed into a 500 it was invisible to the retry. Safe: everything a send announces is after-commit. - Mark-read no longer rewrites the membership row when the pointer is already there (ChatReadPointerRepository, a guarded UPDATE). It was called several times per open, and every rewrite was a chance for the member's own history load or send to fail. The read receipt still goes out as before. - A send may carry a clientMessageId (ChatSendLedger, Redis): a retry of a send that already committed is answered with that send's response, and one still in flight with 409 SEND_IN_PROGRESS, so the client can retry without ever posting a message twice. Fails open. A ratchet **************** holds every @Transactional chat handler to the retry, and the retry to a catch that lets the conflict out. MediaControllerDbConflictTest replays the production failure through a real proxy: the conflicted attempt rolls back, a second transaction commits once, and nothing is announced for the attempt that failed. 1384 tests pass.

Tutte le modifiche

Come quello che vedi la spedizione?

Tutto questo arriva nel vostro spazio di lavoro da solo. Iniziare sul piano gratuito e leggere di nuovo questa pagina in un mese.

Inizia gratis per sempreVisualizza il prezzo