Skip to content

docs: workers howto for jitter and middleware chain#77

Merged
ankurs merged 20 commits intomainfrom
docs/workers-middleware-jitter
Apr 24, 2026
Merged

docs: workers howto for jitter and middleware chain#77
ankurs merged 20 commits intomainfrom
docs/workers-middleware-jitter

Conversation

@ankurs
Copy link
Copy Markdown
Member

@ankurs ankurs commented Apr 23, 2026

Summary

  • Add Jitter section: WithJitter(percent), WithDefaultJitter(percent), WithInitialDelay, formula
  • Add Middleware section: CycleHandler, CycleFunc, Middleware types, worker-level and run-level APIs, writing custom middleware
  • Add Built-in Middleware section: Recover, Tracing, Duration, DistributedLock, Timeout, Slog, LogContext, DefaultInterceptors
  • Update all code examples for new API (NewWorker(name).HandlerFunc(fn), info.Name(), etc.)
  • Update WorkerContextWorkerInfo with private fields + getters
  • Update Packages.md description to mention middleware and jitter
  • Add Playwright content test verifying WithJitter, Middleware, CycleHandler, CycleFunc, DistributedLock

Depends on go-coldbrew/workers#5

Test plan

  • npx playwright test passes with local Jekyll server
  • Workers howto page renders all code blocks and tables

Summary by CodeRabbit

  • Documentation
    • Expanded worker docs: composable middleware (recover, tracing, distributed locking, timing, per-cycle timeouts, structured logging), jitter for periodic desynchronization, revised handler/worker model with updated examples, middleware configuration and ordering, graceful shutdown/termination semantics, logging and metrics guidance, testing tips, best practices, and updated integration notes.
  • Tests
    • Added end-to-end test coverage for the worker documentation page.

Add Jitter, Middleware, and Built-in Middleware sections.
Update all code examples for new API:
  NewWorker(name).HandlerFunc(fn), info.Name(), info.Attempt()
Update WorkerContext → WorkerInfo with private fields + getters.
Add Playwright content test for middleware/jitter keywords.
Update Packages.md description.

Ref: go-coldbrew/workers#5
Copilot AI review requested due to automatic review settings April 23, 2026 07:41
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 23, 2026

Warning

Rate limit exceeded

@ankurs has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 8 minutes and 22 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 8 minutes and 22 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8487ca0e-fbce-44a2-8fb3-cca538b961f9

📥 Commits

Reviewing files that changed from the base of the PR and between 5d571ea and b6b9f3c.

📒 Files selected for processing (2)
  • Packages.md
  • howto/workers.md
📝 Walkthrough

Walkthrough

Documentation replaces the WorkerContext-based handler model with cycle handlers taking context.Context and *WorkerInfo, introduces a middleware/interceptor architecture with built-in middleware and jitter/initial-delay options for periodic workers, updates logging/metrics guidance, and adds an E2E test for the workers how‑to page.

Changes

Cohort / File(s) Summary
Packages doc
Packages.md
Removed explicit WorkerContext mention; expanded Workers feature list to describe composable middleware (recover, tracing, distributed locking, timing, per-cycle timeout, structured logging) and jitter for periodic-worker desynchronization.
How-to / Workers guide
howto/workers.md
Large rewrite: switches handler API to context.Context + *WorkerInfo; introduces cycle handler/middleware types (CycleHandler, CycleFunc, Middleware), interceptor ordering (WithInterceptors vs AddInterceptors), ErrDoNotRestart, jitter/initial-delay options (per-worker and run-level), built-in middleware (Recover, Tracing, Duration, DistributedLock, Timeout, Slog/LogContext), Locker concept, channel/batch helper updates, handler.Close() shutdown hook, updated logging and Prometheus metric semantics, expanded examples and testing guidance.
Tests
tests/content.spec.ts
Adds Playwright E2E test for /howto/workers/ asserting presence of code blocks and keywords like WithJitter, Middleware, CycleHandler, CycleFunc, DistributedLock.

Sequence Diagram(s)

sequenceDiagram
  participant Supervisor
  participant Runner
  participant MiddlewareChain
  participant Handler
  participant LockService
  participant Metrics
  Supervisor->>Runner: start worker
  Runner->>MiddlewareChain: invoke cycle (context, *WorkerInfo)
  MiddlewareChain->>LockService: acquire distributed lock (optional)
  MiddlewareChain->>Handler: call CycleHandler
  Handler-->>MiddlewareChain: return result / ErrDoNotRestart
  MiddlewareChain->>Metrics: record attempt duration
  Runner->>Supervisor: report status / decide restart
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 I hopped through docs with a curious twitch,

Context in paw and WorkerInfo stitched,
Middleware carrots strung in a row,
Jittered hops make the run cycles slow,
I nibble the change — hop, commit, and switch!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically summarizes the main changes: documentation updates for jitter and middleware chain features in the workers howto guide.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/workers-middleware-jitter

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Updates the Workers documentation to reflect the new go-coldbrew/workers API (middleware/interceptor chain, jitter, and WorkerInfo), and adds a Playwright content regression test to ensure the updated page renders key new concepts.

Changes:

  • Expanded howto/workers.md with new sections for jitter, middleware types/APIs, and built-in middleware; updated examples to the new handler/WorkerInfo API.
  • Updated Packages.md Workers entry to mention middleware and jitter support.
  • Added a Playwright content test asserting the Workers howto renders key middleware/jitter terms and code blocks.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
tests/content.spec.ts Adds a content regression test for the Workers howto page.
howto/workers.md Major docs rewrite: new jitter + middleware sections and updated examples/types.
Packages.md Updates Workers package description to include middleware + jitter.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread howto/workers.md Outdated
Comment thread howto/workers.md
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread howto/workers.md Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 7 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread howto/workers.md
Comment thread howto/workers.md Outdated
Comment thread howto/workers.md Outdated
Comment thread howto/workers.md Outdated
Comment thread howto/workers.md Outdated
Comment thread howto/workers.md Outdated
Comment thread howto/workers.md
Copy link
Copy Markdown

@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: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@howto/workers.md`:
- Around line 378-383: The fenced code block closing fence is glued to the
trailing "))" in the workers examples, e.g. the snippet using
workers.NewWorker("metrics-reporter").HandlerFunc(workers.EveryInterval(...
func(ctx context.Context, info *workers.WorkerInfo) error { return
reportMetrics(ctx) }, )), so move the closing triple-backticks onto its own line
after the closing parenthesis; apply the same fix to the other four occurrences
with the same pattern (the code blocks that end with EveryInterval/HandlerFunc
and reportMetrics-like handlers) so each block ends with the final "),\n))\n```"
sequence (closing fence on a separate line).
- Around line 147-150: The fenced pseudocode block containing the lines "spread 
= base × percent ÷ 100" and "jittered = base − spread + rand(2 × spread)" is
missing a language tag; update that code fence to include a language (use "text"
or "pseudo") so markdownlint MD040 is satisfied (e.g., change the opening ``` to
```text).
🪄 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: 4e54aa08-356f-4665-835f-27fa5f9eb5a2

📥 Commits

Reviewing files that changed from the base of the PR and between 25a6ea2 and bf3e52d.

📒 Files selected for processing (3)
  • Packages.md
  • howto/workers.md
  • tests/content.spec.ts

Comment thread howto/workers.md Outdated
Comment thread howto/workers.md Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread howto/workers.md Outdated
Comment thread howto/workers.md Outdated
Comment thread howto/workers.md Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread howto/workers.md Outdated
Comment thread howto/workers.md Outdated
Comment thread howto/workers.md Outdated
Copy link
Copy Markdown

@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

♻️ Duplicate comments (1)
howto/workers.md (1)

147-150: ⚠️ Potential issue | 🟡 Minor

Add a language to this fenced code block (MD040).

The formula block is still missing a fence language, which keeps markdownlint warning active.

Suggested fix
-```
+```text
 spread   = base × percent ÷ 100
 jittered = base − spread + rand(2 × spread)
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against the current code and only fix it if needed.

In @howto/workers.md around lines 147 - 150, The fenced code block containing
the formulas "spread = base × percent ÷ 100" and "jittered = base − spread +
rand(2 × spread)" is missing a fence language which triggers markdownlint MD040;
update the fence to include a language token (for example text) so the block
becomes text ... to silence MD040 while preserving the formula content.


</details>

</blockquote></details>

</blockquote></details>

<details>
<summary>🤖 Prompt for all review comments with AI agents</summary>

Verify each finding against the current code and only fix it if needed.

Inline comments:
In @howto/workers.md:

  • Line 152: Update the text in howto/workers.md where the interval description
    reads "1ms" to use a space between number and unit ("1 ms") for consistent unit
    formatting; locate the sentence containing "The effective interval is clamped to
    a minimum of 1ms (never zero or negative)." and change "1ms" to "1 ms".

Duplicate comments:
In @howto/workers.md:

  • Around line 147-150: The fenced code block containing the formulas "spread =
    base × percent ÷ 100" and "jittered = base − spread + rand(2 × spread)" is
    missing a fence language which triggers markdownlint MD040; update the fence to
    include a language token (for example text) so the block becomes ```text ...
🪄 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: 593a2a4e-9659-4e1e-af16-6acf306fc909

📥 Commits

Reviewing files that changed from the base of the PR and between bf3e52d and 13c5677.

📒 Files selected for processing (1)
  • howto/workers.md

Comment thread howto/workers.md
ankurs added 3 commits April 24, 2026 12:19
- Add "Why Workers" section with plain goroutines comparison + distributed locking
- Add "Handler Return Values" section documenting return nil/error/ErrDoNotRestart behavior
- Add "Graceful Shutdown" section
- Add "Testing" section with NewWorkerInfo, WithTestChildren, RunWorker patterns
- Add "Best Practices" section
- Fix Builder Methods table: add WithMetrics, fix parameter types, fix Slog description
- Fix log import ambiguity in examples
- Fix RunWorker docs (discards error)
- Clarify two logging layers (supervisor slog vs middleware Slog)
- Label ColdBrew Integration as planned
@ankurs ankurs requested a review from Copilot April 24, 2026 05:12
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread howto/workers.md Outdated
Comment on lines +127 to +130
| `return nil` | Worker stops permanently (even with restart enabled) |
| `return error` | Worker restarts with backoff (if restart enabled) |
| `return ctx.Err()` | Clean shutdown — context was cancelled |
| `return workers.ErrDoNotRestart` | Explicit permanent stop (e.g., channel closed, work exhausted) |
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

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

The “Handler Return Values” table says return nil stops the worker permanently, but a few lines later the doc says periodic workers (with Every) should return nil for success and continue to the next tick. This is internally inconsistent and will confuse readers. Consider updating the table to distinguish long-running vs periodic behavior (or clarify that nil means “cycle succeeded” for periodic workers but “stop” for non-periodic workers).

Suggested change
| `return nil` | Worker stops permanently (even with restart enabled) |
| `return error` | Worker restarts with backoff (if restart enabled) |
| `return ctx.Err()` | Clean shutdown — context was cancelled |
| `return workers.ErrDoNotRestart` | Explicit permanent stop (e.g., channel closed, work exhausted) |
| `return nil` | **Long-running workers**: stop permanently if the handler returns. **Periodic workers** (with `Every`): mark the cycle successful and wait for the next tick. |
| `return error` | Treat the run/cycle as failed and restart with backoff (if restart enabled). |
| `return ctx.Err()` | Clean shutdown — the worker context was cancelled. |
| `return workers.ErrDoNotRestart` | Explicit permanent stop (e.g., channel closed, work exhausted). |

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Fixed — table now distinguishes long-running vs periodic workers for return nil behavior.

Copy link
Copy Markdown

@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.

♻️ Duplicate comments (1)
howto/workers.md (1)

201-201: ⚠️ Potential issue | 🟡 Minor

Use 1 ms (with a space) for unit formatting consistency.

Line 201 still says 1ms; please change it to 1 ms to match standard technical writing style used elsewhere.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@howto/workers.md` at line 201, Update the unit formatting in the sentence
currently reading "The effective interval is clamped to a minimum of 1ms (never
zero or negative)." to use a space between the number and unit so it reads "The
effective interval is clamped to a minimum of 1 ms (never zero or negative).",
ensuring consistency with other instances of "ms" formatting in the document.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@howto/workers.md`:
- Line 201: Update the unit formatting in the sentence currently reading "The
effective interval is clamped to a minimum of 1ms (never zero or negative)." to
use a space between the number and unit so it reads "The effective interval is
clamped to a minimum of 1 ms (never zero or negative).", ensuring consistency
with other instances of "ms" formatting in the document.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: efbd79c0-bc7f-4762-acf8-70d090da4554

📥 Commits

Reviewing files that changed from the base of the PR and between 13c5677 and 1f7eea6.

📒 Files selected for processing (1)
  • howto/workers.md

Copy link
Copy Markdown

@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.

♻️ Duplicate comments (1)
howto/workers.md (1)

201-201: ⚠️ Potential issue | 🟡 Minor

Use 1 ms instead of 1ms for unit formatting consistency.

LanguageTool flags this as a spelling/orthography issue. Standard technical writing style uses a space between number and unit.

-The effective interval is clamped to a minimum of 1ms (never zero or negative). Each tick recomputes independently — successive intervals differ.
+The effective interval is clamped to a minimum of 1 ms (never zero or negative). Each tick recomputes independently — successive intervals differ.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@howto/workers.md` at line 201, Replace the unit formatting "1ms" with "1 ms"
in the sentence inside howto/workers.md (the sentence: "The effective interval
is clamped to a minimum of 1ms (never zero or negative). Each tick recomputes
independently — successive intervals differ."); update it so the number and unit
are separated by a space ("1 ms") to match standard technical style.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@howto/workers.md`:
- Line 201: Replace the unit formatting "1ms" with "1 ms" in the sentence inside
howto/workers.md (the sentence: "The effective interval is clamped to a minimum
of 1ms (never zero or negative). Each tick recomputes independently — successive
intervals differ."); update it so the number and unit are separated by a space
("1 ms") to match standard technical style.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f3a112e6-d430-49c6-a721-e910b1449a41

📥 Commits

Reviewing files that changed from the base of the PR and between 1f7eea6 and 5d571ea.

📒 Files selected for processing (1)
  • howto/workers.md

- Fix WithBackoffJitter type (interface, not function)
- Add go-coldbrew/log import comments to disambiguate examples
- Fix Slog section to say "log lines" (plural) with LogContext pairing
- Move ErrDoNotRestart section to after Handler Return Values
- Remove misleading errors.Is example (Run doesn't propagate ErrDoNotRestart)
- Remove redundant WithRestart(true) in per-tenant example
- Fix log.Fatal → slog.Error in Prometheus example
- Update overview diagram to show middleware → handler
- Add complete CycleHandler struct example with Close()
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread howto/workers.md
Comment thread Packages.md Outdated
ankurs added 4 commits April 24, 2026 21:48
1. batchProcessor one-liner uses NewBatchProcessor constructor
2. "Before" goroutine example shows ctx creation
3. EveryInterval section: builder form first, manual form second
4. EveryInterval manual form uses named function (not inline)
5. Per-worker metrics example uses named handler not undefined fn
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread tests/content.spec.ts
Comment thread tests/content.spec.ts
Comment thread howto/workers.md
@ankurs ankurs merged commit 7269c8d into main Apr 24, 2026
7 checks passed
@ankurs ankurs deleted the docs/workers-middleware-jitter branch April 24, 2026 14:23
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.

2 participants