pub struct RunnerHost { /* private fields */ }Expand description
Runtime host that manages tenant-bound packs and flow execution.
Implementations§
Source§impl RunnerHost
impl RunnerHost
pub async fn start(&self) -> Result<(), Error>
pub async fn stop(&self) -> Result<(), Error>
pub async fn load_pack( &self, tenant: &str, pack_path: &Path, ) -> Result<(), Error>
pub async fn handle_activity( &self, tenant: &str, activity: Activity, ) -> Result<Vec<Activity>, Error>
Sourcepub async fn handle_activity_for_revision(
&self,
tenant: &str,
deployment_id: DeploymentId,
bundle_id: BundleId,
revision_id: RevisionId,
activity: Activity,
) -> Result<Vec<Activity>, Error>
pub async fn handle_activity_for_revision( &self, tenant: &str, deployment_id: DeploymentId, bundle_id: BundleId, revision_id: RevisionId, activity: Activity, ) -> Result<Vec<Activity>, Error>
Execute an activity against a specific deployment/bundle/revision runtime.
Unlike handle_activity, which resolves the
tenant-only (legacy) runtime, this targets a fully-qualified revision
entry inserted by ActivePacks::insert_revision. A tenant can host
several concurrent revisions under a traffic split, so the legacy
tenant-only lookup cannot disambiguate them — the ingress revision
dispatcher selects the revision and calls this.
§Session isolation contract
This method runs the selected revision’s runtime against whatever
session/state stores that runtime was built with (at
TenantRuntime::load_revision time). It does not add a revision
dimension to the session key: the session/resume/state backend keys on
(env, tenant, user) plus pack/flow, not on the revision. If two
live revisions of the same pack for one tenant share a single session
backend, a wait/resume snapshot created by revision A can be fetched —
or clobbered — by revision B during a traffic split, retry, or
rebalance, resuming a snapshot against a different flow graph.
Callers that load more than one revision per tenant onto one host
(i.e. every traffic-split producer) MUST give each revision an
isolated session and state store (a per-revision store instance, or a
revision-namespaced backend) when calling load_revision. The shared
RunnerHost stores (session_store()/state_store()) are only safe to
reuse across revisions when at most one revision is ever live per
tenant. The greentic-start activation path enforces this.
Sourcepub async fn identify_messaging_endpoints_for_revision(
&self,
tenant: &str,
deployment_id: DeploymentId,
bundle_id: BundleId,
revision_id: RevisionId,
provider_types: &[&str],
payload: &[u8],
) -> Result<HashMap<String, IdentifyOutcome>, Error>
pub async fn identify_messaging_endpoints_for_revision( &self, tenant: &str, deployment_id: DeploymentId, bundle_id: BundleId, revision_id: RevisionId, provider_types: &[&str], payload: &[u8], ) -> Result<HashMap<String, IdentifyOutcome>, Error>
Per-revision per-provider_type identify-instance probe (M1 IID.4).
Given the candidate provider_types an env declares messaging
endpoints for, ask each pack loaded under this revision (main +
overlays) which provider_id the inbound payload claims to address.
The greentic-start resolver pairs the returned provider_id with the
provider_type and looks the MessagingEndpointId up in the env’s
admit table; that’s how a header-less webhook gets auto-routed to the
right endpoint.
payload is forwarded opaque to every probed component. The M1
IID.4d wrapper convention from greentic-start is
{headers: [{name,value}], body: <parsed-or-null>}. See the WIT
docstring on greentic:provider-instance-identity@0.1.0/identify-instance
for the full contract.
This is the unscoped legacy API; new callers should use
identify_messaging_endpoints_for_revision_scoped for per-provider
header allowlist scoping (Phase D). Merge lattice:
Identified > NoMatch > Unsupported — first pack to Identified
wins and that type drops out of remaining probing.
The per-pack loop is inlined (rather than factored into a shared
AsyncFnMut-based helper) deliberately: routing the loop through an
AsyncFnMut closure destabilises HRTB Send inference for
downstream consumers spawning the returned future (greentic-start’s
hyper service_fn). The Send-bound test
[identify_futures_are_send] guards against silent regression.
Sourcepub async fn identify_messaging_endpoints_for_revision_scoped(
&self,
tenant: &str,
deployment_id: DeploymentId,
bundle_id: BundleId,
revision_id: RevisionId,
provider_types: &[&str],
headers: &[(String, String)],
body: &Value,
) -> Result<HashMap<String, IdentifyOutcome>, Error>
pub async fn identify_messaging_endpoints_for_revision_scoped( &self, tenant: &str, deployment_id: DeploymentId, bundle_id: BundleId, revision_id: RevisionId, provider_types: &[&str], headers: &[(String, String)], body: &Value, ) -> Result<HashMap<String, IdentifyOutcome>, Error>
Per-provider scoped variant of
identify_messaging_endpoints_for_revision.
The wrapper is built per-provider from the component’s cached
describe-identify-instance hint (see
PackRuntime::resolve_identify_hint): hinted components receive
ONLY the headers their hint declares; unhinted components receive
every header the caller passed in (back-compat).
Loop inlined for the same reason as
identify_messaging_endpoints_for_revision.
Sourcepub async fn describe_identify_instances_for_revision(
&self,
tenant: &str,
deployment_id: DeploymentId,
bundle_id: BundleId,
revision_id: RevisionId,
provider_types: &[&str],
) -> Result<HashMap<String, Option<IdentifyInstanceHint>>, Error>
pub async fn describe_identify_instances_for_revision( &self, tenant: &str, deployment_id: DeploymentId, bundle_id: BundleId, revision_id: RevisionId, provider_types: &[&str], ) -> Result<HashMap<String, Option<IdentifyInstanceHint>>, Error>
Per-revision describe-identify-instance hint discovery.
Fans the cached describe probe out across main pack + overlays;
first non-None hint per provider_type wins. Lets callers inspect
the per-provider header allowlist without running the expensive
identify-instance probe. None value means no pack in this revision
exposes a usable hint for that provider_type.
Loop inlined for the same reason as
[identify_messaging_endpoints_for_revision].
Sourcepub async fn invoke_provider_for_revision(
&self,
tenant: &str,
deployment_id: DeploymentId,
bundle_id: BundleId,
revision_id: RevisionId,
provider_type: &str,
op: &str,
input_json: Vec<u8>,
correlation_id: Option<String>,
trace_id: Option<String>,
) -> Result<Value, Error>
pub async fn invoke_provider_for_revision( &self, tenant: &str, deployment_id: DeploymentId, bundle_id: BundleId, revision_id: RevisionId, provider_type: &str, op: &str, input_json: Vec<u8>, correlation_id: Option<String>, trace_id: Option<String>, ) -> Result<Value, Error>
Per-revision provider invocation (Phase D).
Locates the unique pack in (deployment_id, bundle_id, revision_id)
whose greentic.provider-extension.v1 binds the requested
provider_type, verifies op is in that declaration’s allowlist,
then calls op on it with input_json.
Used by greentic-start’s Phase D ProviderRoute admission arm to
run provider webhooks (e.g. ingest_http) without round-tripping
through the flow engine. The provider component returns the parsed
HTTP-out envelope verbatim; greentic-start dispatches the events
it carries back through the flow runtime separately.
correlation_id is threaded into the ComponentExecCtx as both
correlation_id and idempotency_key (mirroring the operator-API
pattern in build_exec_ctx). trace_id rides through as-is.
Fails closed when:
- the revision isn’t loaded (error chain names deployment + revision)
- no pack in the revision binds
provider_type - multiple packs in the revision bind
provider_type— the URL → provider routing the caller did at the route table is unable to disambiguate at invoke time. Mirrors the within-pack ambiguity check inProviderRegistry::resolve, lifted to the revision level so an overlay accidentally redeclaring a main-pack provider can’t silently shadow the wrong runtime. A future revision of this API can accept an explicitprovider_idto disambiguate when D.3 wires identification + invocation together. opis not in the resolved provider’s declaredopsallowlist (defense-in-depth: a caller bug or misconfiguredProviderRoutecannot smuggle an undeclared op past the schema-core boundary).
Loop inlined for the same reason as
[identify_messaging_endpoints_for_revision].
pub async fn tenant(&self, tenant: &str) -> Option<TenantHandle>
pub fn active_packs(&self) -> Arc<ActivePacks> ⓘ
pub fn health_state(&self) -> Arc<HealthState> ⓘ
pub fn wasi_policy(&self) -> Arc<RunnerWasiPolicy> ⓘ
pub fn session_store(&self) -> Arc<dyn SessionStore> ⓘ
pub fn state_store(&self) -> Arc<dyn StateStore> ⓘ
pub fn session_host(&self) -> Arc<dyn SessionHost> ⓘ
pub fn state_host(&self) -> Arc<dyn StateHost> ⓘ
pub fn secrets_manager(&self) -> Arc<dyn SecretsManager> ⓘ
pub fn tenant_configs(&self) -> HashMap<String, Arc<HostConfig>>
Auto Trait Implementations§
impl !RefUnwindSafe for RunnerHost
impl !UnwindSafe for RunnerHost
impl Freeze for RunnerHost
impl Send for RunnerHost
impl Sync for RunnerHost
impl Unpin for RunnerHost
impl UnsafeUnpin for RunnerHost
Blanket Implementations§
Source§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> FutureExt for T
impl<T> FutureExt for T
Source§fn with_context(self, otel_cx: Context) -> WithContext<Self>
fn with_context(self, otel_cx: Context) -> WithContext<Self>
Source§fn with_current_context(self) -> WithContext<Self>
fn with_current_context(self) -> WithContext<Self>
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request