You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Follow-up from the PR #662 review (yujiawei, P2; Jerry-Xin concurred). Non-blocking defense-in-depth.
Problem
In internal/cardactiondispatch/queue.go, the route-missing first-seen marker (route_missing_since) is now cleared under a token guard (clearRouteMissingScript: HGET tokens[id] == token before HDEL), but it is written without one β routeMissingSinceScript (RouteMissingSeenAt) does HSETNX keyed only by event_id, no ownership check.
This leaves one asymmetric-refund corner open. Trace:
Worker A (token T-A) claims a route-missing event and issues RouteMissingSeenAt, but the Redis call stalls in flight (GC/scheduler).
A's lease expires β ReclaimExpired requeues it β Worker B (token T-B) claims it. B sees the route has recovered, calls ClearRouteMissing (valid T-B) β marker gone β B proceeds to Deliver.
A's stalled RouteMissingSeenAt finally lands and re-plants the marker (HSETNX on the now-absent field).
Requires an in-flight marker write reordered past a lease expiry and a reclaim + re-claim and a route recovery and a delivery crash, all in the same episode. No data loss (idempotent consumer); worst case is a delayed dead-letter. Reviewers explicitly called this a follow-up, not a merge blocker.
Possible fix
Token-guard the marker write symmetric to the clear: give routeMissingSinceScript the tokens key + token arg and only HSETNX when HGET tokens[id] == token. This is a signature change β RouteMissingSeenAt gains a token param β touching the dispatchQueue interface and the two test fakes; the dispatcher already holds lease.Token at the call site.
Ref: PR #662, yujiawei review at head fe386b40; tracked in .octospec/tasks/card-action-dispatch-defer-hardening/context.yaml as item (c).
Follow-up from the PR #662 review (yujiawei, P2; Jerry-Xin concurred). Non-blocking defense-in-depth.
Problem
In
internal/cardactiondispatch/queue.go, the route-missing first-seen marker (route_missing_since) is now cleared under a token guard (clearRouteMissingScript:HGET tokens[id] == tokenbeforeHDEL), but it is written without one βrouteMissingSinceScript(RouteMissingSeenAt) doesHSETNXkeyed only byevent_id, no ownership check.This leaves one asymmetric-refund corner open. Trace:
T-A) claims a route-missing event and issuesRouteMissingSeenAt, but the Redis call stalls in flight (GC/scheduler).ReclaimExpiredrequeues it β Worker B (tokenT-B) claims it. B sees the route has recovered, callsClearRouteMissing(validT-B) β marker gone β B proceeds toDeliver.RouteMissingSeenAtfinally lands and re-plants the marker (HSETNXon the now-absent field).reclaimScriptsees the re-planted marker β refunds B's genuine delivery attempt β the exactMaxAttempts-bound bypass PR fix(cardaction): harden route-missing defer path β reclaim attempt-leak + LiveTTL floor (#623, #624)Β #662 closed for the common path.Severity: astronomically narrow / non-blocking
Requires an in-flight marker write reordered past a lease expiry and a reclaim + re-claim and a route recovery and a delivery crash, all in the same episode. No data loss (idempotent consumer); worst case is a delayed dead-letter. Reviewers explicitly called this a follow-up, not a merge blocker.
Possible fix
Token-guard the marker write symmetric to the clear: give
routeMissingSinceScriptthe tokens key + token arg and onlyHSETNXwhenHGET tokens[id] == token. This is a signature change βRouteMissingSeenAtgains atokenparam β touching thedispatchQueueinterface and the two test fakes; the dispatcher already holdslease.Tokenat the call site.Ref: PR #662, yujiawei review at head
fe386b40; tracked in.octospec/tasks/card-action-dispatch-defer-hardening/context.yamlas item (c).