Skip to content

fix: PriorityJobQueue follow-ups from #100 review (#103) - #104

Merged
wpak-ai merged 2 commits into
developfrom
fix/queue-followups-103
Jul 31, 2026
Merged

fix: PriorityJobQueue follow-ups from #100 review (#103)#104
wpak-ai merged 2 commits into
developfrom
fix/queue-followups-103

Conversation

@bradjin8

@bradjin8 bradjin8 commented Jul 31, 2026

Copy link
Copy Markdown
Collaborator

Summary

Addresses the three remaining review items from #100 / merged #101 that were not included before that PR closed:

  • cancel_all emits JOB_CANCELLED for each cancelled job, matching cancel().
  • Event listeners run outside self._lock - snapshot listeners under the lock and dispatch callbacks after release so listeners can safely call back into the queue.
  • all_dependencies_met treats FAILED and CANCELLED as unmet - only PASSED and SKIPPED satisfy needs dependencies; dependents no longer become ready after a failed or cancelled upstream job.

Closes #100

Test plan

  • pytest tests/test_queue.py (34 passed)
  • pre-commit run --files cli/localci/core/queue.py cli/tests/test_queue.py CHANGELOG.md
  • CI green

Notes

Issue #103 scope updated from release-only work to these queue follow-ups; v0.1.0 release prep remains on release/v0.1.0 (PR #103 on that branch).

Summary by CodeRabbit

  • New Features

    • Added queue cancellation events for cancelled jobs.
    • Jobs with failed or cancelled dependencies are now blocked from running.
    • Passed and skipped dependencies are recognized as complete.
  • Bug Fixes

    • Queue event listeners now run safely after queue state updates and in FIFO order.
    • Improved cancellation event reporting when cancelling multiple jobs.
  • Documentation

    • Updated the changelog with queue cancellation, dependency blocking, and event listener behavior.

Emit JOB_CANCELLED in cancel_all, dispatch listeners outside the lock,
and treat FAILED/CANCELLED dependencies as unmet in all_dependencies_met.
@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 08b2f9ec-79d6-4260-a519-948a786b024d

📥 Commits

Reviewing files that changed from the base of the PR and between 097ccfe and f93c380.

📒 Files selected for processing (2)
  • cli/localci/core/queue.py
  • cli/tests/test_queue.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • cli/tests/test_queue.py

📝 Walkthrough

Walkthrough

Queue dependency checks now use job statuses. Queue events are collected under the lock and dispatched after unlocking. Cancellation, priority, completion, and listener behavior receive updated test coverage and changelog entries.

Changes

Queue behavior updates

Layer / File(s) Summary
Status-based dependency readiness
cli/localci/core/queue.py, cli/tests/test_queue.py
Dependency checks require existing jobs to be PASSED or SKIPPED. Failed and cancelled dependencies keep dependent jobs blocked.
Deferred queue event dispatch
cli/localci/core/queue.py, cli/tests/test_queue.py, CHANGELOG.md
Queue transitions defer listener callbacks until after releasing the queue lock. Cancellation, priority, completion, and listener behavior are covered by tests and documented in the changelog.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

Suggested reviewers: wpak-ai, clean6378-max-it

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR does not implement issue #103 release requirements for CHANGELOG.md, SECURITY.md, or CONTRIBUTING.md. Implement the release-preparation requirements in issue #103, or update the linked issue to explicitly describe the PriorityJobQueue follow-ups.
Out of Scope Changes check ⚠️ Warning The queue behavior and tests address PriorityJobQueue follow-ups, not the linked issue's release-preparation scope. Move the PriorityJobQueue changes to a correctly scoped issue or update issue #103 before merging.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies PriorityJobQueue follow-up fixes and accurately reflects the main code changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/queue-followups-103

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (2)
cli/tests/test_queue.py (2)

155-160: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Cover every dependency-satisfaction case.

This test does not verify that SKIPPED satisfies needs. It also does not verify that a missing dependency remains unmet.

Add assertions for both cases. The resolver contract requires an existing dependency in PASSED or SKIPPED status.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cli/tests/test_queue.py` around lines 155 - 160, Add coverage in the
dependency-status test around resolver.all_dependencies_met: assert that an
existing upstream dependency with QueuedJobStatus.SKIPPED satisfies the
downstream need, and assert that a missing dependency remains unmet. Preserve
the existing PASSED, FAILED, and CANCELLED assertions.

259-270: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Make the deadlock regression fail instead of hang.

If callbacks run while self._lock is held again, queue.enqueue(...) blocks inside listener. The subsequent acquired.wait(timeout=5) never runs, so this test can hang CI indefinitely.

Run enqueue in a daemon worker thread. Join with a timeout, then assert that the worker completed.

Proposed fix
         queue.add_listener(listener)
-        queue.enqueue(make_job("Job 2", priority=1, index=1))
-        assert acquired.wait(timeout=5)
+        worker = threading.Thread(
+            target=lambda: queue.enqueue(make_job("Job 2", priority=1, index=1)),
+            daemon=True,
+        )
+        worker.start()
+        worker.join(timeout=5)
+
+        assert not worker.is_alive()
+        assert acquired.is_set()
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cli/tests/test_queue.py` around lines 259 - 270, Update
test_listener_can_acquire_lock_during_callback to execute the second
queue.enqueue call in a daemon worker thread. Join that thread with a timeout,
assert it completed, then assert acquired.wait(timeout=5) so a lock-held
callback causes a bounded test failure rather than hanging CI.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@cli/localci/core/queue.py`:
- Around line 189-193: Update _prepare_emit to capture the job’s state while
self._lock is held, so each JobEvent contains an immutable snapshot or
transition state rather than the mutable QueuedJob reference. Ensure later queue
operations and listeners cannot alter the status observed by previously prepared
events, preserving the event’s state at emission time.
- Around line 195-201: Update the queue event flow around _dispatch_emits so
emitted events are appended to a queue-owned FIFO while self._lock is held,
rather than dispatched from operation-local pending lists. After releasing
self._lock, drain that shared FIFO through a single dispatcher, preserving
enqueue/transition order across concurrent operations; do not rely on a
dispatcher mutex protecting only local pending lists.
- Around line 186-187: Update add_listener to acquire self._lock before
appending the callback to _listeners, ensuring registration is synchronized with
_prepare_emit’s listener snapshots while preserving the existing callback
registration behavior.

---

Nitpick comments:
In `@cli/tests/test_queue.py`:
- Around line 155-160: Add coverage in the dependency-status test around
resolver.all_dependencies_met: assert that an existing upstream dependency with
QueuedJobStatus.SKIPPED satisfies the downstream need, and assert that a missing
dependency remains unmet. Preserve the existing PASSED, FAILED, and CANCELLED
assertions.
- Around line 259-270: Update test_listener_can_acquire_lock_during_callback to
execute the second queue.enqueue call in a daemon worker thread. Join that
thread with a timeout, assert it completed, then assert acquired.wait(timeout=5)
so a lock-held callback causes a bounded test failure rather than hanging CI.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0b18e742-73ae-48f3-876d-ce34ae3673ad

📥 Commits

Reviewing files that changed from the base of the PR and between 09ebd73 and 097ccfe.

📒 Files selected for processing (3)
  • CHANGELOG.md
  • cli/localci/core/queue.py
  • cli/tests/test_queue.py

Comment thread cli/localci/core/queue.py Outdated
Comment thread cli/localci/core/queue.py
Comment thread cli/localci/core/queue.py Outdated
@bradjin8 bradjin8 self-assigned this Jul 31, 2026
@wpak-ai
wpak-ai merged commit 2c804a3 into develop Jul 31, 2026
7 checks passed
@wpak-ai
wpak-ai deleted the fix/queue-followups-103 branch July 31, 2026 18:18
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.

Take the lock in PriorityJobQueue.is_done

2 participants