Lock Middleware
The Lock Middleware is built-in middleware that gives you capability to lock messages. It’s available for CommandBus and QueryBus
How to use it
As for any Middleware, you can use it by adding it to the bus
instance.
const commandBus = createCommandBus<CommandHandlerRegistry>();commandBus.useLockMiddleware({ adapter, ttl: 500, // the default ttl for all messages tick: 100, // the delay between each try to get the lock timeout: 1000 // the maximum time to wait for the lock getLockKey: async (envelope) => envelope.message.__type, intents: { createUser: { getLockKey: async (envelope) => envelope.message.something, timeout: 20, ttl: 50, tick: 10, }, },});
Remember built-in middlewares are intent aware, therefore you can customize the behavior per intent using the key
intents
.
Of course, the key is in the adapter
that you will provide to the createLockMiddleware
function.
This adapter must respect the LockAdapter
interface.
Here is an example:
type LockerInfo = { expiresAt: number;};
export const createInMemoryLockAdapter = (): LockAdapter => { const store: Map<string, LockerInfo> = new Map();
return { acquire: async (key, ttl) => { if (store.has(key)) { if (store.get(key)!.expiresAt > Date.now()) { return false; } } const now = Date.now(); const expiresAt = now + ttl; store.set(key, { expiresAt }); return true; }, release: async (key) => { store.delete(key); }, };};
const adapter = createInMemoryLockAdapter();
Explanation
With the Lock Middleware, if the intent is already locked, it will be returned directly without calling the handler.
You have to pass at least one of the following parameters to the createLockMiddleware
function:
getLockKey
: a function that takes an envelope and returns a string key (the one that will be used to identify the lock)
Then as a second argument, you can provide the following parameters (and per intent):
- adapter: the adapter to use to store the lock (default:
inMemoryLockAdapter
) - ttl: number (default:
500
) - the time to live in milliseconds - tick: number (default:
100
) - the delay between each try to get the lock - timeout: number (default:
1000
) - the maximum time to wait for the lock
Added Stamps
No stamps are added by this middleware.
Going further
Missive.js. MIT License.
Powered by Astro Starlight.
Inspired by Symfony Messenger