Repository navigation
feat(resumption): throttle paused-task replay when tasks queue is busy - #986
Conversation
Before fetching each batch, the ESS resumption worker checks the backlog on xmc-tasks-stream (pending + lag via XINFO GROUPS and a capped XRANGE). If it reaches max_backlog_threshold, the worker waits 10s and returns to the top of the loop, so pause state and fencing are re-checked first. Backlog calculation lives in the task_queue client so ESS only depends on a small BacklogChecker interface. ExtendClaim is left as a TODO until the lease-extension API lands. TAG=agy CONV=089ef675-f585-4067-9e62-27ef0bad0823
There was a problem hiding this comment.
Code Review
This pull request introduces downstream task queue backlog checking and throttling to the ResumptionWorker. It adds a BacklogChecker interface and implements Redis stream backlog calculation (pending + lag) via CalculateStreamBacklog to pause task replay when the backlog exceeds a specified threshold. Comprehensive unit tests and Bazel build updates are also included. The review feedback suggests two key improvements: replacing time.After with time.NewTimer in the throttling loop to prevent potential short-term memory leaks, and optimizing the backlog calculation to skip or limit XRANGE queries when the pending message count already meets or exceeds the threshold.
- Use time.NewTimer with explicit Stop for the throttle wait and extract it into a reusable waitOrCancel method. - Skip XRANGE when pending alone meets the threshold and otherwise read only threshold - pending + 1 entries. TAG=agy CONV=089ef675-f585-4067-9e62-27ef0bad0823
…ty backlog fallbacks - Merge PayloadPublisher and BacklogChecker into a single TaskQueue interface so the task queue client is passed once. - Warn when backlog inspection silently falls back to an empty backlog (missing/unsupported Redis client, missing consumer group). - Add tests for backlog == threshold and the default threshold fallback. TAG=agy CONV=089ef675-f585-4067-9e62-27ef0bad0823
- Merge throttle decision cases into a single table test. - Share worker setup across stop-while-throttled tests. - Drop waitOrCancel tests already covered by the throttling tests. TAG=agy CONV=089ef675-f585-4067-9e62-27ef0bad0823
Move the stream backlog logic into redisclient as PublisherClient.BacklogLength, using the publisher's stream and a caller-provided consumer group. task_queue.Client.CalculateBacklogLength now takes the group and delegates. Address review feedback: - Rename CalculateBacklog to CalculateBacklogLength and document the capped count. - Return 0 when the stream disappears before XRANGE (pending entries go with it). - Log pause_duration when throttling replay. TAG=agy CONV=089ef675-f585-4067-9e62-27ef0bad0823
…sher TAG=agy CONV=089ef675-f585-4067-9e62-27ef0bad0823
|
@janzak-dev While addressing the comments I noticed that the backlog.go was put in the wrong place (in the taskqueue instead of redisclient). That's why more things were changed since your last review, all of it is intentional. |
Summary
The ESS resumption worker now pauses replay while
xmc-tasks-streamis busy, so replaying paused tasks can't push Redis toward its memory limit.Key Changes
Client.CalculateBacklogcomputespending + lagusingXINFO GROUPSandXRANGE. XRANGE is skipped whenpendingalone reaches the threshold, and otherwise reads onlythreshold - pending + 1entries, so the result is capped just above the threshold. A missing stream counts as zero backlog. Cases that silently fall back to an empty backlog (missing or unsupported Redis client, missing consumer group) log a warning. A compile-time check makes sure the production publisher supports the needed Redis commands.max_backlog_thresholdfrom the trigger message (default 500). If the backlog is at or above it, the worker waits 10s (cancellable) and goes back to the top of the loop, so pause state and fencing are re-checked before anything is replayed. The worker takes a singleTaskQueuedependency (enqueue + backlog), whichtask_queue.Clientsatisfies.Out of scope
xmc_resumption_throttles_totaletc.) come in a separate PR.Verification
bazel test //internal/task_queue:task_queue_test //cmd/experiment_state_server/resumption:resumption_test(Passed)bazel build //cmd/experiment_state_server/...(Passed)TAG=agy
CONV=089ef675-f585-4067-9e62-27ef0bad0823