Skip to content

feat(renderer): lock-free ring buffer for high-throughput SharedArrayBuffer communication#35

Merged
Asjas merged 4 commits intomainfrom
copilot/implement-lock-free-ring-buffer
Mar 23, 2026
Merged

feat(renderer): lock-free ring buffer for high-throughput SharedArrayBuffer communication#35
Asjas merged 4 commits intomainfrom
copilot/implement-lock-free-ring-buffer

Conversation

Copy link
Contributor

Copilot AI commented Mar 23, 2026

Implements SharedRingBuffer — a SPSC lock-free ring buffer over SharedArrayBuffer for streaming large payloads (e.g. chunked SSR HTML) between the main thread and Worker Threads with zero serialization overhead.

Implementation — packages/renderer/src/ring-buffer.ts

Buffer layout: 8-byte header (writePos Int32 + readPos Int32) + N-byte data ring.

Design: Monotonically increasing pointers (pointer % capacity for actual position). writePos is advanced only by the producer; readPos only by the consumer — no CAS loops required. Split writes/reads across the ring boundary are handled transparently.

// Producer (main thread)
const ring = new SharedRingBuffer(64 * 1024);
ring.write(encoder.encode(htmlChunk)); // false if full
await fastify.runTask({ sharedBuffer: ring.getSharedBuffer() });

// Consumer (worker thread) — reconstruct from transferred SAB
const ring = SharedRingBuffer.fromSharedBuffer(task.sharedBuffer);
const chunk = ring.read(4096); // null if empty

API surface: write(chunk): boolean, read(maxBytes): Uint8Array | null, fromSharedBuffer(sab) static factory, availableToRead, availableToWrite, isEmpty, isFull, capacity, byteLength, getSharedBuffer().

Atomics.notify is called on writePos after writes and on readPos after reads, keeping the API extensible for future blocking-consumer/producer patterns without breaking changes.

Docs fix — docs/worker-communication.md

The existing pseudocode example had Atomics.notify(this.readPos, 0) inside write() — wrong target; a waiting reader blocks on writePos, not readPos. Replaced the entire sketch with accurate usage examples and an API reference table.

Exports

  • SharedRingBuffer re-exported from the package root (@scratchyjs/renderer)
  • "./ring-buffer" named export added to package.json

Tests — ring-buffer.test.ts (50 tests)

Covers: constructor validation, fromSharedBuffer shared-memory semantics, write/read contract, ring-wrap (split writes and reads across boundary), fill/drain/refill cycles, introspection getters, partial reads, and a streaming HTML chunks simulation.


⚡ Quickly spin up Copilot coding agent tasks from anywhere on your macOS or Windows machine with Raycast.

@github-actions
Copy link
Contributor

github-actions bot commented Mar 23, 2026

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 98.67%
⬆️ +0.04%
2007 / 2034
🔵 Statements 98.07%
⬆️ +0.05%
2094 / 2135
🔵 Functions 99.25%
⬆️ +0.02%
399 / 402
🔵 Branches 92.61%
⬆️ +0.12%
1104 / 1192
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
packages/renderer/src/ring-buffer.ts 100% 100% 100% 100%
Generated in workflow #293 for commit 64f9485 by the Vitest Coverage Report Action

…Buffer communication

Co-authored-by: Asjas <3828967+Asjas@users.noreply.github.com>
Agent-Logs-Url: https://github.com/Asjas/scratchyjs/sessions/e50a6765-1b96-42b5-af30-49c4c1d8b529
Copilot AI changed the title [WIP] Implement lock-free ring buffer for high-throughput SharedArrayBuffer communication feat(renderer): lock-free ring buffer for high-throughput SharedArrayBuffer communication Mar 23, 2026
Copilot AI requested a review from Asjas March 23, 2026 13:14
@github-actions
Copy link
Contributor

github-actions bot commented Mar 23, 2026

📚 Docs preview deployed

https://scratchyjs-docs-pr-35.asjas.workers.dev

Updates automatically on every push to this PR.

@Asjas Asjas marked this pull request as ready for review March 23, 2026 13:50
Copilot AI review requested due to automatic review settings March 23, 2026 13:50
Copy link
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

Adds a new SharedRingBuffer primitive to @scratchyjs/renderer to support high-throughput, zero-copy streaming over SharedArrayBuffer between the main thread and Worker Threads, plus docs and exports updates.

Changes:

  • Introduces SharedRingBuffer SPSC ring buffer implementation over SharedArrayBuffer.
  • Adds a comprehensive Vitest suite for ring buffer behavior and re-export checks.
  • Updates worker communication docs and package exports to expose the new API.

Reviewed changes

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

Show a summary per file
File Description
packages/renderer/src/ring-buffer.ts New SharedRingBuffer implementation (SPSC ring buffer over SAB).
packages/renderer/src/ring-buffer.test.ts New test suite covering correctness, wrap-around, and streaming simulation.
packages/renderer/src/index.ts Re-exports SharedRingBuffer from the package root.
packages/renderer/src/index.test.ts Verifies the new root re-export.
packages/renderer/package.json Adds ./ring-buffer subpath export.
docs/worker-communication.md Replaces incorrect pseudocode with usage examples + API reference.
IMPLEMENTATION_PLAN.md Marks the ring buffer item as completed.

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: A-J Roos <asjasroos@pm.me>
@Asjas Asjas merged commit 2d3aa73 into main Mar 23, 2026
14 checks passed
@Asjas Asjas deleted the copilot/implement-lock-free-ring-buffer branch March 23, 2026 14:07
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.

3 participants