Replace mutex state machine with channel-based send loop

The emitter coordinated background sends via a mutex protecting three booleans (sending, pending, stopped), a WaitGroup, and a recursive goroutine-spawning start() method. This was hard to follow and reason about correctness.

This replaces all of that with a single long-lived goroutine reading from a chan struct{} (capacity 1). AddAsync/Flush do a non-blocking send on the channel; the goroutine drains storage on each signal. Stop() cancels the context and waits for the goroutine to exit via a done channel.

Also adds a backoff after failed send.

Builds on top of !259 (merged), refs https://gitlab.com/gitlab-org/architecture/usage-billing/design-doc/-/work_items/36.

Edited by Igor

Merge request reports

Loading