-
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
14 changed files
with
489 additions
and
38 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
--- | ||
title: Async Middleware | ||
description: Built-in middleware to defer handling to a consumer. | ||
--- | ||
|
||
import { Icon, Aside, Steps } from '@astrojs/starlight/components'; | ||
|
||
The Async Middleware is built-in middleware that gives you capability to defer the handling to an consumer to achieve real asynchronousity. | ||
It's only available for _CommandBus_ and _EventBus_ | ||
|
||
## How to use it | ||
|
||
As for any Middleware, you can use it by adding it to the `bus` instance. | ||
|
||
```typescript | ||
const commandBus = createCommandBus<CommandHandlerRegistry>(); | ||
commandBus.useAsyncMiddleware({ | ||
consume: false, // KEY POINT | ||
produce: async (envelope) => { | ||
// use your favorite queue system here | ||
console.log('Generic Push to Queue', envelope); | ||
}, | ||
async: true,// default is true | ||
intents: { | ||
createUser: { | ||
async: true, | ||
produce: async (envelope) => { | ||
// use your favorite queue system here | ||
console.log('createUser Push to Queue', envelope); | ||
}, | ||
}, | ||
}, | ||
}); | ||
``` | ||
|
||
> Remember built-in middlewares are _intent_ aware, therefore you can customize the behavior per intent using the key `intents`. | ||
Next, you need to have a consumer that will consume it. The way to do that with Missive.js is to create another bus with this middlware with `consume: true`. | ||
|
||
```typescript | ||
commandBus.useAsyncMiddleware({ | ||
consume: true, // KEY POINT | ||
}); | ||
``` | ||
|
||
The worker script that consumes the queue can dispatch the message it receives directly to the dispatch method: | ||
|
||
```typescript | ||
// Consumer script | ||
onMessage: async (message) => { | ||
const envelope = JSON.parse(message); | ||
await commandBus.dispatch(intent); | ||
} | ||
``` | ||
<Aside title="Gotchas" type="note"> | ||
Generally, the `dispatch` receives an `intent` but it can also receive an `envelope`. In this case, the `envelope` is the message received from the queue. | ||
</Aside> | ||
|
||
### Explanation | ||
|
||
The flow is the following: | ||
|
||
<Steps> | ||
|
||
1. Your application (web node for instance) will have a bus on which this middleware is added with `consume: false`. | ||
|
||
2. When you dispatch an intent, the middleware will push the intent to the queue system (via the `produce` method that you provide) instead of handling it. | ||
|
||
3. You have another application (worker node for instance) that will have a bus on which this middleware is added with `consume: true`. | ||
|
||
4. This worker will consume the intent from the queue system and handle it. | ||
|
||
</Steps> | ||
|
||
<Aside title="Important things to remember" type="caution"> | ||
- `intent` will pass through the bus twice, once for the `produce` and once for the `consume`, so make sure your middleware have no side effects. | ||
- Async Middleware breaks sthe chain of middlewares and for this reason, it is usually register the last. | ||
</Aside> | ||
|
||
<Aside title="Gotchas" type="tip"> | ||
When you dispatch an `envelope` to the `bus`, the bus will save the `envelope` original `stamps` in the `ReprocessedStamp` stamp. | ||
This way, the bus that consumes the `envelope` can have access to the original `stamps`. | ||
</Aside> | ||
|
||
|
||
## Added Stamps | ||
|
||
The Async Middleware is going to add: | ||
|
||
- | ||
```typescript | ||
type AsyncStamp = Stamp<undefined, 'missive:async'>; | ||
``` | ||
> When the intent is pushed to the queue. | ||
|
||
- | ||
```typescript | ||
type ReprocessedStamp = Stamp<{ stamps: Stamp[] }, 'missive:reprocessed'>; | ||
``` | ||
> When the envelope is dispatched. | ||
|
||
## Going further | ||
|
||
<div class='flex flex-row'> | ||
<span className='pr-2'>Look at the code of the </span> | ||
<a href="https://github.com/Missive-js/missive.js/tree/main/libs/missive.js/src/middlewares/async-middleware.ts" class="contents" target="_blank"><Icon name="github" class="mr-2"/>Async Middleware</a> | ||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
--- | ||
title: Built-in Stamps | ||
description: All the built-in Stamps that Missive.js provides. | ||
--- | ||
|
||
import { Aside } from '@astrojs/starlight/components'; | ||
|
||
|
||
This page lists all the built-in Stamps that Missive.js provides. | ||
Stamps are a way to handle cross-cutting concerns in your application. They are key to keeping your code clean and maintainable. | ||
Most of all, they are easy to write and use, and they can be generic! | ||
|
||
## Added by the Bus | ||
|
||
### IdentityStamp | ||
|
||
```typescript | ||
type AsyncStamp = Stamp<undefined, 'missive:async'>; | ||
``` | ||
Added on `bus.dispatch(intent|envelope)`. | ||
|
||
<Aside title="Dispatching an envelope" type="note"> | ||
If an `envelope` is dispatched, the original `IdentityStamp` will be preserved. | ||
</Aside> | ||
|
||
### HandledStamp | ||
|
||
```typescript | ||
type HandledStamp<R> = Stamp<R, 'missive:handled'>; | ||
``` | ||
Added when the intent is handled by the handler. | ||
|
||
<Aside title="More than one handler" type="tip"> | ||
The `HandledStamp` will be added by each handler. | ||
</Aside> | ||
|
||
<Aside title="Conditional handling" type="caution"> | ||
If a Middleware adds this stamp, the bus will not run the handler. | ||
</Aside> | ||
|
||
|
||
### ReprocessedStamp | ||
|
||
```typescript | ||
type ReprocessedStamp = Stamp<{ stamps: Stamp[] }, 'missive:reprocessed'>; | ||
``` | ||
|
||
Added when the `envelope` is dispatched through the bus instead of an `intent`. When this happens, | ||
the bus will save the original `stamps` in the `ReprocessedStamp` stamp. | ||
|
||
|
||
## Added by the Middlewares | ||
|
||
### AsyncStamp | ||
|
||
```typescript | ||
type AsyncStamp = Stamp<undefined, 'missive:async'>; | ||
``` | ||
|
||
Added when the envelope is sent to a queue via the [Async middleware](/missive.js/built-in-middlewares/async). | ||
|
||
### FromCacheStamp | ||
|
||
```typescript | ||
type FromCacheStamp = Stamp<undefined, 'missive:cache:hit'>; | ||
``` | ||
|
||
Added when the [Cacher middleware](/missive.js/built-in-middlewares/cacher) finds the result in the cache. | ||
|
||
### FeatureFlagFallbackStamp | ||
|
||
```typescript | ||
type FeatureFlagFallbackStamp = Stamp<undefined, 'missive:feature-flag-fallback'>; | ||
``` | ||
|
||
When the [Feature Flag Middleware](/missive.js/built-in-middlewares/feature-flag) uses a fallbackHandler. | ||
|
||
### TimingsStamp | ||
|
||
```typescript | ||
type TimingsStamp = Stamp<{ total: number }, 'missive:timings'> | ||
``` | ||
Add by the [Logger middleware](/missive.js/built-in-middlewares/logger) when the message is handled or errored with the total time elapsed in nanoseconds. | ||
### RetriedStamp | ||
```typescript | ||
type RetriedStamp = Stamp<{ attempt: number; errorMessage: string }, 'missive:retried'>; | ||
``` | ||
|
||
Added by the [Retryer middleware](/missive.js/built-in-middlewares/retryer) when the middleware retries the handling of the intent. | ||
<Aside title="More than one retry" type="tip"> | ||
You will get more than one Stamp! | ||
</Aside> | ||
|
||
|
||
### WebhookCalledStamp | ||
|
||
```typescript | ||
type WebhookCalledStamp = Stamp<{ attempt: number; text?: string, status?: number }, 'missive:webhook-called'>; | ||
``` | ||
|
||
Add by the [Webhook middleware](/missive.js/built-in-middlewares/webhook) when the middleware succeed to call the webhook(s) or ultimately at the end of the retries. | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,7 +18,7 @@ | |
"Sébastien Morel <[email protected]>", | ||
"Anaël Chardan" | ||
], | ||
"version": "0.2.0", | ||
"version": "0.3.0", | ||
"type": "module", | ||
"main": "./build/index.cjs", | ||
"module": "./build/index.js", | ||
|
Oops, something went wrong.