1# purescript-yoga-om-workerbees
3Multi-threaded computation for the Om effect monad using Node.js worker threads.
5This library provides a clean, type-safe interface for running CPU-bound computations across multiple worker threads, with support for shared memory primitives and atomic operations.
9- **Worker Pool Management**: Create and manage pools of worker threads
10- **Shared Memory Primitives**:
11 - `SharedInt`: Atomic Int32 reference with compare-and-swap
12 - `SharedState`: JSON-serialized state with spinlock synchronization
13 - `SharedMap`: Concurrent hash map with striped locks
14- **Type-Safe**: Full PureScript type safety for worker communication
15- **Om Integration**: Seamless integration with the Om effect monad
16- **Automatic Work Distribution**: Distribute tasks across available workers
21spago install yoga-om-workerbees
25- `purescript-yoga-om` - The Om effect monad
26- `purescript-node-workerbees` - Low-level worker thread bindings
27- `purescript-yoga-json` - JSON serialization
31### 1. Create a Worker Module
37import Node.WorkerBees as WB
39-- Worker function: Int -> Int
40fibWorker :: Int -> Int
43 | otherwise = fibWorker (n - 1) + fibWorker (n - 2)
45-- Export as worker main
47main = WB.makeAsMain fibWorker
50### 2. Bundle the Worker
55 --outfile dist/workers/MyWorker.js \
59### 3. Use the Worker Pool
65import Effect.Aff (launchAff_)
66import Yoga.Om.WorkerBees (makePool, distributeWork, terminatePool)
72 { workerPath: "./dist/workers/MyWorker.js"
77 let inputs = [35, 36, 37, 38]
78 results <- distributeWork pool inputs
86### SharedInt (Atomic Counter)
89import Yoga.Om.WorkerBees.SharedInt as SharedInt
91-- Create atomic counter
92counter <- SharedInt.new 0 # liftEffect
95SharedInt.add counter 1 # liftEffect
96SharedInt.sub counter 1 # liftEffect
97value <- SharedInt.read counter # liftEffect
100success <- SharedInt.compareAndSwap counter 0 42 # liftEffect
103SharedInt.modify counter (_ + 1) # liftEffect
106### SharedState (JSON State)
109import Yoga.Om.WorkerBees.SharedState as SharedState
111type AppState = { counter :: Int, message :: String }
113-- Create shared state (1KB buffer)
114state <- SharedState.new 1024 { counter: 0, message: "Hello" } # liftEffect
117current <- SharedState.read state # liftEffect
118SharedState.write state { counter: 1, message: "Updated" } # liftEffect
121SharedState.modify state (\s -> s { counter = s.counter + 1 }) # liftEffect
124### SharedMap (Concurrent Hash Map)
127import Yoga.Om.WorkerBees.SharedMap as SharedMap
129-- Create map (16 stripes, 4KB per entry)
130map <- SharedMap.new 16 4096 # liftEffect
132-- Insert/lookup/delete
133SharedMap.insert map "key" { value: 42 } # liftEffect
134maybeValue <- SharedMap.lookup map "key" # liftEffect
135SharedMap.delete map "key" # liftEffect
138SharedMap.modify map "key" (\v -> v { value = v.value + 1 }) # liftEffect
143Run the console examples:
146# Install dependencies
149# Fibonacci calculation with worker pool
150bun run example:fibonacci
152# Shared atomic counter
153bun run example:counter
162See the `examples/` directory for full source code.
164## When to Use WorkerBees
166**Use WorkerBees for:**
167- CPU-bound computations (cryptography, image processing, parsing)
168- Parallel processing of large datasets
169- Tasks that would block the event loop
171**Don't use WorkerBees for:**
172- I/O operations (use `Aff` instead - Node.js already handles I/O concurrency)
173- Simple computations (overhead of worker communication isn't worth it)
174- Shared state when Aff + `Ref` would suffice
178- **WorkerPool**: Manages a pool of worker threads
179- **Sendable**: Type-safe serialization for worker communication
180- **SharedArrayBuffer**: Native shared memory between threads
181- **Atomics**: Low-level atomic operations (load, store, compareExchange)
182- **SharedInt/SharedState/SharedMap**: High-level shared memory abstractions
1861. **Pool Size**: Default is 4 workers. Adjust based on CPU cores and workload:
188 makePool { workerPath, poolSize: 8 }
1912. **Batch Work**: Distribute many small tasks rather than few large ones for better load balancing
1933. **Shared Memory**: Use `makePoolWithData` to share memory instead of copying data:
195 counter <- SharedInt.new 0 # liftEffect
196 pool <- makePoolWithData (SharedInt.toSendable counter) config
1994. **Worker Bundling**: Always bundle workers with `--platform node` for optimal performance
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list