- शिप
- 28 सितंबर 2026 को 2:53 am बजे UTC
- लेखक
- Kamo
- Commit
- 8a8d34c
DaemonService hands ConversionService every row that is still unprocessed: on its poll tick, on every voip.recording.received message (which does not wait for a batch in flight), and again after its 10-minute read timeout gives up on a batch still running here. Chunked transcription through AIService runs at about 0.4 x real time, so a call batch with more than ~24 minutes of audio outlasts that window, and the rows still in flight were converted, transcribed and stored a second time: a duplicate Img/Recording row and AUDIO_SECONDS metered twice. processOne now takes a Redis lease on the row (SET NX PX, random token) before reading it. The lease is renewed every third of its 5 minutes while the work runs, so a dead pod drops it within one lease; a worker past 4 hours stops renewing. Before storing, the worker checks it still holds the lease, and a failure is written to the row only while it does. A row another worker holds answers ok/inFlight untouched; Redis unreachable leaves the row for a later tick (fails closed, like SingletonTaskRunner). Redis, not a column: no DDL. **************** pins the failure scenario: a 3-recording, 30-minute batch dispatched again while its first recording is transcribing stores and transcribes each recording once (4 transcriptions without the claim). SP12 final review I2.
