pub struct App { /* private fields */ }Implementations§
Source§impl App
impl App
Sourcepub async fn start(
runtime: Runtime,
store: Arc<dyn LogStore>,
config: AppConfig,
) -> Result<Arc<App>>
pub async fn start( runtime: Runtime, store: Arc<dyn LogStore>, config: AppConfig, ) -> Result<Arc<App>>
Recover from the log, then open ingress.
Recovery is not a special mode: it is the same fold the runtime always runs, started from the newest snapshot. A process that has just been SIGKILLed and one that has just been deployed take exactly this path.
Takes a prepared Runtime rather than a Placed, because building one requires choosing
a backend, and that choice belongs to whoever assembles the process — not to the sequencer.
Sourcepub fn stylesheet(&self) -> &str
pub fn stylesheet(&self) -> &str
The stylesheet /beck.css serves — this program’s classes and nothing else.
pub fn runtime(&self) -> &Runtime
pub fn store_kind(&self) -> &'static str
pub fn head(&self) -> Seq
pub fn subscribe(&self) -> Receiver<Seq>
Sourcepub fn drain(&self)
pub fn drain(&self)
Tell every subscription this process is going away.
Idempotent, and one-way: an application that has drained does not come back, because the thing that would bring it back is a new process.
Sourcepub fn draining(&self) -> Receiver<bool>
pub fn draining(&self) -> Receiver<bool>
Watch for the drain. true already means it has happened.
pub async fn state(&self) -> Value
Sourcepub async fn render(&self, actor: &(impl Viewer + ?Sized)) -> Result<Html>
pub async fn render(&self, actor: &(impl Viewer + ?Sized)) -> Result<Html>
Render a subscriber’s view of the current state, by full recompute.
Kept for the two callers that render a state nobody is subscribed to: the server-side render
of the first document, and the resumption path’s reconstruction of the view as of an old
seq. A live subscription goes through App::maintain instead.
Sourcepub fn presence(&self) -> &Arc<Registry>
pub fn presence(&self) -> &Arc<Registry>
The roster itself, for a connection that wants to join it and for a gauge that wants to read it.
Sourcepub fn awareness(&self) -> &Arc<Registry>
pub fn awareness(&self) -> &Arc<Registry>
The awareness roster, for a connection that wants to contribute to it.
Sourcepub fn view_engine(&self) -> Result<Engine>
pub fn view_engine(&self) -> Result<Engine>
An engine for one new subscription, of whichever kind this application is configured for.
With sharing on it owns only the per-session operators; the rest arrive from the one shared
dataflow. With it off it owns the whole plan, which is what every subscription did before
docs/23-incremental-views-report.md.
Sourcepub async fn maintain(
&self,
engine: &mut Engine,
actor: &(impl Viewer + ?Sized),
) -> Result<(Html, Seq)>
pub async fn maintain( &self, engine: &mut Engine, actor: &(impl Viewer + ?Sized), ) -> Result<(Html, Seq)>
Render a subscriber’s view of the current state, by maintaining it. Returns the page and the version it reflects.
The engine belongs to the subscription, so its arrangements survive between events and the
per-event work is proportional to what the event changed (§5.3). The state is cloned under
the read lock and the engine runs outside it — an Arc bump under the lock, and no
rendering while the sequencer wants to write.
The version is read under the same lock as the state, because the sequencer publishes
both under its write lock, and a page paired with a seq it does not reflect is a wrong DOM
after the client’s next reconnect: a resuming client is served the difference from the seq
its last frame carried. This used to be app.head() sampled after the render, which is a
larger number whenever an event landed in between.
Sourcepub fn identity(&self) -> &Arc<dyn Identity>
pub fn identity(&self) -> &Arc<dyn Identity>
Whether subscriptions maintain their views (§5.3) or recompute them. How this process decides who is asking.
Public because both edges — the socket and the document handler — have to ask the same
question, and because the dashboard and the startup line have to be able to say which
provider is in force. An operator who cannot tell from the logs whether authentication is
on does not have authentication (docs/48 §48.2).
Sourcepub fn clock(&self) -> &Arc<dyn Clock>
pub fn clock(&self) -> &Arc<dyn Clock>
The clock this process was configured with — F11’s supplied one, never an ambient reading.
Public for the same reason App::identity is: the HTTP edge has to answer “how long is
this credential good for” and must not reach for a second clock to do it.
pub fn maintains_views(&self) -> bool
Whether the operators that do not read the session are held once between subscribers.
The shared dataflow, for a measurement that wants to know what it holds.
Sourcepub async fn propose(
&self,
id: String,
actor: impl Into<Proposer>,
command: Value,
) -> Result<Seq, String>
pub async fn propose( &self, id: String, actor: impl Into<Proposer>, command: Value, ) -> Result<Seq, String>
Propose a command. Returns the seq its events landed at.
The reply is the ack, and it means committed — not “your view has caught up”. Phase 0 found out the hard way that those are different facts (§18.5 item 1).
Sourcepub async fn read_snapshot<T>(&self, f: impl FnOnce(&Value, Seq) -> T) -> T
pub async fn read_snapshot<T>(&self, f: impl FnOnce(&Value, Seq) -> T) -> T
Run something against a consistent snapshot of the accumulator and the version it is at.
The read lock is held for the whole of f, which is what makes it a snapshot rather than
two facts read at two times: the sequencer commits under the write lock, so nothing can move
the state — and therefore nothing can advance the shared dataflow past this version — while
this runs. crate::pgwire is the caller, and it is the one place a reader needs the two
together; a rendering subscriber takes a clone instead, because a render is O(page) and a
scan is O(rows).
Sourcepub async fn state_at(&self, seq: Seq) -> Result<Value>
pub async fn state_at(&self, seq: Seq) -> Result<Value>
The state as of seq, for a resuming subscriber.