pub trait EffectMiddleware: Send + Sync {
type Op: Operation;
// Required method
fn try_process_effect(
&self,
operation: Self::Op,
resolver: EffectResolver<<Self::Op as Operation>::Output>,
);
}Expand description
An effect processing middleware.
Implement this trait to provide effect processing in Rust on the core side. The two typical uses for this are:
- Reusing a Rust implementation of a capability compatible with all target platforms.
- Using an existing crate which is not built with Sans-IO in mind.
There are a number of considerations for doing this:
- The effect processing will rely on system APIs or crates which MUST be portable to all platforms the library using this middleware is going to be deployed to. This is fundamentally trading off portability for reuse of the Rust implementation.
- The middleware MUST process the effect asynchronously — it must not call
EffectResolver::resolvebeforetry_process_effectreturns. On native targets this typically means spawning a thread or sending work to a channel-based worker. On WASM (which has no threads) this means usingspawn_localor a similar async task primitive. Callingresolve()synchronously insidetry_process_effectwill panic. - Because the resolver may be sent to another thread (on native), the core
and therefore the app are shared between threads. The app must be
SendandSync, which also forces theModeltype to beSendandSync. This should not be a problem —Modelshould not normally be!Sendor!Sync.
§Example
ⓘ
impl EffectMiddleware for MyMiddleware {
type Op = MyOperation;
fn try_process_effect(
&self,
operation: MyOperation,
mut resolver: EffectResolver<<MyOperation as Operation>::Output>,
) {
std::thread::spawn(move || {
let output = do_work(operation);
resolver.resolve(output);
});
}
}Required Associated Types§
Required Methods§
Sourcefn try_process_effect(
&self,
operation: Self::Op,
resolver: EffectResolver<<Self::Op as Operation>::Output>,
)
fn try_process_effect( &self, operation: Self::Op, resolver: EffectResolver<<Self::Op as Operation>::Output>, )
Process the given operation and resolve via the provided resolver.
The framework has already extracted the operation from the effect enum.
Use the EffectResolver to send the result back. The resolver must
not be called before this method returns — dispatch the work
asynchronously (e.g. std::thread::spawn on native, spawn_local on
WASM, or a channel send) and call EffectResolver::resolve from
there.