Skip to content

Worker job queue + cancellation#100

Merged
csxark merged 1 commit into
csxark:mainfrom
Aditya8369:81
Jul 9, 2026
Merged

Worker job queue + cancellation#100
csxark merged 1 commit into
csxark:mainfrom
Aditya8369:81

Conversation

@Aditya8369

@Aditya8369 Aditya8369 commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Summary of Changes
lib/hooks/useCipherWorker.ts:

Refactored worker creation into a reusable createWorker helper function.
Automatically aborts any previous request currently running in the worker when a new request begins. It does this by terminating the worker thread (to stop CPU-heavy cipher jobs early) and rejecting the previous request's promise with a standard AbortError.
Supports a custom AbortSignal inside the options parameter.
Enforces a 10-second request timeout budget, raising a WORKER_TIMEOUT error if exceeded.
Clears timeout timers and removes AbortSignal listeners when requests complete (or fail/abort) to prevent memory leaks.
components/cipher/CipherLayout.tsx:

Manages an AbortController using a useRef to handle user input changes.
Aborts previous active calculations before launching new ones.
Ignores AbortError/DOMException in the catch block to prevent temporary error banners and ensure smooth transition between results.
Aborts calculations if the component unmounts or the user switches to a different cipher.
tests/unit/hooks/useCipherWorker.test.ts:

Created unit tests that mock the Web Worker environment.
Verified worker initialization, auto-aborting of overlapping runs, manual AbortSignal aborting, and the 10-second timeout. All new tests pass successfully.

closes #81

Summary by CodeRabbit

  • Bug Fixes
    • Improved cipher run reliability by automatically canceling outdated or overlapping computations.
    • Added better handling for canceled runs and worker failures so users see fewer stale results and fewer unexpected errors.
    • Long-running cipher jobs now stop after a timeout, helping prevent the app from hanging.
  • Tests
    • Added coverage for successful runs, canceling previous runs, manual cancellation, and timeout behavior.

@vercel

vercel Bot commented Jul 9, 2026

Copy link
Copy Markdown

@Aditya8369 is attempting to deploy a commit to the csxark's projects Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds cancellation and timeout support to cipher computations. useCipherWorker gains terminateWorkerAndRejectAll and createWorker helpers, per-request abort/timeout tracking, and a 10-second inactivity timeout. CipherLayout uses an AbortController ref to cancel stale runs on cipher change, unmount, or new runs. New unit tests cover success, auto-abort, explicit abort, and timeout paths.

Changes

Worker Cancellation and Timeout Handling

Layer / File(s) Summary
Worker hook request tracking, abort, and timeout logic
lib/hooks/useCipherWorker.ts
Adds terminateWorkerAndRejectAll and createWorker helpers, tracks signal/onAbort/timeoutId per request, clears timeouts/listeners on response, sets a 10s inactivity timeout, strips AbortSignal before serialization, and updates worker.onerror to reject all pending requests.
CipherLayout abort wiring on run and cipher change
components/cipher/CipherLayout.tsx
Introduces an abortControllerRef, aborts prior computations on cipher change/unmount/new run, passes signal into runCipher options, gates result/history updates on abort state, and silently handles AbortError.
useCipherWorker test suite for success, abort, and timeout
tests/unit/hooks/useCipherWorker.test.ts
Adds a MockWorker-based test suite validating successful resolution, auto-abort on overlapping requests, explicit AbortSignal cancellation, and 10-second inactivity timeout behavior.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CipherLayout
  participant useCipherWorker
  participant Worker

  CipherLayout->>useCipherWorker: runCipher(options, signal)
  useCipherWorker->>useCipherWorker: terminateWorkerAndRejectAll(previous requests)
  useCipherWorker->>Worker: createWorker() / postMessage(payload)
  useCipherWorker->>useCipherWorker: install abort listener + 10s timeout
  alt signal aborted
    useCipherWorker->>CipherLayout: reject(AbortError)
  else timeout elapsed
    useCipherWorker->>Worker: terminate()
    useCipherWorker->>CipherLayout: reject(WORKER_TIMEOUT)
  else worker responds
    Worker->>useCipherWorker: onmessage(result)
    useCipherWorker->>useCipherWorker: clear timeout, remove abort listener
    useCipherWorker->>CipherLayout: resolve(result)
  end
Loading

Possibly related issues

Possibly related PRs

  • csxark/CryptoViz#30: Modifies CipherLayout to trigger handleRun() automatically on input changes, overlapping with this PR's abort-cancellation logic for in-flight runs.
  • csxark/CryptoViz#38: Modifies useCipherWorker.ts onmessage handling logic, overlapping with the message-handling changes made here.

Suggested labels: ECSoC26, ECSoC26-L1

Suggested reviewers: csxark

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately reflects the main change: worker queueing and cancellation.
Linked Issues check ✅ Passed The PR implements AbortController-style cancellation so newer cipher requests supersede older ones and update the UI as intended.
Out of Scope Changes check ✅ Passed The changes stay focused on cipher worker cancellation, lifecycle cleanup, and tests; no unrelated edits are evident.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

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

🤖 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 `@lib/hooks/useCipherWorker.ts`:
- Around line 162-165: The timeout handling in useCipherWorker is using a raw
WORKER_TIMEOUT string and a plain Error, which skips the CipherError contract
and exposes an unfriendly message to CipherLayout. Update the timeout callback
to create and propagate a CipherError from errors.ts with code WORKER_TIMEOUT
and a user-facing message, and set hook error state to that message rather than
the literal code. Make sure terminateWorkerAndRejectAll and any callers continue
to receive the structured error so they can branch on code while displaying a
readable string.
🪄 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 Plus

Run ID: b7f18d57-7483-43f7-af91-864ceb611d4e

📥 Commits

Reviewing files that changed from the base of the PR and between 245e776 and 67f65bc.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (3)
  • components/cipher/CipherLayout.tsx
  • lib/hooks/useCipherWorker.ts
  • tests/unit/hooks/useCipherWorker.test.ts

Comment on lines +162 to +165
const timeoutId = setTimeout(() => {
setError('WORKER_TIMEOUT')
terminateWorkerAndRejectAll(new Error('WORKER_TIMEOUT'))
}, 10000)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Timeout rejects/sets a raw error code instead of a user-facing message, and bypasses the CipherError contract.

The hook rejects with new Error('WORKER_TIMEOUT') and sets error to the literal 'WORKER_TIMEOUT'. CipherLayout renders {error || workerError} verbatim, so users see the raw code WORKER_TIMEOUT rather than a readable message. Since errors.ts already exposes a CipherError(code, message) type carrying a WORKER_TIMEOUT code, prefer surfacing a CipherError with a friendly message so consumers can both display a sensible string and branch on code.

🛠️ Proposed change
-        const timeoutId = setTimeout(() => {
-          setError('WORKER_TIMEOUT')
-          terminateWorkerAndRejectAll(new Error('WORKER_TIMEOUT'))
-        }, 10000)
+        const timeoutId = setTimeout(() => {
+          const timeoutError = new CipherError(
+            'WORKER_TIMEOUT',
+            'The computation timed out after 10 seconds.'
+          )
+          setError(timeoutError.message)
+          terminateWorkerAndRejectAll(timeoutError)
+        }, 10000)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const timeoutId = setTimeout(() => {
setError('WORKER_TIMEOUT')
terminateWorkerAndRejectAll(new Error('WORKER_TIMEOUT'))
}, 10000)
const timeoutId = setTimeout(() => {
const timeoutError = new CipherError(
'WORKER_TIMEOUT',
'The computation timed out after 10 seconds.'
)
setError(timeoutError.message)
terminateWorkerAndRejectAll(timeoutError)
}, 10000)
🤖 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 `@lib/hooks/useCipherWorker.ts` around lines 162 - 165, The timeout handling in
useCipherWorker is using a raw WORKER_TIMEOUT string and a plain Error, which
skips the CipherError contract and exposes an unfriendly message to
CipherLayout. Update the timeout callback to create and propagate a CipherError
from errors.ts with code WORKER_TIMEOUT and a user-facing message, and set hook
error state to that message rather than the literal code. Make sure
terminateWorkerAndRejectAll and any callers continue to receive the structured
error so they can branch on code while displaying a readable string.

@csxark csxark left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Great work @Aditya8369, and thank you for your contribution! 🎉I've reviewed the changes, and everything looks good. The requested fixes have been addressed correctly, and the implementation aligns well with the requirements. This is ready to be merged. Looking forward to your future contributions!

@csxark csxark added the ECSoC26 Elite Coders Summer of Code 2026 label Jul 9, 2026
@csxark csxark merged commit fec21f5 into csxark:main Jul 9, 2026
2 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ECSoC26-L2 ECSoC26 Elite Coders Summer of Code 2026

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Worker job queue + cancellation

2 participants