Skip to main content

ClusterControllerCtx

Trait ClusterControllerCtx 

Source
pub trait ClusterControllerCtx: Send {
    // Required methods
    fn now(&self) -> Timestamp;
    fn cluster_states<'life0, 'life1, 'async_trait>(
        &'life0 mut self,
        clusters: &'life1 [ClusterId],
    ) -> Pin<Box<dyn Future<Output = Vec<ClusterState>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn managed_cluster_ids<'life0, 'async_trait>(
        &'life0 mut self,
    ) -> Pin<Box<dyn Future<Output = Vec<ClusterId>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait;
    fn hydrated_replicas<'life0, 'life1, 'async_trait>(
        &'life0 mut self,
        cluster_id: ClusterId,
        replicas: &'life1 [ReplicaId],
    ) -> Pin<Box<dyn Future<Output = BTreeSet<ReplicaId>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn has_hydratable_objects<'life0, 'async_trait>(
        &'life0 mut self,
        cluster_id: ClusterId,
    ) -> Pin<Box<dyn Future<Output = bool> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait;
    fn refresh_window_inputs<'life0, 'async_trait>(
        &'life0 mut self,
        cluster_id: ClusterId,
    ) -> Pin<Box<dyn Future<Output = Option<RefreshWindowInputs>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait;
    fn apply<'life0, 'async_trait>(
        &'life0 mut self,
        decisions: Vec<Decision>,
    ) -> Pin<Box<dyn Future<Output = ApplyOutcome> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait;
}
Expand description

The strategy-agnostic pull/apply interface between the controller and its environment.

The controller depends on exactly this trait. Reads are batched and pulled on demand; the single write applies a tick’s batch under a compare-and-append guard. Implementations marshal these to wherever the live signals live (for v1, the Coordinator’s catalog and compute/storage controllers, reached over a channel from the controller’s own task, hence the Send bound).

Required Methods§

Source

fn now(&self) -> Timestamp

Current wall-clock time, as the controller’s strategies should see it.

Source

fn cluster_states<'life0, 'life1, 'async_trait>( &'life0 mut self, clusters: &'life1 [ClusterId], ) -> Pin<Box<dyn Future<Output = Vec<ClusterState>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

A consistent durable view of the given managed clusters and their replicas. Clusters that do not exist or are unmanaged are omitted from the result.

Source

fn managed_cluster_ids<'life0, 'async_trait>( &'life0 mut self, ) -> Pin<Box<dyn Future<Output = Vec<ClusterId>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

The ids of all managed clusters the controller owns this tick.

Source

fn hydrated_replicas<'life0, 'life1, 'async_trait>( &'life0 mut self, cluster_id: ClusterId, replicas: &'life1 [ReplicaId], ) -> Pin<Box<dyn Future<Output = BTreeSet<ReplicaId>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Of replicas on cluster, which are online and have all current (non-transient) collections on the cluster hydrated. The returned set is a subset of replicas.

Callers should request only replicas their strategy currently needs. This keeps live-signal dependencies local to the strategies that consume them.

Source

fn has_hydratable_objects<'life0, 'async_trait>( &'life0 mut self, cluster_id: ClusterId, ) -> Pin<Box<dyn Future<Output = bool> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Whether cluster_id has at least one hydratable (dataflow-backed) object bound to it: an index, materialized view, ingestion source, or sink.

A catalog-level approximation of “the hydration check has something to count”. Where the two disagree at the margin, the mismatch is self-healing: a replica with nothing to hydrate reads hydrated, and the burst winds down via its linger.

Source

fn refresh_window_inputs<'life0, 'async_trait>( &'life0 mut self, cluster_id: ClusterId, ) -> Pin<Box<dyn Future<Output = Option<RefreshWindowInputs>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

The refresh-window live signals for one scheduled cluster: the read timestamp, the compaction estimate, and the bound REFRESH MVs’ write frontiers and schedules. Returns None when the cluster is missing, unmanaged, or no longer scheduled ON REFRESH at pull time. The controller only asks about clusters it observed as scheduled, so None means a concurrent DDL moved the cluster mid-tick, and the schedule’s membership in the compare-and-append witness rejects any decision derived from the stale observation.

Pulled on demand the same way as Self::hydrated_replicas: the controller probes a cluster only when the on-refresh strategy needs the signal (i.e. the cluster is scheduled), so a steady MANUAL cluster never pays for it.

Source

fn apply<'life0, 'async_trait>( &'life0 mut self, decisions: Vec<Decision>, ) -> Pin<Box<dyn Future<Output = ApplyOutcome> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Apply a tick’s batch of decisions under their compare-and-append guards. Each decision carries the ExpectedClusterState it was derived from; the implementation re-reads every target cluster and, if any has since diverged, returns ApplyOutcome::Rejected without transacting anything. Otherwise the batch’s catalog operations are transacted together.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§