Skip to main content

EffectMiddleware

Trait EffectMiddleware 

Source
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:

  1. Reusing a Rust implementation of a capability compatible with all target platforms.
  2. 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::resolve before try_process_effect returns. 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 using spawn_local or a similar async task primitive. Calling resolve() synchronously inside try_process_effect will 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 Send and Sync, which also forces the Model type to be Send and Sync. This should not be a problem — Model should not normally be !Send or !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§

Source

type Op: Operation

The operation type this middleware can process.

Required Methods§

Source

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.

Implementors§