Files
hakorune/docs/reference/concurrency/semantics.md

56 lines
3.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## Concurrency Semantics (docs-only; to guide MVP)
Status: reference for userland Phase0. No runtime changes during the featurepause.
### Blocking & Non-Blocking
- `send(v)` blocks when the buffer is full (capacity reached). Unblocks when a receiver takes an item.
- `receive()` blocks when buffer is empty. Unblocks when a sender provides an item.
- `try_send(v) -> Bool`: returns immediately; false if full or closed.
- `try_receive() -> (Bool, Any?)`: returns immediately; false if empty and not closed.
- `receive_timeout(ms) -> (Bool, Any?)`: returns false on timeout.
Implementation note (Phase0): no busy loop. Use cooperative queues; later replaced by OS-efficient wait.
### Close Semantics
- `close()` marks the channel closed. Further `send` is an error.
- After close, `receive` continues to drain buffered items; once empty, returns a closed indicator (shape per API, e.g., `(false, End)`).
- Double close is an error.
### Select Semantics
- `when(channel, handler)` registers selectable cases.
- `await()` examines cases:
- If one or more ready: choose one (random/roundrobin) and execute its handler atomically.
- If none ready: Phase0 may block via a multi-wait helper or return false if non-blocking policy requested.
- Fairness: no starvation requirement; Phase0 uses simple fairness; Phase2 integrates runtime help.
### Structured Concurrency
- `RoutineScopeBox` owns spawned routines.
- On `fini()`: cancel pending children, bounded join, and ensure resource release.
- Cancellation should unblock channel waits promptly.
### Types & Safety
- Phase0: runtime tag checks on `ChannelBox` send/receive are optional; document expected element type.
- Future: `TypedChannelBox<T>` with static verification; falls back to runtime tags when needed.
### Observability
- Enable `NYASH_CONC_TRACE=1` to emit JSONL events.
- Event schema (recommendation):
- Common: `ts` (ms), `op` (string), `rid` (routine id), `cid` (channel id, optional), `ok` (bool), `scope` (scope id, optional)
- spawn/start/join/cancel: `{op:"spawn", rid, ts}`, `{op:"join", rid, ok, ts}`
- send/recv: `{op:"send", cid, size, cap, ts}`, `{op:"recv", cid, size, cap, ts}`
- park/unpark: `{op:"park", rid, reason, ts}`, `{op:"unpark", rid, reason, ts}`
- select: `{op:"select", cases:n, chosen:k, ts}`
- close: `{op:"close", cid, ts}`
- Causality: producers must emit before consumers observe; timestamps monotonic per process.
### Test Plan (smokes)
- ping_pong.hako: two routines exchange N messages; assert order and count.
- bounded_pc.hako: producer/consumer with capacity=1..N; ensure no busy-wait and correct totals.
- select_two.hako: two channels; verify first-ready choice and distribution.
- close_semantics.hako: send after close -> error; drain -> End; double close -> error.
- scope_cancel.hako: RoutineScopeBox cancels children; parked receivers unblocked.
### Migration Path
- Phase0 userland boxes are kept while Phase2 runtime grows; API stable.
- Replace cooperative wait with WaiterBox (Phase1) and runtime park/unpark later.