From 5fe9d67c10563d98dd5c40ab89bf581f9d0cb83d Mon Sep 17 00:00:00 2001 From: Devin Ivy Date: Thu, 9 Apr 2026 17:46:50 -0400 Subject: [PATCH] feat: add shared-state example using structs and mutex Demonstrates multiple workers updating a shared struct position protected by a mutex to prevent read-modify-write races. Co-Authored-By: Claude Opus 4.6 (1M context) --- examples/shared-state/main.ts | 30 ++++++++++++++++++++++++ examples/shared-state/update-position.ts | 15 ++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 examples/shared-state/main.ts create mode 100644 examples/shared-state/update-position.ts diff --git a/examples/shared-state/main.ts b/examples/shared-state/main.ts new file mode 100644 index 0000000..6625d00 --- /dev/null +++ b/examples/shared-state/main.ts @@ -0,0 +1,30 @@ +// Multiple workers updating shared struct state protected by a mutex. +// Without the mutex, the read-modify-write would race and lose updates. +// Requires Node v24+. +// +// Run: node examples/shared-state/main.ts + +import { pool, shared, int32, mutex } from '../../src/index.ts'; +import { updatePosition } from './update-position.ts'; + +const lock = mutex(); +const pos = shared({ x: int32, y: int32 }); + +const steps = 1000; + +{ + using run = pool(4); + + // 4 workers each move the position (1, 2) per step, 1000 steps each + await Promise.all([ + run(updatePosition(lock, pos, 1, 2, steps)), + run(updatePosition(lock, pos, 1, 2, steps)), + run(updatePosition(lock, pos, 1, 2, steps)), + run(updatePosition(lock, pos, 1, 2, steps)), + ]); +} + +const final = pos.load(); +console.log(`Expected: { x: ${4 * steps}, y: ${4 * steps * 2} }`); +console.log(`Actual: { x: ${final.x}, y: ${final.y} }`); +console.log(final.x === 4 * steps && final.y === 4 * steps * 2 ? 'PASS — mutex prevented races' : 'FAIL — data race!'); diff --git a/examples/shared-state/update-position.ts b/examples/shared-state/update-position.ts new file mode 100644 index 0000000..665ec92 --- /dev/null +++ b/examples/shared-state/update-position.ts @@ -0,0 +1,15 @@ +import { mo } from '../../src/index.ts'; +import type { SharedStruct, Int32, Mutex } from '../../src/index.ts'; + +type Position = SharedStruct<{ x: Int32; y: Int32 }>; + +export const updatePosition = mo( + import.meta, + async (lock: Mutex, pos: Position, dx: number, dy: number, steps: number): Promise => { + for (let i = 0; i < steps; i++) { + using guard = await lock.lock(); + const current = pos.load(); + pos.store({ x: current.x + dx, y: current.y + dy }); + } + }, +); -- 2.51.2