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}