Skip to content

events/queue: read ScheduledTime under the lock and match it in execute - #172

Merged
cicoyle merged 1 commit into
dapr:mainfrom
JoshVanL:fix/queue-peek-under-lock
Oct 16, 2026
Merged

cicoyle merged 1 commit into
dapr:mainfrom
JoshVanL:fix/queue-peek-under-lock

Conversation

@JoshVanL

Copy link
Copy Markdown
Contributor

processLoop peeked the front item under the lock but called ScheduledTime after unlocking, so a concurrent Dequeue could hand the item back to its owner first. go-cron reset and reused such items, and the read dereferenced the reset state (nil pointer SIGSEGV in the dapr scheduler under load). The heap already calls ScheduledTime under this lock on every Enqueue, so no new lock order.

execute also matched the front item by pointer only. An owner that dequeued an item and enqueued the same pointer with a later time could have it fire at the old time. execute now also requires the scheduled time read by processLoop, and restarts the loop if it changed.

processLoop peeked the front item under the lock but called ScheduledTime
after unlocking, so a concurrent Dequeue could hand the item back to its owner
first. go-cron reset and reused such items, and the read dereferenced the reset
state (nil pointer SIGSEGV in the dapr scheduler under load). The heap already
calls ScheduledTime under this lock on every Enqueue, so no new lock order.

execute also matched the front item by pointer only. An owner that dequeued an
item and enqueued the same pointer with a later time could have it fire at the
old time. execute now also requires the scheduled time read by processLoop,
and restarts the loop if it changed.

Signed-off-by: joshvanl <me@joshvanl.dev>
@JoshVanL
JoshVanL requested a balanced review from Copilot October 16, 2026 15:45
@JoshVanL
JoshVanL requested review from a team as code owners October 16, 2026 15:45

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The focused synchronization fixes have regression coverage and no identified blocking issues; tests were not run.

0 open findings

What changed in this PR

Fixes queue scheduling races when owners dequeue and reuse items.

Changes:

  • Reads scheduled times while holding the processor lock.
  • Checks both item identity and scheduled time before execution.
  • Adds regression tests for lock protection and rescheduling.
File Description
events/​queue/​queue.go Documents scheduled-time locking guarantees.
events/​queue/​processor.go Protects reads and rejects stale execution attempts.
events/​queue/​processor_peeklock_test.go Tests locked reads and reused-item scheduling.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@cicoyle
cicoyle merged commit 95535a2 into dapr:main Oct 16, 2026
6 checks passed
dapr-bot pushed a commit to karljaxon/dapr that referenced this pull request Oct 19, 2026
Use the tags for 1.19 in place of the main commits that RC3 and RC4
pin. kit v0.19.0 adds dapr/kit#172. durabletask-go v0.15.1 is the
commit that is pinned now.

Signed-off-by: Nelson Parente <nelson_parente@live.com.pt>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants