Skip to content

23 · Concurrency

Limiting concurrent work

`parallel(limit: 2) [for id in ids => await load_profile(id)]` processes an array with at most two active jobs and returns results in source order.

On this page

parallel(limit: 2) [for id in ids => await load_profile(id)] processes an array with at most two active jobs and returns results in source order. The example counts active jobs so the bound is observable, then verifies an empty input and a source snapshot.

Limiting concurrent work.

18-bounded-parallel.zolo
Playground
var active = 0
var peak = 0
async fn load_profile(id: int) -> int {
    active += 1
    if active > peak { peak = active }
    defer { active -= 1 }
    sleep 2ms
    return id * 10
}
let profiles = parallel(limit: 2) [for id in [1, 2, 3, 4] => await load_profile(id)]
assert_eq(peak, 2)
assert_eq(active, 0)
assert_eq(profiles.len(), 4)
assert_eq(profiles[0], 10)
assert_eq(profiles[3], 40)
print(peak)
print(profiles[0])
print(profiles[3])
let no_ids: [int] = []
let empty = parallel(limit: 4) [for id in no_ids => id]
assert_eq(empty.len(), 0)

// The pool snapshots source items before evaluating any mapper.

let mut ids = [1, 2, 3]
let original = parallel(limit: 1) [for id in ids => { ids[1] = 99; id }]
assert_eq(original[1], 2)
assert_eq(ids[1], 99)

The positive integer limit and source are evaluated once, in that order. A fixed worker pool claims the next job after completing the current one; it does not spawn a task per input. The source snapshot protects pending items from later mutations. Failure cancels siblings and drains cleanup before propagating the error. This is cooperative concurrency; CPU-only jobs do not gain OS threads. Available on VM, native and LLVM; wasm-aot reports the scheduler limitation.

Global index

Find your way through Zolo

Try an idea

Start here

9 results

9 results

enespt-br