Summary
It would be cool if this library had a system similar to middlewares in the inngest library (https://www.inngest.com/docs/features/middleware/dependency-injection)
So the user would be able to define a piece of code on workflow level, that will be executed around every step. This would enable things like
- custom tracing / logging
- dependency injection
- wrapping each step in a custom
AsyncLocalStorage context
My specific problem and workaround
I am using AsyncLocalStorage in my application as some kind of request-scoped dependency provider. This way I can have a tenant scoped db transaction that can always be accessed through als.getStore().
This store gets constructed in the middleware of my endpoint normally based on userId and tenantId and is afterwards accessible through the whole call stack.
This gets lost however since steps are executed outside of the call stack (and the process altogether)
export async function calculationStep(scope: RunScope): Promise<{ // RunScope is the serialized version of my AsyncLocalStorage store.
var1: string[];
var2: string | null;
}> {
'use step';
return runInAlsContext(scope, async () => { // based on the scope variables the ALS store is reconstructed like I would do in my api middleware
const { rlsDb } = getContext(); // getContext is a wrapper for als.getStore();
...
});
Right now I am wrapping the code in each step inside a runInAlsContext function. This ends up in a lot of boilerplate, and easy to miss once.
Possible solution
(very rough draft)
- define a middleware and attach it to a workflow where it is defined
- middleware function takes a "next" function as argument and a context/params object
- the context/params object gets passed at trigger time of the workflow in the start() function (how to keep this typesafe?)
Happy to dive into some code during the weekend and give an api proposal...
Summary
It would be cool if this library had a system similar to middlewares in the inngest library (https://www.inngest.com/docs/features/middleware/dependency-injection)
So the user would be able to define a piece of code on workflow level, that will be executed around every step. This would enable things like
AsyncLocalStoragecontextMy specific problem and workaround
I am using
AsyncLocalStoragein my application as some kind of request-scoped dependency provider. This way I can have a tenant scoped db transaction that can always be accessed through als.getStore().This store gets constructed in the middleware of my endpoint normally based on userId and tenantId and is afterwards accessible through the whole call stack.
This gets lost however since steps are executed outside of the call stack (and the process altogether)
Right now I am wrapping the code in each step inside a
runInAlsContextfunction. This ends up in a lot of boilerplate, and easy to miss once.Possible solution
(very rough draft)
Happy to dive into some code during the weekend and give an api proposal...