relayer/Orchestrator.md
The Orchestrator is a framework for structuring software components using an event-driven architecture.
This decouples functionality (in the handlers) from execution (via an event dispatcher). This allows the application to have multiple versions for same functionality with minor (or even major) differences in the flow. It also simplifies tracing and error handling.
Event dispatcher interface is an abstraction to plug in various dispatcher implementations.
It is possible to use one or a combination of dispatchers in a single orchestrator.
Event trait
pub trait Event: Clone + Send + Sync + 'static {
fn event_type(&self) -> u8;
fn request_id(&self) -> Uuid;
}
Orchestrator just needs the event type and request id for handling the events.
Event Dispatcher trait
#[async_trait]
pub trait EventDispatcher<E: Event>: Send + Sync {
async fn dispatch_event(&self, event: E) -> Result<(), Error>;
}
Defined generically over the Event, orchestrator uses the dispatcher to execute a handler for the event.
** Event Handler and Handler Registry traits**
#[async_trait]
pub trait EventHandler<E: Event>: Send + Sync {
async fn handle_event(&self, event: E);
}
pub trait HandlerRegistry<E: Event> {
fn register_handler(&self, event_id: u8, handler: Arc<dyn EventHandler<E>>);
}
Consumers of the event implement the Handler trait and Orchestrator implements a Handler Registry. The Handlers are registered in the orchestrator in the main program.
Request ID
Below is a high-level diagram showing how event-driven flow is structured for Input Proof in the Relayer SDK. Input Proof in Relayer SDK
Decouples Functionality from Execution
Flexible Flow Definition
Meta-Features as Shared Components