QuickstartCommon Recipes

SP8D’s common recipes are your practical, copy-paste guide to integrating high-performance channels into real-world JavaScript and Node.js apps. This page provides actionable patterns for browser, Node.js, and AI/ML workflows, with diagrams and troubleshooting tips to help you build robust, scalable systems fast.

SP8D Recipes: Integration Patterns for JavaScript & Node.js

Unlock SP8D’s superpowers: copy-paste these patterns to integrate channels across workers, threads, AI loops, and dashboards. Each recipe below is ready to use and includes a visual or explanation to help you understand the data flow and integration points.


Pattern Selection Guide

Use CasePatternWhen to UseRecipe Link
Main thread ↔ Web Worker (browser)SPSC/SPSCOne producer, one consumer, browserBrowser Recipe
Main thread ↔ Worker (Node.js)SPSC/SPSCOne producer, one consumer, Node.jsNode.js Recipe
Multiple producers/consumersMPSC/MPMCScale out, reduce contentionMultiplexing
AI/ML model integrationAsyncOffload to model worker, async flowsAI/ML Recipe
Diagnostics & monitoringAnyDebug, monitor, tuneDiagnostics
Backpressure handlingAnyBuffer full, retry, asyncBackpressure

Quick Reference: Common Patterns

  • SPSC (Single-Producer, Single-Consumer): Fastest, simplest, use for 1:1 thread comms.
  • MPSC/MPMC (Multi-Producer/Consumer): Use for scaling, fairness, and contention reduction.
  • Async/AI/ML: Use async iteration and workers for model inference or event-driven flows.
  • Diagnostics: Always monitor stats in staging/production for best results.
  • Backpressure: Always handle buffer full/empty signals to avoid data loss or stalls.

In a Browser (Main Thread to Worker)

This pattern enables high-performance, zero-copy communication between your main thread and a Web Worker. The main thread creates the channel and buffer, transfers it to the worker, and both communicate through the shared channel.

⚠️

Requires SharedArrayBuffer support in your browser.

Diagram: Browser: main thread and worker communicate via a shared SP8D channel.

main.ts
import { createChannel } from "@sp8d/core";
 
const { channel, buffer } = createChannel({ slots: 16, slotSize: 32 });
const worker = new Worker("worker.js");
worker.postMessage(buffer, [buffer]);
channel.send(new Uint8Array([99, 100, 101]));
worker.ts
import { attachChannel } from "@sp8d/core";
 
self.onmessage = (e: MessageEvent<SharedArrayBuffer>) => {
  const channel = attachChannel(e.data);
  const msg = channel.recv();
  console.log("Worker received:", msg); // Uint8Array([99, 100, 101])
};

Node.js with worker_threads

This recipe shows how to use SP8D for fast, lock-free communication between Node.js worker threads. The main thread creates the channel and buffer, passes it to the worker, and both communicate through the shared channel.

⚠️

Requires Node.js 18+ and worker_threads.

Diagram: Node.js: main thread and worker communicate via a shared SP8D channel.

main.ts
import { createChannel } from "@sp8d/core";
import { Worker } from "worker_threads";
 
const { channel, buffer } = createChannel({ slots: 32, slotSize: 32 });
const worker = new Worker("./worker.js", { workerData: buffer });
channel.send(new Uint8Array([123]));
worker.ts
import { workerData } from "worker_threads";
import { attachChannel } from "@sp8d/core";
 
const channel = attachChannel(workerData);
const msg = channel.recv();
console.log("Worker received:", msg); // Uint8Array([123])

Multiplexing: Multiple Producers, One or Many Consumers

This pattern enables scalable, concurrent communication by using segments or multiple channels. Each producer/consumer pair can be in its own worker.

Diagram: Multiplexing: multiple producers and consumers with a segmented SP8D channel.

Each producer and consumer can operate in its own thread or worker, mapped to segments for fair sharing and reduced contention.

// In each producer thread:
channel.send(new Uint8Array([myProducerId]));
 
// In each consumer thread:
while (true) {
  const msg = channel.recv();
  if (msg) process(msg);
}

For fair sharing and less contention, map producer/consumer IDs to segments using (id % segments) when creating the channel.


Integrating with ML or AI Model Workers

This recipe demonstrates how to use SP8D for efficient, async message passing to and from ML/AI model workers. The main thread sends data to the worker, which processes it (e.g., with an ML model) and can optionally send results back.

Diagram: AI/ML integration: main thread sends data to a worker for model inference via SP8D channel.

Replace runMyMLModel with your own model inference function.

ai-worker.ts
import { attachChannel } from "@sp8d/core";
 
let channel;
self.onmessage = (e) => {
  channel = attachChannel(e.data);
};
 
async function processMessages() {
  while (true) {
    const msg = await channel.recvAsync(); // waits for a message
    const result = await runMyMLModel(msg); // user-defined
    // Optionally, send result back via another channel
  }
}
processMessages();

Using Diagnostics & Stats

Monitor health and performance in real time with SP8D diagnostics.

import { createChannel, createChannelDiagnostics } from "@sp8d/core";
 
const { channel } = createChannel({ slots: 16, slotSize: 64 });
const diagnostics = createChannelDiagnostics(channel, 100);
 
diagnostics.onUpdate((stats) => {
  console.log("SP8D Stats:", stats);
});
diagnostics.start();

Stats include: .used (msgs in flight), .throughput (msgs/sec), .consumerLag, .errors, .conflicts, .reclaimed.


Handling Backpressure (Full Buffer)

This pattern shows how to handle cases where the buffer is full and the producer must wait or retry.

// Producer waits if buffer is full
const payload = createPayload();
while (!channel.send(payload)) {
  // Buffer is full, wait a bit or drop/log as needed
  await new Promise((r) => setTimeout(r, 1));
}
⚠️

If the buffer is full, the producer must wait, retry, or drop messages as appropriate for your workload.


Common Pitfalls & Troubleshooting

⚠️
  • Buffer full, send fails: Always check the return value of send() and handle backpressure (see Backpressure).

  • Wrong concurrency mode: Use SPSC for 1:1, MPSC/MPMC for scaling. Mismatched mode can cause errors.

  • SharedArrayBuffer issues: Ensure browser/Node.js supports it and transfer buffers correctly.

  • Diagnostics not enabled: Use diagnostics in staging to catch issues early.

  • Async gotchas: Use sendAsync and recvAsync for non-blocking flows; avoid busy-wait in production.

  • Segment mapping: For fairness, map IDs to segments using id % segments.

For advanced troubleshooting, see the SP8D Troubleshooting Guide and Slot State Machine Troubleshooting.


Where to Go Next