Skip to content

Document wait_or_shutdown helper#85

Merged
leynos merged 2 commits intomainfrom
codex/add-doc-comment-and-example-to-worker.rs
Sep 11, 2025
Merged

Document wait_or_shutdown helper#85
leynos merged 2 commits intomainfrom
codex/add-doc-comment-and-example-to-worker.rs

Conversation

@leynos
Copy link
Copy Markdown
Owner

@leynos leynos commented Sep 11, 2025

Summary

  • document wait_or_shutdown with parameters and a simple example

Testing

  • make fmt
  • make lint
  • make test

https://chatgpt.com/codex/tasks/task_e_68c1e4cd07788322bb69b6895799390d

Summary by Sourcery

Documentation:

  • Document WorkerHooks::wait_or_shutdown with parameter descriptions and a code example

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Sep 11, 2025

Summary by CodeRabbit

  • New Features

    • Added a helper to wait for either a specified timeout or a shutdown signal, improving responsiveness and preventing blocking during shutdown. Supports immediate return with zero seconds. No existing behaviour changed.
  • Documentation

    • Included usage examples and guidance for the new helper to clarify expected behaviour and typical use cases.

Summary by CodeRabbit

  • New Features
    • Added an asynchronous wait that completes on either a timeout or a shutdown signal, enabling smoother graceful shutdowns and more responsive worker control without blocking.
  • Documentation
    • Included usage examples for the new waiting behaviour.
  • Chores
    • Expanded the public API to support non-blocking waits integrated with shutdown handling, without altering existing behaviour.

Walkthrough

Add a new public async helper to WorkerHooks: wait_or_shutdown(secs: u64, shutdown: &mut watch::Receiver<()>), which awaits either a timeout via Tokio sleep or a shutdown signal via shutdown.changed(), returning when either completes. No existing code paths are altered.

Changes

Cohort / File(s) Summary
Worker wait helper
crates/comenqd/src/worker.rs
Add pub async fn wait_or_shutdown(secs: u64, shutdown: &mut watch::Receiver<()>) using tokio::select! to await sleep or shutdown.changed(). Include docs and examples.

Sequence Diagram(s)

sequenceDiagram
    actor Caller
    participant WH as WorkerHooks::wait_or_shutdown
    participant T as tokio::time::sleep
    participant S as shutdown watch::Receiver

    Caller->>WH: wait_or_shutdown(secs, &mut shutdown)
    activate WH
    WH->>T: sleep(secs)
    WH->>S: changed()
    alt timeout
        T-->>WH: sleep completes
        WH-->>Caller: return (timeout elapsed)
    else shutdown
        S-->>WH: change observed
        WH-->>Caller: return (shutdown signalled)
    end
    deactivate WH
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Pre-merge checks (3 passed)

✅ Passed checks (3 passed)
Check name Status Explanation
Title Check ✅ Passed Mark the title as accurate and concise; it directly names the primary change (documenting the wait_or_shutdown helper) and maps to the added doc comment and example in crates/comenqd/src/worker.rs. The title is short, specific and readable for history scans.
Description Check ✅ Passed Accept the description as related to the changeset; it summarises the documentation addition, lists testing steps and includes the Sourcery summary which aligns with the changeset. The description is not off-topic and therefore meets the lenient criteria for this check.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

Poem

A tick, a tock, a whisper: “down we go?”
Sleep waits in one lane, signals in the other’s flow.
Select the first to knock upon the gate—
Timeout or hush, either seals the fate.
The worker nods: “I’m ready when you say so.” ⏳🛎️


📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 74c7323 and 363fb9d.

📒 Files selected for processing (1)
  • crates/comenqd/src/worker.rs (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

**/*.rs: Clippy warnings MUST be disallowed.
Fix any warnings emitted during tests in the code itself rather than silencing them.
Where a function is too long, extract meaningfully named helper functions adhering to separation of concerns and CQRS.
Where a function has too many parameters, group related parameters in meaningfully named structs.
Where a function is returning a large error consider using Arc to reduce the amount of data returned.
Write unit and behavioural tests for new functionality. Run both before and after making any change.
Every module must begin with a module level (//! ) comment explaining the module's purpose and utility.
Document public APIs using Rustdoc comments (///) so documentation can be generated with cargo doc.
Prefer immutable data and avoid unnecessary mut bindings.
Handle errors with the Result type instead of panicking where feasible.
Avoid unsafe code unless absolutely necessary and document any usage clearly.
Place function attributes after doc comments.
Do not use return in single-line functions.
Use predicate functions for conditional criteria with more than two branches.
Lints must not be silenced except as a last resort.
Lint rule suppressions must be tightly scoped and include a clear reason.
Prefer expect over allow.
Use rstest fixtures for shared setup.
Replace duplicated tests with #[rstest(...)] parameterised cases.
Prefer mockall for mocks/stubs.
Prefer .expect() over .unwrap().
Use concat!() to combine long string literals rather than escaping newlines with a backslash.
Prefer semantic error enums. Derive std::error::Error (via the thiserror crate) for any condition the caller might inspect, retry, or map to an HTTP status.
Use an opaque error only at the app boundary. Use eyre::Report for human-readable logs; these should not be exposed in public APIs.
Never export the opaque type from a library. Convert to domain enums at API boundaries, and to eyre only in the main main() entrypoint or top-level async task.

Files:

  • crates/comenqd/src/worker.rs

⚙️ CodeRabbit configuration file

**/*.rs: * Seek to keep the cyclomatic complexity of functions no more than 12.

  • Adhere to single responsibility and CQRS

  • Place function attributes after doc comments.

  • Do not use return in single-line functions.

  • Move conditionals with >2 branches into a predicate function.

  • Avoid unsafe unless absolutely necessary.

  • Every module must begin with a //! doc comment that explains the module's purpose and utility.

  • Comments and docs must follow en-GB-oxendict (-ize / -our) spelling and grammar

  • Lints must not be silenced except as a last resort.

    • #[allow] is forbidden.
    • Only narrowly scoped #[expect(lint, reason = "...")] is allowed.
    • No lint groups, no blanket or file-wide suppression.
    • Include FIXME: with link if a fix is expected.
  • Where code is only used by specific features, it must be conditionally compiled or a conditional expectation for unused_code applied.

  • Use rstest fixtures for shared setup and to avoid repetition between tests.

  • Replace duplicated tests with #[rstest(...)] parameterised cases.

  • Prefer mockall for mocks/stubs.

  • Prefer .expect() over .unwrap()

  • Ensure that any API or behavioural changes are reflected in the documentation in docs/

  • Ensure that any completed roadmap steps are recorded in the appropriate roadmap in docs/

  • Files must not exceed 400 lines in length

    • Large modules must be decomposed
    • Long match statements or dispatch tables should be decomposed by domain and collocated with targets
    • Large blocks of inline data (e.g., test fixtures, constants or templates) must be moved to external files and inlined at compile-time or loaded at run-time.
  • Environment access (env::set_var and env::remove_var) are always unsafe in Rust 2024 and MUST be marked as such

    • For testing of functionality depending upon environment variables, dependency injection and the mockable crate are the preferred option.
    • If mockable cannot be used, env mutations in tests ...

Files:

  • crates/comenqd/src/worker.rs
🔍 Remote MCP

(no further information available through external documentation sources).

Context Summary for wait_or_shutdown PR Review

Based on the provided pull request context, I can identify several key areas of improvement and concerns that would be valuable for reviewing this PR effectively:

Function Implementation Analysis:
The PR adds a new wait_or_shutdown helper function to WorkerHooks with the signature:

pub async fn wait_or_shutdown(secs: u64, shutdown: &mut watch::Receiver<()>)

This function uses tokio::select! to wait for either a timeout or shutdown signal, implemented as an associated method without &self parameter.

Key Reviewer Concerns Identified:

1. Select Handling Priority Issue

  • Problem: Current implementation may not prioritize shutdown signals appropriately
  • Proposed Fix: Add biased; to tokio::select! and reorder arms to check shutdown before timeout
  • Critical for: Ensuring immediate responsiveness to shutdown signals

2. API Design Improvement

  • Current Issue: Using secs: u64 parameter lacks clarity and risks unit mistakes
  • Proposed Change: Replace with Duration parameter type for better call-site clarity
  • Benefits: Type safety and clearer intent at call sites

3. Testing Gap

  • Missing Tests: No focused async tests for the new functionality
  • Required Scenarios: timeout behavior, shutdown-before-timeout, zero-duration edge cases
  • Framework: Should use rstest/Tokio for comprehensive coverage

4. CI/Test Failure

  • Specific Issue: Unfulfilled lint expectation in crates/comenqd/tests/util.rs
  • Error: #[expect(dead_code, reason = "...")] triggered under -D unfulfilled-lint-expectations
  • Impact: Preventing CI completion and blocking merge

Bot Integration:
The coderabbitai bot has created GitHub issues #87, #88, and #89 to track these improvements, providing detailed code examples and assigning them to the PR author.

Recommendation Priority:

  1. High: Fix CI failure to unblock pipeline
  2. Medium: Add biased select for shutdown priority
  3. Medium: Implement comprehensive async testing
  4. Low: Consider Duration API change for future enhancement
🔇 Additional comments (1)
crates/comenqd/src/worker.rs (1)

99-103: Use Duration instead of u64 seconds for type safety.

Adopt a Duration API and update docs and callers.

File: crates/comenqd/src/worker.rs (hunk: 99–103; also applies to 106–121, 125–129)

-/// - `secs` - Number of seconds to wait before continuing.
+/// - `duration` - How long to wait before continuing.
-/// WorkerHooks::wait_or_shutdown(1, &mut rx).await;
+/// use std::time::Duration;
+/// WorkerHooks::wait_or_shutdown(Duration::from_secs(1), &mut rx).await;
@@
-/// WorkerHooks::wait_or_shutdown(60, &mut rx).await;
+/// WorkerHooks::wait_or_shutdown(Duration::from_secs(60), &mut rx).await;
-pub async fn wait_or_shutdown(secs: u64, shutdown: &mut watch::Receiver<()>) {
-    tokio::select! {
-        biased;
-        _ = shutdown.changed() => {},
-        _ = tokio::time::sleep(Duration::from_secs(secs)) => {},
-    }
-}
+pub async fn wait_or_shutdown(duration: Duration, shutdown: &mut watch::Receiver<()>) {
+    tokio::select! {
+        biased;
+        _ = shutdown.changed() => {},
+        _ = tokio::time::sleep(duration) => {},
+    }
+}
-WorkerHooks::wait_or_shutdown(config.cooldown_period_seconds, shutdown).await;
+WorkerHooks::wait_or_shutdown(Duration::from_secs(config.cooldown_period_seconds), shutdown).await;

Verify call sites by listing all usages and inspect each match:

rg -n --hidden --no-ignore-vcs -g '!**/target/**' 'wait_or_shutdown\('
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch codex/add-doc-comment-and-example-to-worker.rs

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

@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented Sep 11, 2025

Reviewer's Guide

Added comprehensive Rust documentation to the wait_or_shutdown helper in WorkerHooks, detailing its behavior, parameters, and usage with an example.

Class diagram for WorkerHooks with documented wait_or_shutdown

classDiagram
    class WorkerHooks {
        +wait_or_shutdown(secs: u64, shutdown: &mut watch::Receiver<()>)
    }
Loading

File-Level Changes

Change Details Files
Added Rust doc comments for the wait_or_shutdown helper, including parameters and usage example
  • Introduced method-level documentation header describing behavior
  • Documented secs and shutdown parameters in # Arguments
  • Provided a code example demonstrating typical usage
crates/comenqd/src/worker.rs

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

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

Hey there - I've reviewed your changes and found some issues that need to be addressed.


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
crates/comenqd/src/worker.rs (3)

122-127: Prioritise shutdown when both events are ready; bias the select and reorder arms.

Ensure immediate responsiveness to shutdown by preferring the shutdown branch when both futures are ready in the same tick.

Apply:

-        tokio::select! {
-            _ = tokio::time::sleep(Duration::from_secs(secs)) => {},
-            _ = shutdown.changed() => {},
-        }
+        tokio::select! {
+            biased;
+            _ = shutdown.changed() => {},
+            _ = tokio::time::sleep(Duration::from_secs(secs)) => {},
+        }

122-127: Take Duration instead of seconds to improve call-site clarity and prevent unit mistakes.

Accept Duration directly and remove implicit unit conversion. Update call sites accordingly.

Apply in this block:

-    pub async fn wait_or_shutdown(secs: u64, shutdown: &mut watch::Receiver<()>) {
+    pub async fn wait_or_shutdown(duration: Duration, shutdown: &mut watch::Receiver<()>) {
         tokio::select! {
-            biased;
-            _ = shutdown.changed() => {},
-            _ = tokio::time::sleep(Duration::from_secs(secs)) => {},
+            biased;
+            _ = shutdown.changed() => {},
+            _ = tokio::time::sleep(duration) => {},
         }
     }

Also update call sites (outside this hunk):

-WorkerHooks::wait_or_shutdown(config.cooldown_period_seconds, shutdown).await;
+WorkerHooks::wait_or_shutdown(Duration::from_secs(config.cooldown_period_seconds), shutdown).await;

122-127: Add focused tests for timeout and shutdown paths using rstest.

Exercise both branches and the zero-duration edge to meet the testing guideline.

Add a new async test module:

#[cfg(test)]
mod tests {
    use super::*;
    use rstest::rstest;
    use tokio::sync::watch;

    #[tokio::test]
    async fn returns_immediately_on_zero_secs() {
        let (_tx, mut rx) = watch::channel(());
        WorkerHooks::wait_or_shutdown(Duration::from_secs(0), &mut rx).await;
    }

    #[tokio::test]
    async fn returns_on_shutdown_before_timeout() {
        let (tx, mut rx) = watch::channel(());
        let mut rx2 = tx.subscribe();
        let fut = WorkerHooks::wait_or_shutdown(Duration::from_secs(60), &mut rx2);
        tx.send(()).expect("notify");
        fut.await;
    }
}

Do you want me to open a follow-up PR with these tests?

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7e1e364 and 74c7323.

📒 Files selected for processing (1)
  • crates/comenqd/src/worker.rs (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

**/*.rs: Clippy warnings MUST be disallowed.
Fix any warnings emitted during tests in the code itself rather than silencing them.
Where a function is too long, extract meaningfully named helper functions adhering to separation of concerns and CQRS.
Where a function has too many parameters, group related parameters in meaningfully named structs.
Where a function is returning a large error consider using Arc to reduce the amount of data returned.
Write unit and behavioural tests for new functionality. Run both before and after making any change.
Every module must begin with a module level (//! ) comment explaining the module's purpose and utility.
Document public APIs using Rustdoc comments (///) so documentation can be generated with cargo doc.
Prefer immutable data and avoid unnecessary mut bindings.
Handle errors with the Result type instead of panicking where feasible.
Avoid unsafe code unless absolutely necessary and document any usage clearly.
Place function attributes after doc comments.
Do not use return in single-line functions.
Use predicate functions for conditional criteria with more than two branches.
Lints must not be silenced except as a last resort.
Lint rule suppressions must be tightly scoped and include a clear reason.
Prefer expect over allow.
Use rstest fixtures for shared setup.
Replace duplicated tests with #[rstest(...)] parameterised cases.
Prefer mockall for mocks/stubs.
Prefer .expect() over .unwrap().
Use concat!() to combine long string literals rather than escaping newlines with a backslash.
Prefer semantic error enums. Derive std::error::Error (via the thiserror crate) for any condition the caller might inspect, retry, or map to an HTTP status.
Use an opaque error only at the app boundary. Use eyre::Report for human-readable logs; these should not be exposed in public APIs.
Never export the opaque type from a library. Convert to domain enums at API boundaries, and to eyre only in the main main() entrypoint or top-level async task.

Files:

  • crates/comenqd/src/worker.rs

⚙️ CodeRabbit configuration file

**/*.rs: * Seek to keep the cyclomatic complexity of functions no more than 12.

  • Adhere to single responsibility and CQRS

  • Place function attributes after doc comments.

  • Do not use return in single-line functions.

  • Move conditionals with >2 branches into a predicate function.

  • Avoid unsafe unless absolutely necessary.

  • Every module must begin with a //! doc comment that explains the module's purpose and utility.

  • Comments and docs must follow en-GB-oxendict (-ize / -our) spelling and grammar

  • Lints must not be silenced except as a last resort.

    • #[allow] is forbidden.
    • Only narrowly scoped #[expect(lint, reason = "...")] is allowed.
    • No lint groups, no blanket or file-wide suppression.
    • Include FIXME: with link if a fix is expected.
  • Where code is only used by specific features, it must be conditionally compiled or a conditional expectation for unused_code applied.

  • Use rstest fixtures for shared setup and to avoid repetition between tests.

  • Replace duplicated tests with #[rstest(...)] parameterised cases.

  • Prefer mockall for mocks/stubs.

  • Prefer .expect() over .unwrap()

  • Ensure that any API or behavioural changes are reflected in the documentation in docs/

  • Ensure that any completed roadmap steps are recorded in the appropriate roadmap in docs/

  • Files must not exceed 400 lines in length

    • Large modules must be decomposed
    • Long match statements or dispatch tables should be decomposed by domain and collocated with targets
    • Large blocks of inline data (e.g., test fixtures, constants or templates) must be moved to external files and inlined at compile-time or loaded at run-time.
  • Environment access (env::set_var and env::remove_var) are always unsafe in Rust 2024 and MUST be marked as such

    • For testing of functionality depending upon environment variables, dependency injection and the mockable crate are the preferred option.
    • If mockable cannot be used, env mutations in tests ...

Files:

  • crates/comenqd/src/worker.rs
⏰ Context from checks skipped due to timeout of 120000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build-test
🔇 Additional comments (1)
crates/comenqd/src/worker.rs (1)

122-122: Make wait_or_shutdown crate-visible if it is not intended for external callers.

File: crates/comenqd/src/worker.rs

Run to verify external usages:

# From repository root (tracked files)
git grep -n --no-color 'wait_or_shutdown' | rg -v '^crates/comenqd/' || true

# Fallback (search all files then exclude the crate)
rg -n --hidden --no-ignore -S '\bwait_or_shutdown\b' -C2 | rg -v '^crates/comenqd/' || true

Apply:

-    pub async fn wait_or_shutdown(secs: u64, shutdown: &mut watch::Receiver<()>) {
+    pub(crate) async fn wait_or_shutdown(secs: u64, shutdown: &mut watch::Receiver<()>) {

Comment thread crates/comenqd/src/worker.rs
@leynos
Copy link
Copy Markdown
Owner Author

leynos commented Sep 11, 2025

@coderabbitai please create new GitHub issues for the following:

crates/comenqd/src/worker.rs (3)

122-127: Prioritise shutdown when both events are ready; bias the select and reorder arms.

Ensure immediate responsiveness to shutdown by preferring the shutdown branch when both futures are ready in the same tick.

Apply:

-        tokio::select! {
-            _ = tokio::time::sleep(Duration::from_secs(secs)) => {},
-            _ = shutdown.changed() => {},
-        }
+        tokio::select! {
+            biased;
+            _ = shutdown.changed() => {},
+            _ = tokio::time::sleep(Duration::from_secs(secs)) => {},
+        }

122-127: Take Duration instead of seconds to improve call-site clarity and prevent unit mistakes.

Accept Duration directly and remove implicit unit conversion. Update call sites accordingly.

Apply in this block:

-    pub async fn wait_or_shutdown(secs: u64, shutdown: &mut watch::Receiver<()>) {
+    pub async fn wait_or_shutdown(duration: Duration, shutdown: &mut watch::Receiver<()>) {
         tokio::select! {
-            biased;
-            _ = shutdown.changed() => {},
-            _ = tokio::time::sleep(Duration::from_secs(secs)) => {},
+            biased;
+            _ = shutdown.changed() => {},
+            _ = tokio::time::sleep(duration) => {},
         }
     }

Also update call sites (outside this hunk):

-WorkerHooks::wait_or_shutdown(config.cooldown_period_seconds, shutdown).await;
+WorkerHooks::wait_or_shutdown(Duration::from_secs(config.cooldown_period_seconds), shutdown).await;

122-127: Add focused tests for timeout and shutdown paths using rstest.

Exercise both branches and the zero-duration edge to meet the testing guideline.

Add a new async test module:

#[cfg(test)]
mod tests {
    use super::*;
    use rstest::rstest;
    use tokio::sync::watch;

    #[tokio::test]
    async fn returns_immediately_on_zero_secs() {
        let (_tx, mut rx) = watch::channel(());
        WorkerHooks::wait_or_shutdown(Duration::from_secs(0), &mut rx).await;
    }

    #[tokio::test]
    async fn returns_on_shutdown_before_timeout() {
        let (tx, mut rx) = watch::channel(());
        let mut rx2 = tx.subscribe();
        let fut = WorkerHooks::wait_or_shutdown(Duration::from_secs(60), &mut rx2);
        tx.send(()).expect("notify");
        fut.await;
    }
}

@leynos
Copy link
Copy Markdown
Owner Author

leynos commented Sep 11, 2025

@coderabbitai please create a new GitHub issue for the following:

Compiling cucumber v0.20.2
error: this lint expectation is unfulfilled
Error: --> crates/comenqd/tests/util.rs:16:14
|
16 | #[expect(dead_code, reason = "Constructed in integration tests but unused here")]
| ^^^^^^^^^
|
= note: Constructed in integration tests but unused here
= note: -D unfulfilled-lint-expectations implied by -D warnings
= help: to override -D warnings add #[allow(unfulfilled_lint_expectations)]

error: could not compile comenqd (test "util") due to 1 previous error
warning: build failed, waiting for other jobs to finish...
error: could not compile comenqd (test "retry_helper") due to 1 previous error
error: process didn't exit successfully: /home/runner/.rustup/toolchains/nightly-2025-07-22-x86_64-unknown-linux-gnu/bin/cargo test --tests --manifest-path /home/runner/work/comenq/comenq/Cargo.toml --target-dir /home/runner/work/comenq/comenq/target/llvm-cov-target --workspace (exit status: 101)
cargo llvm-cov --workspace --summary-only --lcov --output-path lcov.info failed with code 1
Error: Process completed with exit code 1.
Run actions/upload-artifact@v4

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Sep 11, 2025

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

I'll create three GitHub issues for the improvement suggestions you've outlined. Let me create them now:

@leynos I've created three separate GitHub issues for your improvement suggestions:

  1. Prioritise shutdown when both events are ready in wait_or_shutdown - Addresses the need to bias the select macro towards shutdown signals
  2. Use Duration parameter instead of seconds in wait_or_shutdown - Improves API design by using Duration type for better clarity
  3. Add focused tests for wait_or_shutdown timeout and shutdown paths - Ensures proper test coverage for both execution paths

Each issue includes detailed descriptions, the proposed solutions with code examples, file locations, and references back to this PR and comment. All issues have been assigned to you for future implementation.


🏁 Script executed:

#!/bin/bash

# Create first issue: Prioritise shutdown in select macro
gh issue create \
  --title "Prioritise shutdown when both events are ready in wait_or_shutdown" \
  --body "## Description
Ensure immediate responsiveness to shutdown by preferring the shutdown branch when both futures are ready in the same tick in the \`wait_or_shutdown\` function.

## Problem
Currently, the \`tokio::select!\` macro in \`wait_or_shutdown\` doesn't bias towards shutdown, which means if both the sleep timer and shutdown signal are ready simultaneously, the selection is arbitrary.

## Solution
Add \`biased;\` to the select macro and reorder arms to prioritise shutdown:

\`\`\`rust
tokio::select! {
    biased;
    _ = shutdown.changed() => {},
    _ = tokio::time::sleep(Duration::from_secs(secs)) => {},
}
\`\`\`

## Location
- File: \`crates/comenqd/src/worker.rs\`
- Lines: 122-127

## References
- PR: https://github.com/leynos/comenq/pull/85
- Comment: https://github.com/leynos/comenq/pull/85#discussion_r1753363840" \
  --assignee leynos

# Create second issue: Use Duration instead of seconds
gh issue create \
  --title "Use Duration parameter instead of seconds in wait_or_shutdown" \
  --body "## Description
Improve call-site clarity and prevent unit mistakes by accepting Duration directly instead of u64 seconds in the \`wait_or_shutdown\` function.

## Problem
The current API takes \`secs: u64\` which requires implicit unit conversion and is prone to unit mistakes. Using Duration is more explicit and type-safe.

## Solution
Change the function signature and update call sites:

\`\`\`rust
// Function signature
pub async fn wait_or_shutdown(duration: Duration, shutdown: &mut watch::Receiver<()>) {
    tokio::select! {
        biased;
        _ = shutdown.changed() => {},
        _ = tokio::time::sleep(duration) => {},
    }
}

// Call site update
WorkerHooks::wait_or_shutdown(Duration::from_secs(config.cooldown_period_seconds), shutdown).await;
\`\`\`

## Location
- File: \`crates/comenqd/src/worker.rs\`
- Lines: 122-127
- Additional call sites need updating

## References
- PR: https://github.com/leynos/comenq/pull/85
- Comment: https://github.com/leynos/comenq/pull/85#discussion_r1753363840" \
  --assignee leynos

# Create third issue: Add unit tests
gh issue create \
  --title "Add focused tests for wait_or_shutdown timeout and shutdown paths" \
  --body "## Description
Exercise both branches and edge cases of the \`wait_or_shutdown\` function to meet testing guidelines.

## Problem
The \`wait_or_shutdown\` function currently lacks focused unit tests that verify both the timeout and shutdown paths work correctly.

## Solution
Add a new async test module with rstest:

\`\`\`rust
#[cfg(test)]
mod tests {
    use super::*;
    use rstest::rstest;
    use tokio::sync::watch;

    #[tokio::test]
    async fn returns_immediately_on_zero_secs() {
        let (_tx, mut rx) = watch::channel(());
        WorkerHooks::wait_or_shutdown(Duration::from_secs(0), &mut rx).await;
    }

    #[tokio::test]
    async fn returns_on_shutdown_before_timeout() {
        let (tx, mut rx) = watch::channel(());
        let mut rx2 = tx.subscribe();
        let fut = WorkerHooks::wait_or_shutdown(Duration::from_secs(60), &mut rx2);
        tx.send(()).expect(\"notify\");
        fut.await;
    }
}
\`\`\`

## Location
- File: \`crates/comenqd/src/worker.rs\`
- Lines: 122-127

## References
- PR: https://github.com/leynos/comenq/pull/85
- Comment: https://github.com/leynos/comenq/pull/85#discussion_r1753363840" \
  --assignee leynos

echo "All three issues have been created successfully."

Length of output: 177


@leynos Perfect! I've successfully created three GitHub issues for your improvement suggestions:

  1. Issue Prioritise shutdown when both events are ready in wait_or_shutdown #87: Prioritise shutdown when both events are ready in wait_or_shutdown
  2. Issue Use Duration parameter instead of seconds in wait_or_shutdown #88: Use Duration parameter instead of seconds in wait_or_shutdown
  3. Issue Add focused tests for wait_or_shutdown timeout and shutdown paths #89: Add focused tests for wait_or_shutdown timeout and shutdown paths

Each issue contains detailed descriptions, the specific problems they address, proposed solutions with code examples, file locations, and references back to this PR. All issues have been assigned to you for future implementation.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Sep 11, 2025

Tip

For best results, initiate chat on the files or code changes.

crates/comenqd/tests/util.rs:16:14
|
16 | #[expect(dead_code, reason = "Constructed in integration tests but unused here")]
| ^^^^^^^^^
|
= note: Constructed in integration tests but unused here
= note: `-D unfulfilled-lint-expectations` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(unfulfilled_lint_expectations)]`
```

Impact

This is causing compilation failures in the test suite and preventing CI from completing successfully.

Suggested Solution

Either:

  1. Remove the `#[expect(dead_code)]` attribute if the code is now being used
  2. Replace it with `#[allow(dead_code)]` if the code should remain unused
  3. Add `#[allow(unfulfilled_lint_expectations)]` as suggested by the compiler

Context

@leynos leynos merged commit 6264dfd into main Sep 11, 2025
2 of 3 checks passed
@leynos leynos deleted the codex/add-doc-comment-and-example-to-worker.rs branch September 11, 2025 11:16
@leynos
Copy link
Copy Markdown
Owner Author

leynos commented Sep 11, 2025

@coderabbitai please create a new GitHub issue for the following compilation error:

   Compiling cucumber v0.20.2
error: this lint expectation is unfulfilled
Error:   --> crates/comenqd/tests/util.rs:16:14
   |
16 |     #[expect(dead_code, reason = "Constructed in integration tests but unused here")]
   |              ^^^^^^^^^
   |
   = note: Constructed in integration tests but unused here
   = note: `-D unfulfilled-lint-expectations` implied by `-D warnings`
   = help: to override `-D warnings` add `#[allow(unfulfilled_lint_expectations)]`

error: could not compile `comenqd` (test "util") due to 1 previous error
warning: build failed, waiting for other jobs to finish...
error: could not compile `comenqd` (test "retry_helper") due to 1 previous error
error: process didn't exit successfully: `/home/runner/.rustup/toolchains/nightly-2025-07-22-x86_64-unknown-linux-gnu/bin/cargo test --tests --manifest-path /home/runner/work/comenq/comenq/Cargo.toml --target-dir /home/runner/work/comenq/comenq/target/llvm-cov-target --workspace` (exit status: 101)
cargo llvm-cov --workspace --summary-only --lcov --output-path lcov.info failed with code 1
Error: Process completed with exit code 1.
Run actions/upload-artifact@v4

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Sep 11, 2025

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

@leynos I've created a GitHub issue to track the compilation error that's blocking your CI pipeline. The issue documents the unfulfilled lint expectation in crates/comenqd/tests/util.rs and includes the suggested solutions from the compiler.

This is a critical blocker that needs to be resolved before the PR can be merged successfully.


🏁 Script executed:

#!/bin/bash

# Create GitHub issue for the compilation error
gh issue create \
  --title "Fix unfulfilled lint expectation in crates/comenqd/tests/util.rs" \
  --body "## Description

CI compilation is failing due to an unfulfilled lint expectation in the test utilities file.

## Error Details

\`\`\`
error: this lint expectation is unfulfilled
Error:   --> crates/comenqd/tests/util.rs:16:14
   |
16 |     #[expect(dead_code, reason = \"Constructed in integration tests but unused here\")]
   |              ^^^^^^^^^
   |
   = note: Constructed in integration tests but unused here
   = note: \`-D unfulfilled-lint-expectations\` implied by \`-D warnings\`
   = help: to override \`-D warnings\` add \`#[allow(unfulfilled_lint_expectations)]\`
\`\`\`

## Impact

This error is preventing:
- Successful compilation of the test suite
- CI pipeline completion
- PR merge capability

## Suggested Solutions

The compiler suggests three possible fixes:

1. **Remove the \`#[expect(dead_code)]\` attribute** if the code is now being used
2. **Replace with \`#[allow(dead_code)]\`** if the code should remain potentially unused
3. **Add \`#[allow(unfulfilled_lint_expectations)]\`** to override the strict warning

## Location

- **File**: \`crates/comenqd/tests/util.rs\`
- **Line**: 16

## References

- **PR**: https://github.com/leynos/comenq/pull/85
- **Reported by**: @leynos" \
  --assignee leynos

Length of output: 42


@leynos Perfect! I've successfully created Issue #91: Fix unfulfilled lint expectation in crates/comenqd/tests/util.rs

The issue documents the CI compilation failure and includes:

  • Complete error details and location
  • Impact on the CI pipeline
  • Three suggested solutions from the compiler
  • References back to this PR

This should help track and resolve the critical blocker preventing your PR from passing CI tests.

   /|   /|  
  ( :v:  )
   |(_)|

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant