Skip to main content

a3s_runtime/
driver.rs

1use crate::contract::{
2    RuntimeActionRequest, RuntimeCapabilities, RuntimeExecRequest, RuntimeExecResult,
3    RuntimeInspection, RuntimeLogChunk, RuntimeLogQuery, RuntimeObservation, RuntimeRemoval,
4    RuntimeUnitSpec,
5};
6use crate::{ProviderId, RuntimeResult, RuntimeUnitRecord};
7use async_trait::async_trait;
8
9/// Provider-specific primitive used by `ManagedRuntimeClient`.
10///
11/// Drivers do not own request idempotency or durable shared state. `apply`,
12/// `stop`, and `remove` must nevertheless be safe to reattach after an
13/// ambiguous transport failure using the stable unit identity and generation.
14/// A successful `apply` must also retire every older provider generation for
15/// the unit before returning, leaving exactly one managed provider resource.
16/// If that handoff is interrupted, an exact retry must discover the partially
17/// created current generation and finish the same reconciliation.
18#[async_trait]
19pub trait RuntimeDriver: Send + Sync {
20    fn provider_id(&self) -> &ProviderId;
21
22    async fn capabilities(&self) -> RuntimeResult<RuntimeCapabilities>;
23
24    async fn apply(
25        &self,
26        spec: &RuntimeUnitSpec,
27        current: &RuntimeObservation,
28    ) -> RuntimeResult<RuntimeObservation>;
29
30    async fn inspect(&self, unit: &RuntimeUnitRecord) -> RuntimeResult<RuntimeInspection>;
31
32    async fn stop(
33        &self,
34        unit: &RuntimeUnitRecord,
35        request: &RuntimeActionRequest,
36    ) -> RuntimeResult<RuntimeObservation>;
37
38    async fn remove(
39        &self,
40        unit: &RuntimeUnitRecord,
41        request: &RuntimeActionRequest,
42    ) -> RuntimeResult<RuntimeRemoval>;
43
44    async fn logs(
45        &self,
46        unit: &RuntimeUnitRecord,
47        query: &RuntimeLogQuery,
48    ) -> RuntimeResult<Vec<RuntimeLogChunk>>;
49
50    /// Executes one durably identified request within its original budget.
51    ///
52    /// `ManagedRuntimeClient` always supplies `request.deadline_at_ms` as the
53    /// effective absolute deadline captured by the first reservation: the
54    /// smaller of that attempt's `timeout_ms` window and any caller-provided
55    /// absolute deadline. A pending replay receives the same persisted value,
56    /// so a driver must not restart or extend the execution window. Drivers may
57    /// enforce a shorter provider-specific timeout and must deduplicate or
58    /// reattach the stable request ID after an ambiguous result.
59    async fn exec(
60        &self,
61        unit: &RuntimeUnitRecord,
62        request: &RuntimeExecRequest,
63    ) -> RuntimeResult<RuntimeExecResult>;
64}