diff options
Diffstat (limited to 'src/compaction/mod.rs')
| -rw-r--r-- | src/compaction/mod.rs | 150 |
1 files changed, 0 insertions, 150 deletions
diff --git a/src/compaction/mod.rs b/src/compaction/mod.rs deleted file mode 100644 index 4685b86..0000000 --- a/src/compaction/mod.rs +++ /dev/null @@ -1,150 +0,0 @@ -//! Compaction: replacing the document with a snapshot in a new epoch. -//! -//! * `snapshot`: deterministic snapshot build (step 3). -//! * `records`: the replicated compaction records under `_continuum/compactions/<id>`. -//! * `coordinator`: proposal, settle period and decision on the node that was asked. -//! * `switch`: switching this node to a committed epoch (worker). -//! * `catchup`: rejoining a newer epoch from peers (late, new or failed nodes), then -//! replaying or quarantining this node's own missing changes. -//! * `quarantine`: inspecting, replaying or discarding quarantined changes. -//! * `delta`: replaying this node's changes since the base into the new epoch. -//! * `local`: per-node in-memory state (prebuilt snapshots, switch status, archive). -//! * `api`: `/admin/compaction(s)` handlers. -//! -//! The rest of the node is reached exclusively through [`Host`], so this module never -//! depends on `AppState`, peers or sync internals. - -mod api; -mod catchup; -mod coordinator; -mod delta; -mod local; -mod quarantine; -mod records; -pub(crate) mod snapshot; -mod switch; - -pub(crate) use local::Compaction; -pub(crate) use switch::run_worker; - -use std::future::Future; -use std::sync::Arc; -use std::time::Duration; - -use automerge::AutoCommit; -use axum::{ - routing::{get, post}, - Router, -}; -use tokio::sync::broadcast; - -use crate::replica::Epoch; -use crate::sync::ChangeSet; - -/// What compaction needs from the node. Implemented by `AppState`. -/// -/// Used generically (`H: Host`), never as `dyn Host`, so the generic methods are fine. -pub(crate) trait Host: Clone + Send + Sync + 'static { - /// This node's in-memory compaction state. - fn compaction(&self) -> &Compaction; - - /// This node's peer ID. - fn node_id(&self) -> String; - - /// The epoch of the local replica. - fn current_epoch(&self) -> Epoch; - - /// Lower bound and default basis for the settle period. - fn dormant_after(&self) -> Duration; - - fn is_node_ready(&self) -> impl Future<Output = bool> + Send; - - /// Known (not forgotten) peers. - fn peer_summaries(&self) -> impl Future<Output = Vec<PeerSummary>> + Send; - - /// Stops serving requests (back to `Joining`, keeping the cluster ID), as while a - /// rejoin syncs a fresh document. Returns whether the node was serving. - fn suspend(&self) -> impl Future<Output = bool> + Send; - - /// Serves requests again after [`Host::suspend`]. - fn resume(&self) -> impl Future<Output = ()> + Send; - - /// Whether the document caught up with a peer since the last reset. - fn initial_sync_done(&self) -> bool; - - /// Makes the next sync count as initial again. - fn reset_initial_sync(&self); - - /// Store paths touched by each published document change. - fn subscribe_changes(&self) -> broadcast::Receiver<Arc<ChangeSet>>; - - /// Reads the document on the blocking pool. - fn read_doc<T, F>(&self, f: F) -> impl Future<Output = T> + Send - where - F: FnOnce(&AutoCommit) -> T + Send + 'static, - T: Send + 'static; - - /// Mutable access to the document without publishing a change (e.g. forks). - fn update_doc<T, F>(&self, f: F) -> impl Future<Output = T> + Send - where - F: FnOnce(&mut AutoCommit) -> T + Send + 'static, - T: Send + 'static; - - /// One committed change (rolled back on error), published and replicated. - fn commit_doc<T, E, F>(&self, f: F) -> impl Future<Output = Result<T, E>> + Send - where - F: FnOnce(&mut AutoCommit) -> Result<T, E> + Send + 'static, - T: Send + 'static, - E: Send + 'static; - - /// Replaces the document and its epoch atomically. Under the write lock, `f` gets - /// the live document and returns the new one. Afterwards the node resets every - /// peer's sync state and publishes the change. Returns the old document. - fn switch_epoch<E, F>( - &self, - epoch: Epoch, - f: F, - ) -> impl Future<Output = Result<AutoCommit, E>> + Send - where - F: FnOnce(&mut AutoCommit) -> Result<AutoCommit, E> + Send + 'static, - E: Send + 'static; -} - -#[derive(Clone, Debug)] -pub(crate) struct PeerSummary { - pub(crate) id: String, - /// Not dormant. - pub(crate) active: bool, - /// Handshake completed. - pub(crate) established: bool, - /// The epoch the peer last advertised. - pub(crate) epoch: Option<Epoch>, -} - -/// Admin routes. Merged into the authenticated part of the node's router. -pub(crate) fn router<H: Host>() -> Router<H> { - Router::new() - .route( - "/admin/compaction", - post(api::start::<H>).delete(api::abort_current::<H>), - ) - .route("/admin/compactions", get(api::list::<H>)) - .route( - "/admin/compactions/{id}", - get(api::get::<H>).delete(api::abort::<H>), - ) - .route("/admin/epochs", get(api::epochs::<H>)) - .route("/admin/quarantine", get(quarantine::list::<H>)) - .route( - "/admin/quarantine/{id}", - get(quarantine::get::<H>).delete(quarantine::discard::<H>), - ) - .route( - "/admin/quarantine/{id}/document", - get(quarantine::document::<H>), - ) - .route( - "/admin/quarantine/{id}/replay", - post(quarantine::replay::<H>), - ) -} |
