⚙️ Install
If you work with MongoDB, then:
npm i @arturwojnar/hermes @arturwojnar/hermes-mongodb
💡 The easiest example for MongoDB
First, create an OutboxConsumer instance.
const outbox = createOutboxConsumer<Event1 | Event2>({
client,
client.db('hospital'),
publish: async (event) => await eventBus.publish(event),
})
Remember, that the publish
has to throw an error if the delivery to the message broker fails.
Then, you can use the instance to publish events along with a database operation:
await outbox.publish(event, async (session, db) => {
await db.collection('test').insertOne({ param: 1 }, { session })
})
As you see, the event
is passed to the outbox.publish
. Hermes starts a new database session and passes it in the first callback's parameter which is the second parameter.
The changes made in the callback will be persistend along with the passed event.
The event will be sent as fast as the message broker is available.
Alternatively, you can also create a session by your own:
await client.withSession(async (session) => {
await session.withTransaction(async (session) => {
await outbox.publish(event1, session)
await outbox.publish(event2, session)
})
})
Partitioning
By default, Hermes
works on default
partition.
If you want to scale out Hermes
, then you can use multiple partition keys and run separate instances for each partition key.
Example can be running Hermes
instances for tenants of your system. Then, each Hermes
will be responsible for one tenant.
➡️ If you noticed a performance issue: Consider, if your application is not too big, dealing with too many messages. Maybe it's time for a redesign and try to split your application into smaller ones?
const outbox1 = createOutboxConsumer<Event1 | Event2>({
client,
client.db('hospital'),
partitionKey: 'tenant-1',
publish,
})
const outbox2 = createOutboxConsumer<Event1 | Event2>({
client,
client.db('hospital'),
partitionKey: 'tenant-2',
publish,
})
🧹 Cleaning
By default, Hermes does the cleanup on SIGTERM
and SIGINT
unless shouldDisposeOnSigterm
is seto to false
, then you have to call outbox.stop
by your own.