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§
Sourcefn now(&self) -> Timestamp
fn now(&self) -> Timestamp
Current wall-clock time, as the controller’s strategies should see it.
Sourcefn 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 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.
Sourcefn 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 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.
Sourcefn 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 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.
Sourcefn 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 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.
Sourcefn 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 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.
Sourcefn 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,
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".