Skip to content

🤖 fix: bound Shiki worker highlighting#3352

Open
ammar-agent wants to merge 6 commits into
mainfrom
fix/highlight-worker-budget
Open

🤖 fix: bound Shiki worker highlighting#3352
ammar-agent wants to merge 6 commits into
mainfrom
fix/highlight-worker-budget

Conversation

@ammar-agent
Copy link
Copy Markdown
Collaborator

@ammar-agent ammar-agent commented May 21, 2026

Summary

Keep syntax highlighting optimistic while preventing pathological Shiki/TextMate inputs from wedging the renderer. Highlighting still attempts human-scale diffs/code blocks, but worker calls now have bounded runtime, oversized generated/minified hunks fall back before expensive renderer-thread preprocessing, and recovery no longer leaves stale or dead workers in the queue.

Background

A live Mux instance had a shiki-highlighter worker pegging one renderer thread after it became unresponsive inside native Oniguruma matching. Because highlightCode() awaited the Comlink call without a timeout, the worker singleton stayed wedged forever and every later highlight request queued behind it.

Implementation

  • Add a 5s budget around worker highlight() calls.
  • Serialize highlight calls on the client so a queued request's timeout starts only when that payload reaches the front of the queue.
  • On timeout, terminate/recycle the worker and remember the input fingerprint so re-renders do not repeatedly kill fresh workers for the same payload.
  • Resolve the worker proxy when each queued job starts, so jobs queued behind a recycled worker use the fresh worker instead of a terminated Comlink proxy.
  • Guard worker.onerror recycling against stale workers and release the Comlink proxy before termination to avoid unhandled InvalidStateError in Bun.
  • Avoid main-thread Shiki fallback for worker runtime failures, since it uses the same matcher and could freeze the UI.
  • Replace the old 32KB diff cap with a pre-worker sync budget that allows 10k-line human-scale chunks while skipping generated/minified payloads before join/structured-clone work can stall the renderer.

Validation

  • make static-check
  • bun test src/browser/utils/highlighting/
  • make typecheck
  • CI: Codex approved; GitHub CI checks pass. Chromatic's optional UI baseline checks are pending human acceptance for the intended visual update.

Risks

Low-to-medium, limited to syntax highlighting. Pathological or generated/minified inputs now render as plain text after the sync/runtime budget is exceeded, and the fingerprint cache can conservatively skip highlighting for a rare collision, but the underlying code/diff text remains visible and copyable.

Pains

git push/git fetch to GitHub hung repeatedly in this workspace, so branch updates after the initial push were applied through the GitHub Git Database API while keeping the local branch ref synchronized to the API-created commits.


Generated with mux • Model: openai:gpt-5.5 • Thinking: xhigh • Cost: $5.98

@ammar-agent
Copy link
Copy Markdown
Collaborator Author

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2299b3276a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/browser/utils/highlighting/highlightWorkerClient.ts
Keep syntax highlighting optimistic by rendering plain text first while bounding worker highlight calls with a 5s budget. Timeout recovery now terminates and recycles the highlight worker, remembers pathological inputs to avoid repeated worker kills, and avoids main-thread Shiki fallback for worker runtime failures. Remove the 32KB diff highlight cap so human-scale files can attempt highlighting under the same worker budget.

---

_Generated with `mux` • Model: `openai:gpt-5.5` • Thinking: `xhigh` • Cost: `$5.98`_

<!-- mux-attribution: model=openai:gpt-5.5 thinking=xhigh costs=5.98 -->
@ammar-agent ammar-agent force-pushed the fix/highlight-worker-budget branch from 2299b32 to 4d2d33d Compare May 21, 2026 15:51
@ammar-agent
Copy link
Copy Markdown
Collaborator Author

@codex review

Please take another look. I addressed the queued-request timeout poisoning by serializing worker highlight calls on the client side so the timeout clock starts only when a payload reaches the front of the queue.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4d2d33d3a0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/browser/utils/highlighting/highlightWorkerClient.ts Outdated
@ammar-agent
Copy link
Copy Markdown
Collaborator Author

@codex review

Please take another look. I now resolve/revalidate the worker proxy when each queued highlight job starts, so jobs queued behind a recycled worker talk to the fresh worker instead of a terminated Comlink proxy.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 75cfcff509

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/browser/utils/highlighting/highlightWorkerClient.ts Outdated
Resolve the worker proxy when each queued highlight job starts instead of when highlightCode is first called. This keeps later queued chunks from calling into a terminated Comlink proxy after an earlier chunk times out and recycles the worker.

---

_Generated with `mux` • Model: `openai:gpt-5.5` • Thinking: `xhigh` • Cost: `$5.98`_

<!-- mux-attribution: model=openai:gpt-5.5 thinking=xhigh costs=5.98 -->
@ammar-agent ammar-agent force-pushed the fix/highlight-worker-budget branch from 75cfcff to b225f7c Compare May 21, 2026 16:23
@ammar-agent
Copy link
Copy Markdown
Collaborator Author

@codex review

Please take another look on the updated branch. The latest head preserves the queued-worker revalidation fix and keeps the local/remote branch in sync for readiness checks.

Guard worker.onerror recycling so asynchronous error events from an already-replaced highlighter worker cannot terminate the healthy current worker.

---

_Generated with `mux` • Model: `openai:gpt-5.5` • Thinking: `xhigh` • Cost: `$5.98`_

<!-- mux-attribution: model=openai:gpt-5.5 thinking=xhigh costs=5.98 -->
@ammar-agent
Copy link
Copy Markdown
Collaborator Author

@codex review

Please take another look. I added an active-worker guard so stale error events from replaced highlighter workers cannot recycle the current healthy worker.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 43084163b7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/browser/utils/highlighting/highlightWorkerClient.ts Outdated
Guard worker.onerror recycling so asynchronous error events from an already-replaced highlighter worker cannot terminate the healthy current worker.

---

_Generated with `mux` • Model: `openai:gpt-5.5` • Thinking: `xhigh` • Cost: `$5.98`_

<!-- mux-attribution: model=openai:gpt-5.5 thinking=xhigh costs=5.98 -->
@ammar-agent
Copy link
Copy Markdown
Collaborator Author

@codex review

Please take another look. The branch now includes the stale-worker guard: worker creation is captured in createdWorker, and recycleWorker(createdWorker) returns early if the errored worker is no longer active.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: cb11a6eede

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/browser/utils/highlighting/highlightDiffChunk.ts Outdated
Add a pre-worker synchronous budget that still allows human-scale 10k-line chunks, while skipping generated/minified hunks before renderer-thread join and structured-clone work can stall the UI.

---

_Generated with `mux` • Model: `openai:gpt-5.5` • Thinking: `xhigh` • Cost: `$5.98`_

<!-- mux-attribution: model=openai:gpt-5.5 thinking=xhigh costs=5.98 -->
@ammar-agent
Copy link
Copy Markdown
Collaborator Author

@codex review

Please take another look. I added a pre-worker sync budget for oversized/generated diff payloads while explicitly allowing 10k-line human-scale chunks through that budget.

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. More of your lovely PRs please.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Release the Comlink proxy before terminating a recycled highlighter worker so Bun does not later surface an unhandled InvalidStateError when Comlink tries to release an already-terminated endpoint.

---

_Generated with `mux` • Model: `openai:gpt-5.5` • Thinking: `xhigh` • Cost: `$5.98`_

<!-- mux-attribution: model=openai:gpt-5.5 thinking=xhigh costs=5.98 -->
@ammar-agent
Copy link
Copy Markdown
Collaborator Author

@codex review

Please take another look. I added a Comlink proxy release before worker termination to avoid Bun surfacing unhandled InvalidStateError after worker recycling.

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. More of your lovely PRs please.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

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.

1 participant