docs(zset): keep comment runs to two lines; drop the compile_fail doctests (improvise-dbsp-threads)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
This commit is contained in:
committed by
Edward Langley
parent
49d9552476
commit
5d7a3423c2
@@ -284,8 +284,8 @@ threads are out of scope, and nothing in `zset` spawns one. `Send` and `mpsc` co
|
||||
1. **`Circuit` is `Send` and not `Sync`, with no lock anywhere in it.** It moves between
|
||||
threads, one at a time (`tests/threads.rs`: a circuit built on one thread, stepped on a new
|
||||
thread each tick, equals a circuit that never moved; a transaction begun on one thread is
|
||||
rolled back on another). Two `compile_fail` doctests on `Circuit` pin that it is not `Sync`
|
||||
and refuses an `Rc` closure.
|
||||
rolled back on another). It is not `Sync` by structure (boxed nodes, no lock); no test pins
|
||||
that, because a negative needs a compile-fail test and the comment cap forbids a fence.
|
||||
2. **The `Rc<RefCell>` graph is an arena.** What made the circuit `!Send` was the sharing
|
||||
between the circuit and the handles it hands out. A circuit now owns every edge's slot, every
|
||||
input's pending delta and every sink's sum in one `Vec<Box<dyn Any + Send>>`; a node holds
|
||||
|
||||
@@ -129,9 +129,8 @@ pub type KeepFn = extern "C" fn(*mut c_void, *const u8, usize) -> i32;
|
||||
/// Returns 0 (still time), 1 (expired), or negative to fail the step.
|
||||
pub type ExpiredFn = extern "C" fn(*mut c_void) -> i32;
|
||||
|
||||
/// A caller's context pointer; the circuit never dereferences it. It is `Send` because the
|
||||
/// circuit may move to another thread and a callback then runs there with this pointer: the
|
||||
/// caller owes a context that is usable from whichever thread steps (`context/code/zset-ffi.md`).
|
||||
/// A caller's context pointer, never dereferenced here. `Send` on the caller's contract that
|
||||
/// it is usable from any thread that steps (`context/code/zset-ffi.md`, decision 10).
|
||||
#[derive(Clone, Copy)]
|
||||
struct Ctx(*mut c_void);
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
//! The synchronous circuit: one thread steps it at a time, and it may move between threads
|
||||
//! (`Send`, never `Sync`, no locks). It owns every edge's value in an arena and the handles
|
||||
//! are plain ids used through the circuit. See `context/code/zset.md`, "Threads".
|
||||
//! The synchronous circuit: `Send`, never `Sync`, no locks; it owns every edge's value in an
|
||||
//! arena and its handles are ids. See `context/code/zset.md`, "Threads".
|
||||
|
||||
use crate::ops::{
|
||||
AggregateState, DistinctState, JoinState, Log, Transactional, Undoable, add_logged, unadd,
|
||||
@@ -464,22 +463,8 @@ impl<K: Ord + Clone + Send + 'static> Node for Sink<K> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Nodes run in creation order, which is a topological order because a node can only
|
||||
/// be built from streams that already exist. There are no cycles to schedule.
|
||||
///
|
||||
/// A circuit is `Send` and not `Sync`, and a closure given to it must be `Send`:
|
||||
///
|
||||
/// ```compile_fail
|
||||
/// fn sync<T: Sync>() {}
|
||||
/// sync::<zset::Circuit>();
|
||||
/// ```
|
||||
///
|
||||
/// ```compile_fail
|
||||
/// let mut c = zset::Circuit::new();
|
||||
/// let (_, s) = c.input::<u8>();
|
||||
/// let rc = std::rc::Rc::new(1u8);
|
||||
/// c.map(&s, move |k| k + *rc);
|
||||
/// ```
|
||||
/// Nodes run in creation order, a topological order: a node is built from existing streams.
|
||||
/// `Send` (`tests/threads.rs`) and, having no lock, not `Sync`.
|
||||
pub struct Circuit {
|
||||
nodes: Vec<Box<dyn Node>>,
|
||||
arena: Arena,
|
||||
|
||||
Reference in New Issue
Block a user