/
nv-lang
/
nova
Обзор
Документация
Войти
/
nv-lang
/
nova
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
main
std/src/concurrency/timer.nv
119 строк
5 KB
Evgeniy Golovin
merge: comment-hygiene-2 — чистка комментариев std (batch 1-20) + линт-свип 330→13
01 авг 2026, 18:13
01 авг 2026, 18:13
bb8b33d
Код
Авторство
О чём код?
// stdlib documentation surface for ChanReader.close_after. // // The implementation is a compiler builtin (codegen lowers // `ChanReader.close_after(d)` to `nova_chan_reader_close_after_ns(d.nanos)` // in the C runtime channels.h). This file exists solely so `nova doc` can // render the API surface and so AI agents searching the stdlib find // authoritative usage examples. module concurrency.timer import std.time.duration /// Create a one-shot `ChanReader[()]` that closes after `d` elapses. /// /// The channel produces no value — `recv()` returns `Some(())` after the /// timer fires, then `None` thereafter (idempotent closed-state). /// /// Primary use: timeout arms in `select { ... }`: /// /// ```nova /// let t = ChanReader.close_after(5.to_seconds()) /// select { /// Some(v) = rx.recv() => process(v) /// None = t.recv() => log_idle() /// } /// ``` /// /// # Errors /// /// - **Negative `Duration`** → runtime panic with the offending nanosecond /// value. There is no silent zero-wait; user gets an explicit stack frame. /// /// # Edge cases /// /// - **Zero `Duration`** (`Duration.ZERO`, `0.to_nanos()`) → channel /// is already closed; first `recv()` returns `None` without yielding. /// No libuv timer is allocated (fast-path). /// - **Sub-millisecond `Duration`** (e.g. `500_000.to_nanos()`) /// is rounded **up** to 1 ms (the libuv timer granularity). It will never /// round down to a shorter wait than requested. /// /// # Performance /// /// Each call currently allocates a fresh `uv_timer_t` libuv handle /// (~120 bytes + 1 syscall). Adequate for idiomatic 10-100 concurrent /// timers. For high-throughput timer loads (10k+ short HTTP timeouts), a /// custom timer-wheel runtime is planned; until then the per-timer libuv /// cost is the dominant overhead. Bench `timer_alloc_throughput` records /// the current baseline. /// /// # Testing /// /// Mockable through the `Time` effect handler is planned (currently the /// runtime path is real-clock only). Until then, integration tests should /// use small real durations (`10.to_millis()`) and tolerate scheduler /// jitter via `>=` comparisons against `Time.now()`. /// /// # Migration from `Time.after(int)` /// /// `Time.after(int ms)` was removed. The compiler emits a structured E5101 /// diagnostic with a machine-applicable fix-it suggestion if the legacy /// form is encountered. Use the migration tool: /// /// ```bash /// cargo run --bin migrate_plan65 -- --apply /// ``` /// /// which rewrites `Time.after(N)` → `ChanReader.close_after(N.to_millis())` /// for literal arguments. Non-literal arguments (computed expressions) /// receive a `MIGRATE_MANUAL` marker for human review. /// /// # See also /// /// - [`Duration`](../time/duration.nv) — the type-safe interval input. /// - [`Channel.new`](#channel.new) — companion capability-split constructor. /// - Periodic `tick_every(Duration)` ticker + custom timer-wheel runtime /// (planned). #stable(since = "0.6") fn ChanReader_close_after_doc_marker(d Duration) -> () { // Marker function — body is unreachable; codegen lowers the real // ChanReader.close_after via compiler builtin, not via this fn. // Until ChanReader gains a true .nv decl (post-bootstrap), // this file is doc-only. ro _ = d } // ────────────────────────────────────────────────────────────────────────── // `tick_every` namespace squat (forward-declared, NOT impl) // ────────────────────────────────────────────────────────────────────────── /// `ChanReader.tick_every(d Duration) -> ChanReader[()]` — periodic /// ticker channel (placeholder). /// /// **Status: NOT IMPLEMENTED.** Implementation in **Plan 66** /// (`docs/plans/66-timer-wheel-and-tick-every.md`). /// /// The purpose of this declaration — **reserve the name** in the stdlib so that /// external crate / user code cannot define a conflicting /// `ChanReader.tick_every` before the core implementation ships. /// Also serves as a discovery signal for AI agents: "such an API is expected, /// but not available yet". /// /// Plan 66 will cover: /// - Semantics: a periodic tick every `d`, drop-on-overflow by /// default (Tokio `MissedTickBehavior::Skip`). An optional enum /// for Burst/Delay (Tokio parity). /// - Implementation: requires a custom timer-wheel runtime (current libuv /// per-handle overhead is unacceptable for 10k+ concurrent tickers). /// In Plan 65 — libuv per-timer. In Plan 66 — Tokio-style hierarchical /// bucketing. /// /// Until the Plan 66 implementation: calling this function panics with explicit /// guidance. #unstable #stable(since = "0.6") fn ChanReader_tick_every_namespace_squat(d Duration) -> () { ro _ = d panic("ChanReader.tick_every is not yet implemented — see Plan 66 (docs/plans/66-timer-wheel-and-tick-every.md). Use ChanReader.close_after for one-shot timers in Plan 65.") }