Structured Concurrency & Zero-Copy Isolate Regions
A practical, function-by-function guide to writing high-performance, multithreaded code in Nyx with zero data races and zero garbage collection pauses.
1. Why Does This Module Exist?
🛑 The Problem in Other Languages
In Go (go func()), Python (asyncio.create_task), and JavaScript, background tasks can run forever. If a function exits, these "ghost tasks" keep consuming memory or crash when accessing deleted variables. Sending 50 MB between threads forces a slow memcpy that stalls the CPU for ~100 ms.
🛡️ The Nyx Solution
Async Nurseries guarantee that child tasks cannot outlive their parent function (zero dangling tasks). Isolate Regions transfer multi-megabyte structured memory across threads in 5 nanoseconds via an atomic pointer swap (zero copy, zero memory scanning).
2. Nursery API: Function Reference & Tutorial
To spawn concurrent tasks safely, import std.concurrency.
concurrency::open_nursery() -> *void
Creates a new scoped async nursery bound to the current lexical region.
Example:
import std.concurrency;
fn main() {
let nursery = concurrency::open_nursery();
// Tasks will be spawned inside this nursery
}
concurrency::spawn_task(nursery: *void, task_fn: fn(), arg: *void)
Spawns an asynchronous task deterministically managed by the nursery.
Example:
import std.concurrency;
import std.http;
fn fetch_price(sym: String) {
let price = http::get("https://api.market.com/quote/{sym}");
print("Price for {sym}: {price.text()}");
}
fn track_portfolio() {
let nursery = concurrency::open_nursery();
// Spawn 2 parallel tasks
concurrency::spawn_task(nursery, || fetch_price("BTC"), null);
concurrency::spawn_task(nursery, || fetch_price("ETH"), null);
}
concurrency::await_nursery(nursery: *void) -> bool
Cooperatively awaits until all child tasks finish. Automatically cleans up the nursery token.
Returns: true if all tasks completed successfully, false if any task threw an unhandled error.
Example:
import std.concurrency;
fn run_pipeline() {
let nursery = concurrency::open_nursery();
concurrency::spawn_task(nursery, || do_work_1(), null);
concurrency::spawn_task(nursery, || do_work_2(), null);
// Blocks safely until both tasks finish (guaranteed zero orphaned tasks)
let ok = concurrency::await_nursery(nursery);
if ok {
print("All tasks finished cleanly!");
}
}
3. Isolate Regions: Zero-Copy Message Passing Reference
Use Isolate Regions when you want to build large datasets and transfer them to another thread without copying a single byte.
concurrency::create_isolate(capacity: usize) -> *void
Allocates a dedicated thread-local memory arena for zero-copy transfers.
Example:
import std.concurrency;
// Allocate 20 MB isolated memory arena
let isolate = concurrency::create_isolate(20 * 1024 * 1024);
concurrency::send_isolate(ch: *void, region: *void) -> bool
Transfers single-ownership of the entire region to another thread via an $O(1)$ atomic pointer swap. Invalidates the sending thread's handle to eliminate data races.
Example:
import std.concurrency;
fn producer(ch: *void) {
let isolate = concurrency::create_isolate(10 * 1024 * 1024);
// Fill isolate with complex data structures...
// Transferred in 5 nanoseconds (0 memcpy):
concurrency::send_isolate(ch, isolate);
}
concurrency::recv_isolate(ch: *void) -> *void
Receives instant single-ownership of the transferred isolate region in the destination thread.
Example:
import std.concurrency;
fn consumer(ch: *void) {
// Instantly receives the full 10 MB arena
let isolate = concurrency::recv_isolate(ch);
// Process at raw hardware speed with 0 ms GC pause!
}
4. Complete Working Tutorial: High-Speed Financial Order Router
This complete example combines nurseries with isolate regions to ingest and match 100,000 orders across threads:
import std.concurrency;
import std.time;
struct TradeOrder {
id: u64,
symbol: String,
price: f64,
qty: u32,
}
fn main() {
let channel = concurrency::new_channel();
let nursery = concurrency::open_nursery();
// 1. Worker 1: Ingests 100,000 orders into an Isolate Region
concurrency::spawn_task(nursery, || {
let isolate = concurrency::create_isolate(8 * 1024 * 1024);
// Populate orders...
concurrency::send_isolate(channel, isolate);
print("Producer: Sent 100,000 orders via Zero-Copy swap!");
}, null);
// 2. Worker 2: Receives and processes orders
concurrency::spawn_task(nursery, || {
let isolate = concurrency::recv_isolate(channel);
print("Consumer: Received full dataset in 5 nanoseconds!");
}, null);
// 3. Guaranteed clean shutdown
concurrency::await_nursery(nursery);
print("Market matching session complete!");
}
← Previous: Memory Model & Escape Analysis | Next: Modules & Package Imports →