pub struct RuntimeBuilder { /* private fields */ }Expand description
Assembles a Runtime.
Implementations§
Source§impl RuntimeBuilder
impl RuntimeBuilder
pub fn skill(self, s: impl Skill) -> Self
Sourcepub fn signing_as(self, signer: Arc<dyn Signer>) -> Self
pub fn signing_as(self, signer: Arc<dyn Signer>) -> Self
The workload identity this plane signs its outward claims with.
What it buys is that a tool or peer can check who called it. Without a signer the provenance block still travels — a server can correlate on it — but it is an assertion any intermediary could have written, and a callee must not authorize on it.
Give the store the same signer (signing_as there) so records and
outward claims carry one identity. They are separate settings because a
plane can legitimately have one without the other.
Sourcepub fn lease_ttl(self, ttl: Duration) -> Self
pub fn lease_ttl(self, ttl: Duration) -> Self
How long this plane’s run leases last.
The trade is recovery speed against tolerance for a slow instance: a crashed owner’s runs stay unclaimable for this long, and a live owner must renew within it. The runtime heartbeats while a run executes, so this bounds crash detection rather than how long a run may take.
A TTL below MIN_LEASE_TTL is refused at
build/try_build as
BuildError::LeaseUnrenewable.
Both stores keep lease expiry in whole seconds and treat
expires_at <= now as lapsed, so a one-second lease expires the moment
the clock ticks past the second it was written in — no matter how often
it is renewed. Such a lease cannot be held by a live run, and a run that
cannot hold its lease is one any instance may take away mid-flight.
Refused where a manifest-serving plane can report it as a diagnostic
rather than left as a panic in a setter, which try_build’s callers
could never see as a value.
Sourcepub const fn tenant_label(self, label: TenantLabel) -> Self
pub const fn tenant_label(self, label: TenantLabel) -> Self
Put this plane’s tenant on what it reports about itself.
Off by default, and one policy for both signals: the tenant field of
every metric event, and agentplane.tenant on the run span. Read
telemetry::TenantLabel before turning
it on — a tenant name is often a customer name, and an observability
backend is usually the least protected system in a deployment.
Cardinality is bounded by construction — the label is this plane’s tenant, so the number of streams is the number of planes configured, and no request can grow it.
Sourcepub fn memory(self, memories: Arc<dyn MemoryStore>) -> Self
pub fn memory(self, memories: Arc<dyn MemoryStore>) -> Self
Give this plane’s agents a memory.
Optional, and absent by default: an agent with no memory is a normal agent, and one that quietly gained persistent state because a store was wired for something else would be a surprise.
Read crate::memory before wiring one. Writable memory is delayed
code: what is written today is read into a context window tomorrow, where
a model treats it as established fact.
Sourcepub fn semantic_memory(
self,
embedder: Arc<dyn Embedder>,
retriever: Arc<dyn SemanticRetriever>,
) -> Self
pub fn semantic_memory( self, embedder: Arc<dyn Embedder>, retriever: Arc<dyn SemanticRetriever>, ) -> Self
Give this plane a semantic index, and the embedder that speaks its language.
Both together, never one at a time: build holds
Embedder::revision to the IndexIdentity::query_revision the
index declares it accepts, and refuses the pair otherwise
(BuildError::EmbeddingSpaceMismatch says what a mismatch costs).
Also needs memory: the index holds only commitments,
and every hit is materialised from the authoritative store before its
content is exposed.
Attach durable standing-authority accounting.
The ceiling neither of the other two can express. A budget bounds one run; a quota bounds a tenant over a billing period. A standing authority bounds an authorization — what one customer approved, spanning as many runs as it takes, revocable when they change their mind.
Without one, StepCtx::draw refuses
rather than falling back to an in-process counter. That fallback would
fail open the moment a second instance started, which is exactly when
a shared ceiling was needed.
Sourcepub fn quota(self, quotas: Arc<dyn QuotaStore>, quota: TenantQuota) -> Self
pub fn quota(self, quotas: Arc<dyn QuotaStore>, quota: TenantQuota) -> Self
Bound what this tenant may consume, durably.
Budgets bound one run; this bounds the tenant. Both are needed: a caller that can start runs can start a thousand, each within its own ceiling.
The accounting lives in the store, so the ceiling survives a second instance — an in-process counter would silently double the moment somebody scales out, which is exactly when it was needed.
Read crate::quota for what each ceiling does and does not bound; a
limit believed to bound something it does not is worse than none.
Sourcepub fn owner(self, o: impl Into<String>) -> Self
pub fn owner(self, o: impl Into<String>) -> Self
This process instance’s identity, as it appears in run leases.
Not the agent’s name, and the distinction is load-bearing. A lease is renewed without bumping the epoch when the holder is the same owner, so two processes sharing an owner string each read the other’s lease as their own: no fencing, no epoch bump, and two writers on one run. That is precisely the failure the epoch exists to prevent.
So it must be unique per running process, which is what the default is —
override it only if you have a better instance identity than a random
one, such as a pod name. An agent’s name is
Manifest::metadata; several
instances of one agent are normal and must not share this.
The owner lives in the lease table and never in the chain, so it has no bearing on replay.
Sourcepub fn budget(self, budget: Budget) -> Self
pub fn budget(self, budget: Budget) -> Self
Cap what a run may consume.
Defaults to Budget::unlimited, which is right for a runtime whose
effects are all free and local, and wrong the moment one of them calls a
metered API.
Sourcepub fn require_verifier(self) -> Self
pub fn require_verifier(self) -> Self
Refuse a plan in which nothing checks the work.
A node that declares verifies must
already depend on what it checks; this makes carrying one a condition of
admission. It binds every plan this runtime validates, and the one that
matters is the one the embedder did not write: a
Replanner’s successor is a graph proposed
mid-run, and a control that held for the first plan and not for its
replacement is a control a replan removes.
Sourcepub fn cases(self, cases: Arc<dyn CaseStore>) -> Self
pub fn cases(self, cases: Arc<dyn CaseStore>) -> Self
Attach long-lived case storage, enabling correlation and deadlines.
Sourcepub fn outbox(self, outbox: Arc<Outbox>) -> Self
pub fn outbox(self, outbox: Arc<Outbox>) -> Self
Send this plane’s own events to destinations the deployment configured.
Every run registers each destination at admission, so there is no
window in which a run exists and nothing is watching it. Delivery is a
separate, operator-scheduled sweep — see
DeliveryWorker — reading each run’s
journal past a cursor that advances only on 2xx.
This is the mirror image of A2A push, and the mirror is the point: there the caller names a URL and three controls exist because of it. Here the deployment names it, and the run’s own history is the outbox rather than a queue that can fall out of sync with it.
Sourcepub fn push(self, push: Arc<dyn PushStore>) -> Self
pub fn push(self, push: Arc<dyn PushStore>) -> Self
Attach the webhook registration store.
The same handle the A2A server and the Outbox
are given: this is the durable half of push, and it belongs to the
plane because its failures do. A receiver that answers permanently, or
stays silent past the retry ceiling, has its registration
parked rather than deleted — the cursor
is the only record of how far that receiver got — and a parked row is a
backlog an operator reads and re-arms on the operator API. Without this
the plane serves the delivery and cannot answer for it.
Sourcepub fn events(self, events: Arc<dyn EventStore>) -> Self
pub fn events(self, events: Arc<dyn EventStore>) -> Self
Attach inbound-event storage, enabling durable waits.
Sourcepub fn replanner(self, r: Arc<dyn Replanner>) -> Self
pub fn replanner(self, r: Arc<dyn Replanner>) -> Self
Supply the planner that produces successor plans.
Without one, a step asking to replan fails with that as the reason — which is the honest outcome, not a silent no-op.
Sourcepub fn timers(self, timers: Arc<dyn TimerStore>) -> Self
pub fn timers(self, timers: Arc<dyn TimerStore>) -> Self
Supply the durable-timer store.
Needed by StepCtx::sleep and sleep_until, and by the sweep that wakes
them. A runtime without one refuses to sleep rather than falling back to
an in-process wait that a restart would forget.
Sourcepub fn agent(self, agent: Agent) -> Self
pub fn agent(self, agent: Agent) -> Self
Register an agent on this plane.
A runtime runs agents; it is not one. This is where a declaration and its skills arrive together, so several agents can share one journal, one set of drivers and one process identity while each stays separately governed.
The declaration binds for that agent’s steps: an effect naming a model or tool its manifest never listed is refused before dispatch and journaled, and the egress and delegation ceilings combine with the sink’s own — the stricter wins. Its budget bounds its runs. Architectural injection patterns are deliberately absent from the schema, because this runtime cannot prove that arbitrary skill code follows one.
An agent declaring spec.execution needs no skill: the runtime supplies
the behaviour. See provider for the driver mapping it
needs.
It does not set the lease owner. That identifies a process, and one
plane running four agents is still one process — see
owner.
§This call never fails
It records the agent and returns. Every refusal an agent can cause — a
capability none of its skills provide, a provider no driver is registered
for, oversight with nowhere to put a decision — is raised at
build, which panics, or returned by
try_build, which does not.
That split matters for a daemon assembling a plane from files it did not
write: a bad manifest is an input there, and a panic takes down every
other tenant in the process to report it. A # Panics section here,
describing build’s refusals, would send readers looking for a
fallible variant of the wrong call — the refusals are documented where
they fire.
Sourcepub fn provider(
self,
name: impl Into<String>,
provider: Arc<dyn ModelProvider>,
) -> Self
pub fn provider( self, name: impl Into<String>, provider: Arc<dyn ModelProvider>, ) -> Self
Register a model driver under the name a manifest uses for it.
The seam a declarative agent needs. A manifest says provider: anthropic
— a string a reviewer can read — and something has to map that to a
driver holding a credential. That mapping is deployment wiring, not a
property of the agent, which is exactly why it lives here and not in the
file: an agent’s declaration should not change when its API key does.
Required only for ExecutionKind::Completion and the other declarative
kinds. A hand-written skill constructs its own ModelCall and never
consults this.
Sourcepub fn blobs(self, blobs: Arc<dyn BlobStore>) -> Self
pub fn blobs(self, blobs: Arc<dyn BlobStore>) -> Self
Supply content-addressed blob storage.
Needed by StepCtx::store_blob, which is how bytes too large for a
journal record get somewhere durable while the chain keeps only their
digest. A runtime without one refuses rather than silently inlining
megabytes into an append-only chain that can never take them back.
Sourcepub fn disclosures(self, register: Arc<dyn DisclosureRegister>) -> Self
pub fn disclosures(self, register: Arc<dyn DisclosureRegister>) -> Self
Where disclosures of a matter are recorded, so a retention pass names the copies of what it erased.
Sourcepub fn tools(
self,
catalog: Arc<ToolCatalog>,
client: Arc<dyn ToolClient>,
) -> Self
pub fn tools( self, catalog: Arc<ToolCatalog>, client: Arc<dyn ToolClient>, ) -> Self
The operator’s tool catalogue, and the client that reaches those tools.
Required by a tool-calling agent and by nothing else: a skill that
calls tools builds its own ToolCall, because
it knows which client it means. A declarative agent has no code to make
that choice, so the plane makes it once.
The catalogue is the authority. A manifest grants a subset of it, the model is offered exactly that subset, and a name the model returns is matched against it byte for byte.
Sourcepub fn toolbox(self, tools: ToolBox) -> Self
pub fn toolbox(self, tools: ToolBox) -> Self
Typed tools, with their catalogue derived and their coherence enforced.
The one-call form, and the reason it exists is not brevity. Deriving the catalogue and checking it against every agent’s manifest were both possible before and both optional, and a control a caller may forget is not a control — it is advice that reads like one.
So this does three things that were three things:
- derives the catalogue from each agent’s declaration, so a grant, its ceiling and its protected fields are stated once;
- refuses to build if the tools this binary implements and the manifests a reviewer approved have drifted apart;
- wires the box as the client.
The work happens in build rather than here, and that is
the whole reason it is trustworthy: checking on this call would check
against the agents registered so far, so .toolbox(..).agent(..) would
pass by having nothing to disagree with. An enforcement that depends on
the order a builder was written is not one.
Sourcepub fn tool_server(
self,
name: impl Into<String>,
client: Arc<dyn ToolClient>,
) -> Self
pub fn tool_server( self, name: impl Into<String>, client: Arc<dyn ToolClient>, ) -> Self
A tool server this plane reaches over some transport of its own.
An MCP connection is the usual one. Registering it does three things:
- a plane may reach several servers, because the router resolves the
tool://server/namea grant carries rather than handing every id to one client; - typed in-process tools and remote servers can be used by the same agent, which is the ordinary shape;
- a grant naming a server nobody wired is refused at build, in the same breath as a grant nothing implements — both mean the model would be offered a tool that fails when chosen.
Composes with toolbox; the box answers for the servers
its own tools name and these answer for theirs. A server claimed twice is
a panic, because registration order deciding which transport carries a
call is the defect ToolRouter exists to
remove.
Sourcepub fn egress(self, egress: Egress) -> Self
pub fn egress(self, egress: Egress) -> Self
Where this plane’s tool transports may connect.
A ToolClient is the embedder’s code, and the split is the one every
other outbound path here makes: the client owns the connection, the
plane owns the destination. A transport says where it goes with
ToolClient::destination, and
this decides whether that is somewhere it may go — before the effect
exists, so nothing leaves, nothing is journaled and nothing is metered.
A Destination::Local transport is
not judged: tools compiled into the binary and a stdio child process
contact no host of this plane’s choosing, so there is nothing for an
allowlist to decide. What that does not claim is that the far side
reaches nothing — the same residual a compromised allowlisted endpoint
carries.
Unset means no egress control on the tool path, spelled the way an absent policy engine is: by configuring nothing, rather than by configuring something that looks like a control and is not.
let plane = Runtime::builder(store)
.tool_server("tickets", mcp_over_https)
.egress(Egress::new().allow("mcp.tickets.example"))
.build();Sourcepub fn observe_model_streams(self, observer: Arc<dyn RunStreamObserver>) -> Self
pub fn observe_model_streams(self, observer: Arc<dyn RunStreamObserver>) -> Self
Forward every model call’s live output, with the run it belongs to.
Advisory and live-only: the journal’s completion stays the canonical answer, a replay performs no call and so streams nothing, and an observer that drops events changes nothing a run does.
Sourcepub fn content_checker(self, checker: Arc<dyn ContentChecker>) -> Self
pub fn content_checker(self, checker: Arc<dyn ContentChecker>) -> Self
Register a content checker, by its name.
A manifest check naming a checker no builder registered, or mapping a category the checker does not declare, refuses the build: a declared check nothing could run is a control a reviewer approved that does not exist.
Sourcepub const fn max_sensitivity_journaled(self, ceiling: Sensitivity) -> Self
pub const fn max_sensitivity_journaled(self, ceiling: Sensitivity) -> Self
The highest sensitivity this plane will write into an append-only record.
§What this is, and what the key ring is
Two different answers to this data must be erasable, and they compose.
keyring is the seal it half: payloads become
ciphertext whose key an erasure destroys, which reaches every replica
and every backup at once. This is the refuse it half: an argument
more sensitive than the deployment is willing to make permanent is
refused at dispatch, before it reaches the chain.
The plane-level twin of spec.security.max_sensitivity_journaled, for
a plane of hand-written skills that runs under no manifest. The default
is the unsafe one — a journal keeps everything, indefinitely — so a
plane must be able to state the ceiling whether or not it is
declarative. It is an enforcement point at the same gate the manifest’s
field reaches, not a warning; where both are present the stricter
wins, as a reviewed tool grant may only tighten what the operator’s
catalogue allows.
Absent means no ceiling, spelled the way an absent policy engine is.
let plane = Runtime::builder(store)
// Personal data goes in a blob and the chain gets the digest.
.max_sensitivity_journaled(Sensitivity::Internal)
.skill(Triage)
.build();Sourcepub fn tenant(self, tenant: TenantId) -> Self
pub fn tenant(self, tenant: TenantId) -> Self
Which tenant this plane runs as.
One plane, one tenant — but one process, many planes. A plane is the
unit that is bound to a tenant; serving several is
Planes’ job, and it resolves the plane from the
authenticated caller’s tenant rather than from the request, so a handler
cannot reach a store it did not resolve. An unregistered tenant is
refused rather than defaulted.
The name scopes data keys, so one tenant’s cryptographic erasure cannot reach another’s bytes, and it reaches the policy request, so a rule can be written per tenant.
It does not scope the store — that is a separate handle, scoped by
RedbStore::for_tenant or PostgresStore::for_tenant. Two tenants may
share one store, because the tenant is a key component of every row on
both backends rather than a filter. Setting one and not the other is
refused at build rather than discovered later: a plane
whose store is scoped elsewhere works perfectly and writes its runs into
somebody else’s keyspace.
Defaults to default, which is a real tenant rather than an absence: the
single-tenant path is then the same code as the multi-tenant one, and a
special “no tenant” case is a second path that would not get tested.
Sourcepub fn keyring(self, keyring: Arc<dyn KeyRing>) -> Self
pub fn keyring(self, keyring: Arc<dyn KeyRing>) -> Self
Seal payload bytes, and make erasure reach copies deletion cannot.
With a key ring configured, everything written through
StepCtx::blobs — including
store_blob and governed media —
is encrypted under a data key belonging to the run’s case. Erasing
that case destroys the key, so every copy of those bytes becomes
unreadable at once: the live store, the replicas, and every backup ever
taken. Expiring blobs only reaches the first of those.
The case is the erasure unit because it is already the retention unit — bytes are linked to their case at write time, and a second, differently shaped unit for keys would let the two disagree about what an erasure covered.
It also seals the stores the plane holds — the journal’s payloads, case
state, task proposals and buffered event payloads — at
build, so the order they were registered in cannot lose
the guarantee — a store registered after this call is sealed just the
same.
Governed memory is the one store this does not reach.
EncryptedMemoryStore
serialises subject erasure against writes and legal-hold changes with a
process-local mutex, so it holds its contract on a single-writer
deployment and nowhere else; wrapping it here would hand that adapter to
an active-active PostgreSQL plane, where the mutex coordinates nothing
and the hold race it exists to prevent is the result. Its erasure unit
is tenant/memory/<subject> and outlives every case, so erase_case
was never the act that reaches it either. Wrap it yourself, where the
deployment’s topology is visible:
let memories = EncryptedMemoryStore::new(inner, keys.clone(), tenant.clone());
Runtime::builder(store).memory(Arc::new(memories)).keyring(keys).build()Without one, bytes are stored as given and erasure remains deletion.
Sourcepub fn batches(self, batches: Arc<dyn BatchStore>) -> Self
pub fn batches(self, batches: Arc<dyn BatchStore>) -> Self
Supply the store that tracks batch items.
Only needed for Runtime::run_batch; a plane that runs no batches does
not need one, and asking for it unconditionally would make the common
case carry the uncommon one’s setup.
Sourcepub fn policy(self, policy: Arc<dyn PolicyEngine>) -> Self
pub fn policy(self, policy: Arc<dyn PolicyEngine>) -> Self
Supply the authorization engine.
Without one there is no policy layer — the information-flow gates still
apply, but nothing asks whether the principal was allowed. That is a
deliberate absence rather than a permissive default: see core::policy
on why there is no AllowAll to configure by mistake.
The engine’s complete immutable bundle identity is recorded at admission, so both whether policy was on and exactly which executable semantics governed the run are answerable from the journal. An open run may resume only under that same identity.
Sourcepub fn acting_as(self, chain: Delegation) -> Self
pub fn acting_as(self, chain: Delegation) -> Self
The chain this plane’s own runs act under.
The identity of a run the embedder starts in-process — checked against the plan at admission (the plan is the authorization graph, so one that exceeds the chain’s authority never starts), held to the chain’s audience and validity, and journaled, so “on whose behalf” is answerable from history rather than reconstructed from timestamps.
It is not the identity of a run a served surface admits for a
caller: those act under the chain the caller presented, or under none
when it presented none (RunTerms::served). A plane that bound its own
chain to every peer’s run would be an ambient credential.
Verification of the credential belongs to whatever authenticates the caller; what arrives here is already a chain, and its attenuation is guaranteed by its own constructors however it was obtained.
Sourcepub fn peers(self, registry: PeerRegistry, client: Arc<dyn PeerClient>) -> Self
pub fn peers(self, registry: PeerRegistry, client: Arc<dyn PeerClient>) -> Self
The peers this plane may call, and the transport that reaches them.
The registry is wiring — what each peer is granted, which credential
reaches it, how a failed call recovers. What a run may ask a peer
for is a manifest grant, tool://<peer>/<capability>, dispatched
through StepCtx::call_peer.
Refused at build: a peer named agent or like a wired tool server,
and a grant naming a capability outside the peer’s registry scope.
Sourcepub fn witnesses(
self,
witnesses: Vec<Arc<dyn Witness>>,
quorum: WitnessQuorum,
) -> Self
pub fn witnesses( self, witnesses: Vec<Arc<dyn Witness>>, quorum: WitnessQuorum, ) -> Self
Submit this plane’s checkpoints to witnesses, and hold each round to a quorum.
This is the only control here whose value comes from not being this plane. The hash chain proves no record was edited, the signatures say which workload wrote them, and the Merkle log proves no sealed run was removed — but every input to all three comes from the party an auditor is being asked to trust. None of them detects a whole run deleted before anyone took a checkpoint, or two internally perfect histories shown to two auditors. A witness keeps the last checkpoint it saw and cosigns only a checkpoint that provably extends it, so those two stop being invisible.
Availability never waits on it: submission runs on
sweep, after sealing and off the run path, and a
round that falls short is a report rather than a refusal. A run whose
witnesses are unreachable finished long ago, and making the plane’s
availability depend on a third party is the wrong trade for evidence
that is read after the fact.
Point it at witnesses somebody else runs. A witness hosted beside the
history it vouches for is an anchor one compromise removes, and
MemoryWitness says so at its own
definition.
§Errors
build refuses a quorum larger than the
number of witnesses configured, and a witness list with no quorum.
Sourcepub fn witness_interval(self, interval: Duration) -> Self
pub fn witness_interval(self, interval: Duration) -> Self
Declare the maximum time between checkpoint submissions to each
witness: sweep re-submits an unchanged checkpoint
once it has passed since the last round that met quorum, so an idle
plane still carries a fresh witness timestamp. Without it an unchanged
log is never re-submitted.
The interval is kept only as often as sweep runs; a deployment
sweeping on its own scheduler owns that cadence.
§Errors
build refuses an interval with no witnesses.
Sourcepub fn calendar(self, calendar: Arc<dyn Calendar>) -> Self
pub fn calendar(self, calendar: Arc<dyn Calendar>) -> Self
Supply the calendar that resolves deadline descriptions to instants.
Defaults to WallClock, which understands plain offsets and refuses
anything it does not know rather than approximating it. Domain calendars
— working days, holidays, cut-off hours — are the adapter’s job.
Sourcepub fn build(self) -> Arc<Runtime> ⓘ
pub fn build(self) -> Arc<Runtime> ⓘ
Assemble the runtime, or panic naming the wiring mistake.
The ordinary entry point. Every refusal below is a bug in code the author
is looking at, so propagating it through ? to a main that prints it
is ceremony around an abort — and each is caught here at startup rather
than at dispatch, in production, where the cost is a run that has already
begun.
Use try_build where a manifest arrives at runtime
— read from disk, pinned by a registry, or supplied per tenant. There a
bad declaration is an input rather than a bug, and a panic would take
every other tenant in the process down to report it.
§Panics
On any BuildError:
- A manifest declares a capability in
spec.capabilities.providesthat no registered skill provides. An agent has skills, so a declaration advertising one it cannot perform is a card that lies. - Two agents claim the same capability. Dispatch resolves a capability to one skill and to the manifest governing it, so a second claim would silently take the first’s work out from under the first’s budget, model grants and egress ceiling.
- Two skills share a name. A name is what a capability resolves to and what governance is keyed on; two of them make both lookups arbitrary.
- A stated catalogue calls a tool read-only that a reviewed manifest grants as mutating. That exemption drops the whole-value taint gate and makes a timed-out money-moving call retryable — the one direction an operator cannot be right about.
- A declarative agent names a provider no driver is registered for, or
declares
spec.executionwithout a privileged model to call. - A plane and its store — or its blob store — are scoped to different
tenants. The two are set
separately — this builder’s tenant scopes data keys and the policy
request,
for_tenantscopes the store’s keys — and the mismatch does not show up at runtime. It works, and writes this tenant’s runs into another’s keyspace while every erasure and every policy request names the right one.
§Long-running services want try_build
This panics, which is the honest answer for a binary wiring its own
skills: every variant above is a bug in code the author is looking at,
and aborting reports it at the moment it can be fixed. A daemon is a
different case — it wants to exit with a diagnostic, and a plane
assembled from a manifest that arrived at runtime is handling an input,
where a panic reports one tenant’s typo by killing every other tenant’s
in-flight run. try_build returns the same BuildError instead. One
implementation underneath both, so they cannot disagree about what is
refused.
Sourcepub fn try_build(self) -> Result<Arc<Runtime>, BuildError>
pub fn try_build(self) -> Result<Arc<Runtime>, BuildError>
Assemble the runtime, or say why it cannot be.
The same checks as build, returned rather than raised.
One implementation behind both, so they cannot come to disagree about
what is refused.
§Errors
Any BuildError — see build for what each means.
Trait Implementations§
Auto Trait Implementations§
impl !RefUnwindSafe for RuntimeBuilder
impl !UnwindSafe for RuntimeBuilder
impl Freeze for RuntimeBuilder
impl Send for RuntimeBuilder
impl Sync for RuntimeBuilder
impl Unpin for RuntimeBuilder
impl UnsafeUnpin for RuntimeBuilder
Blanket Implementations§
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> 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 more