Skip to main content

somatize_core/
watcher.rs

1//! Who is told what happened. The fifth hole.
2//!
3//! The core provides it and does not fill it, like the other four: it says what
4//! a [`Fact`] is and has nowhere to put one. Where a fact ends up — a file, a
5//! bucket, a notebook drawing a curve while it is still being drawn — is the
6//! business of whoever runs, and it is injected the way a
7//! [`Keeper`](crate::Keeper) is.
8//!
9//! # Emitting is synchronous. Delivering is not the core's problem.
10//!
11//! [`saw`](Watcher::saw) is called from the walk and returns. What the
12//! implementor does with the fact — write it, drop it, push it onto a channel
13//! that another thread drains into a figure — is where anything asynchronous
14//! belongs, and it is why this needs no runtime. That matters more than it
15//! looks: an `async` here would be `async` in every caller of the engine, and
16//! that is the objection that has twice kept a bus out of this project.
17//!
18//! # Called from several threads
19//!
20//! A [`Wave`](crate::Plan::Wave) runs its branches in a `std::thread::scope`, so
21//! several of them call this at once — hence `Send + Sync`, and hence the order
22//! facts arrive in is **not** the order they happened in. Whoever writes them
23//! down decides what to do about that; the engine will not serialize a run to
24//! make a log tidy.
25//!
26//! # There is one, and fanning out is not the core's either
27//!
28//! Not a list, not a registry, no `subscribe`. If you want to write **and**
29//! draw, that is an implementor holding two, in whichever crate needs it. A hole
30//! that starts managing its own tenants stops being a hole.
31
32use crate::Fact;
33
34/// Told what happened, as it happens.
35pub trait Watcher: Send + Sync {
36    /// One fact. Whatever this does, it does not fail: there is no useful
37    /// answer to "the log could not be written" in the middle of a run, and a
38    /// `Result` here would make every emit site a decision about somebody
39    /// else's storage.
40    fn saw(&self, fact: &Fact);
41}