Design of middleware in flowstate
Hey, I'm looking for some guidance on how to design middleware for my crate flowstate.
Flowstate is a library for implementing self-executing workflows as a collection of self-describing states, locally encapsulating their transition logic.
I'd like to add middleware, which would at a basic level allow wrapping states and workflows.
I've implemented flowstate_middleware_tracing as a test case for this, as I don't want to "special case" the features I personally need. This crate depends on the unstable_middleware feature in flowstate. Usage looks like this:
let middleware = TracingMiddleware::default()
.with_workflow_span(|m: &WorkflowMetadata| {
info_span!("custom workflow span", my_workflow_name = m.name)
})
.with_state_span(|m: &WorkflowStateMetadata| {
info_span!("custom state span", my_state_name = m.name)
});
let result = workflow.run_with_middleware(middleware);
This works ok, but I'd really like to add some way to expose per-state fields which can be added to the span.
Initially, I had thought to add a WorkflowState::fields method. However, tracing doesn't allow the addition of dynamic fields, so this doesn't really work.
The only solution I can think of is to allow the WorkflowState implementation to define a make_span method, but I can't think of any way to do this that would not require a "special case" (i.e. only works for tracing) implementation in flowstate.
If anyone has any ideas, I'm open to suggestions!
The litmus test would be that the middleware implementation is flexible enough to allow flowstate_middleware_tracing to have different fields, message, etc. per state, without requiring flowstate to take a dependency on tracing.