@bumail/queue 0.11.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +47 -1
- package/dist/conformance/claims.d.ts +4 -0
- package/dist/conformance/claims.d.ts.map +1 -0
- package/dist/conformance/complete-dsns.d.ts +4 -0
- package/dist/conformance/complete-dsns.d.ts.map +1 -0
- package/dist/conformance/concurrency.d.ts +4 -0
- package/dist/conformance/concurrency.d.ts.map +1 -0
- package/dist/conformance/describe-queue-store.d.ts +11 -0
- package/dist/conformance/describe-queue-store.d.ts.map +1 -0
- package/dist/conformance/doubt.d.ts +5 -0
- package/dist/conformance/doubt.d.ts.map +1 -0
- package/dist/conformance/dsn.d.ts +4 -0
- package/dist/conformance/dsn.d.ts.map +1 -0
- package/dist/conformance/index.d.ts +3 -0
- package/dist/conformance/index.d.ts.map +1 -0
- package/dist/conformance/index.js +820 -0
- package/dist/conformance/index.js.map +18 -0
- package/dist/conformance/items.d.ts +4 -0
- package/dist/conformance/items.d.ts.map +1 -0
- package/dist/conformance/outcomes.d.ts +4 -0
- package/dist/conformance/outcomes.d.ts.map +1 -0
- package/dist/conformance/setup.d.ts +40 -0
- package/dist/conformance/setup.d.ts.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +77 -8
- package/dist/index.js.map +10 -9
- package/dist/queue/attempt.d.ts.map +1 -1
- package/dist/queue/events.d.ts +7 -0
- package/dist/queue/events.d.ts.map +1 -1
- package/dist/queue/fallback-session.d.ts.map +1 -1
- package/dist/queue/options.d.ts +15 -1
- package/dist/queue/options.d.ts.map +1 -1
- package/dist/queue/session.d.ts +5 -1
- package/dist/queue/session.d.ts.map +1 -1
- package/dist/queue/settings/index.d.ts +5 -2
- package/dist/queue/settings/index.d.ts.map +1 -1
- package/dist/queue/settings/sender.d.ts +16 -0
- package/dist/queue/settings/sender.d.ts.map +1 -0
- package/dist/queue/worker.d.ts.map +1 -1
- package/docs/guide.md +119 -3
- package/docs/roadmap.md +20 -6
- package/docs/troubleshooting.md +68 -0
- package/package.json +10 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../src/queue/options.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../src/queue/options.ts"],"names":[],"mappings":"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"}
|
package/dist/queue/session.d.ts
CHANGED
|
@@ -3,12 +3,16 @@ import type { DeliveryContext } from './deliver';
|
|
|
3
3
|
import type { RecipientEvent } from './events';
|
|
4
4
|
import type { Route } from './options';
|
|
5
5
|
/** The route a recipient's last session took, as its events tell it. */
|
|
6
|
-
export type Used = Pick<RecipientEvent, 'route' | 'fallback' | 'mxReply'>;
|
|
6
|
+
export type Used = Pick<RecipientEvent, 'route' | 'fallback' | 'mxReply' | 'reused'>;
|
|
7
7
|
/** One session's outcomes, and the error that ended it, if any. */
|
|
8
8
|
export interface Attempt {
|
|
9
9
|
readonly updates: RecipientUpdate[];
|
|
10
10
|
readonly error?: unknown;
|
|
11
|
+
/** The session went over a connection that had carried a message before. */
|
|
12
|
+
readonly reused?: boolean;
|
|
11
13
|
}
|
|
14
|
+
/** What `used` keeps of a session's connection: `reused` when the sender said. */
|
|
15
|
+
export declare const reusedOf: (a: Attempt) => Pick<Used, "reused">;
|
|
12
16
|
/** One session, by `route` (the domain's own when none is given): each recipient's outcome, whatever happened. */
|
|
13
17
|
export declare function session(ctx: DeliveryContext, item: QueueItem, message: Uint8Array, domain: string, group: readonly string[], route: Route, override?: Route): Promise<Attempt>;
|
|
14
18
|
//# sourceMappingURL=session.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/queue/session.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC/C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAyCvC,wEAAwE;AACxE,MAAM,MAAM,IAAI,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/queue/session.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC/C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAyCvC,wEAAwE;AACxE,MAAM,MAAM,IAAI,GAAG,IAAI,CACtB,cAAc,EACd,OAAO,GAAG,UAAU,GAAG,SAAS,GAAG,QAAQ,CAC3C,CAAC;AAEF,mEAAmE;AACnE,MAAM,WAAW,OAAO;IACvB,QAAQ,CAAC,OAAO,EAAE,eAAe,EAAE,CAAC;IACpC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,4EAA4E;IAC5E,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,kFAAkF;AAClF,eAAO,MAAM,QAAQ,GAAI,GAAG,OAAO,KAAG,IAAI,CAAC,IAAI,EAAE,QAAQ,CACN,CAAC;AAEpD,kHAAkH;AAClH,wBAAsB,OAAO,CAC5B,GAAG,EAAE,eAAe,EACpB,IAAI,EAAE,SAAS,EACf,OAAO,EAAE,UAAU,EACnB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,KAAK,EAAE,KAAK,EACZ,QAAQ,CAAC,EAAE,KAAK,GACd,OAAO,CAAC,OAAO,CAAC,CAyBlB"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import type { QueueOptions, Route
|
|
1
|
+
import type { QueueOptions, Route } from '../options';
|
|
2
2
|
import { type DsnSettings } from './dsn';
|
|
3
3
|
import { type LimitSettings, type RetrySettings } from './limits';
|
|
4
|
+
import { type SenderSettings } from './sender';
|
|
4
5
|
export type { DsnSettings, LimitSettings, RetrySettings };
|
|
5
6
|
/** Every option checked, with its default. */
|
|
6
7
|
export interface Settings {
|
|
@@ -17,7 +18,9 @@ export interface Settings {
|
|
|
17
18
|
readonly pollInterval: number;
|
|
18
19
|
readonly owner: string;
|
|
19
20
|
readonly now: () => number;
|
|
20
|
-
readonly send:
|
|
21
|
+
readonly send: SenderSettings['send'];
|
|
22
|
+
/** Closes the queue's own connection pool, if it has one. */
|
|
23
|
+
readonly close: SenderSettings['close'];
|
|
21
24
|
readonly random: () => number;
|
|
22
25
|
}
|
|
23
26
|
/** The options, checked, with their defaults; `INVALID` names the first wrong one. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/queue/settings/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/queue/settings/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACtD,OAAO,EAAE,KAAK,WAAW,EAAS,MAAM,OAAO,CAAC;AAChD,OAAO,EACN,KAAK,aAAa,EAElB,KAAK,aAAa,EAElB,MAAM,UAAU,CAAC;AAGlB,OAAO,EAAE,KAAK,cAAc,EAAY,MAAM,UAAU,CAAC;AAGzD,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,aAAa,EAAE,CAAC;AAE1D,8CAA8C;AAC9C,MAAM,WAAW,QAAQ;IACxB,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,0CAA0C;IAC1C,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAC5C,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAC/B,QAAQ,CAAC,GAAG,EAAE,WAAW,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACtC,6DAA6D;IAC7D,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,CAAC,CAAC;IACxC,QAAQ,CAAC,MAAM,EAAE,MAAM,MAAM,CAAC;CAC9B;AAKD,sFAAsF;AACtF,wBAAgB,UAAU,CAAC,OAAO,EAAE,YAAY,GAAG,QAAQ,CAoD1D"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { QueueOptions, ReuseOptions, Sender } from '../options';
|
|
2
|
+
/** The sender the queue delivers with, and what stops it. */
|
|
3
|
+
export interface SenderSettings {
|
|
4
|
+
readonly send: Sender;
|
|
5
|
+
/** Closes the pool the queue owns, once its deliveries end; nothing when the sender is not the queue's. */
|
|
6
|
+
readonly close: () => Promise<void>;
|
|
7
|
+
}
|
|
8
|
+
/** `reuse` shaped: the limits given (the pool owns their defaults and checks them), or `false` for one connection per send. */
|
|
9
|
+
export declare function reuseOf(options: QueueOptions): ReuseOptions | false;
|
|
10
|
+
/**
|
|
11
|
+
* Your `send`, untouched; else a pool the queue owns (made on first use,
|
|
12
|
+
* and again after a `close()`, since `stop()` then `start()` is allowed);
|
|
13
|
+
* else `sendMail` with `reuse: false`.
|
|
14
|
+
*/
|
|
15
|
+
export declare function senderOf(options: QueueOptions): SenderSettings;
|
|
16
|
+
//# sourceMappingURL=sender.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sender.d.ts","sourceRoot":"","sources":["../../../src/queue/settings/sender.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAErE,6DAA6D;AAC7D,MAAM,WAAW,cAAc;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,2GAA2G;IAC3G,QAAQ,CAAC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACpC;AAED,+HAA+H;AAC/H,wBAAgB,OAAO,CAAC,OAAO,EAAE,YAAY,GAAG,YAAY,GAAG,KAAK,CAcnE;AAgBD;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,YAAY,GAAG,cAAc,CAiB9D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../../src/queue/worker.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C;;;;;GAKG;AACH,qBAAa,MAAM;;gBAaN,GAAG,EAAE,aAAa;IAsD9B;;;;OAIG;IACG,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IAgCnC,4FAA4F;IAC5F,IAAI,IAAI,IAAI;IAKZ,KAAK,IAAI,IAAI;IAqCb;;;;OAIG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../../src/queue/worker.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C;;;;;GAKG;AACH,qBAAa,MAAM;;gBAaN,GAAG,EAAE,aAAa;IAsD9B;;;;OAIG;IACG,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IAgCnC,4FAA4F;IAC5F,IAAI,IAAI,IAAI;IAKZ,KAAK,IAAI,IAAI;IAqCb;;;;OAIG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAiB3B"}
|
package/docs/guide.md
CHANGED
|
@@ -260,6 +260,39 @@ createQueue({
|
|
|
260
260
|
|
|
261
261
|
No resolver is needed when no route is `'mx'`.
|
|
262
262
|
|
|
263
|
+
### Reusing connections
|
|
264
|
+
|
|
265
|
+
By default the queue sends through a pool of connections it owns: a
|
|
266
|
+
session to a server the queue already has an idle connection to (same
|
|
267
|
+
host, address, port, EHLO name, TLS and credentials) sends its message
|
|
268
|
+
over it, after an `RSET`, instead of opening a connection, a TLS
|
|
269
|
+
handshake and an `AUTH` again. A connection carries 100 messages and
|
|
270
|
+
waits 5 seconds idle, then closes. A `delivered`, `deferred` or `failed`
|
|
271
|
+
event carries `reused: true` when the recipient's last session went over a
|
|
272
|
+
connection that had carried a message before, `false` when it opened one.
|
|
273
|
+
|
|
274
|
+
```ts
|
|
275
|
+
createQueue({
|
|
276
|
+
store,
|
|
277
|
+
hostname: 'mail.example.net',
|
|
278
|
+
resolver,
|
|
279
|
+
reuse: { maxMessages: 50, idleSeconds: 10 }, // or the defaults, or `false`
|
|
280
|
+
});
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
`reuse: false` opens one connection per session, as `sendMail` does. A
|
|
284
|
+
`send` of your own is called as given: the queue never wraps it in a pool,
|
|
285
|
+
and `reuse` does nothing with it, though `createQueue` still checks it.
|
|
286
|
+
`reused` is on the events only if your `send` returns it.
|
|
287
|
+
|
|
288
|
+
`stop()` closes the pool once the deliveries under way end, so no socket
|
|
289
|
+
keeps the process alive; `start()` after it makes a new one. A connection
|
|
290
|
+
that went stale while idle (the server closed it) is never a reason to
|
|
291
|
+
fall back to a smarthost: the pool opens a new one to the same server.
|
|
292
|
+
`@bumail/server` builds its own pool for its `send` and closes it after
|
|
293
|
+
`queue.stop()`. The rules of [Falling back](#falling-back-to-a-smarthost) are
|
|
294
|
+
the same with or without the pool.
|
|
295
|
+
|
|
263
296
|
### Timeouts
|
|
264
297
|
|
|
265
298
|
`timeouts` and `deadline` pass to `sendMail`: each step's timeout in
|
|
@@ -1046,8 +1079,90 @@ codes, and keeps its promises:
|
|
|
1046
1079
|
The queue never gives a store such text: it cleans every reply.
|
|
1047
1080
|
|
|
1048
1081
|
The contract's specs, `describeQueueStore`, which every store here runs,
|
|
1049
|
-
are
|
|
1050
|
-
|
|
1082
|
+
are exported as `@bumail/queue/conformance`: see
|
|
1083
|
+
[Holding your own store to the contract](#holding-your-own-store-to-the-contract).
|
|
1084
|
+
|
|
1085
|
+
## Holding your own store to the contract
|
|
1086
|
+
|
|
1087
|
+
A store you write (over a file, a database, a service) is only a
|
|
1088
|
+
`QueueStore` if it answers the contract above to the letter, in the cases
|
|
1089
|
+
nobody thinks of: a lease that expired, a DSN that fails the checks, a
|
|
1090
|
+
second process claiming at the same time. `describeQueueStore` is the
|
|
1091
|
+
suite the memory, SQLite, PostgreSQL and Redis stores run; call
|
|
1092
|
+
it from a spec of yours and it registers them.
|
|
1093
|
+
|
|
1094
|
+
**It needs Bun.** The suite imports `bun:test`, so the spec runs with
|
|
1095
|
+
`bun test`, not with Node, Vitest or Jest. It is a development
|
|
1096
|
+
dependency: install `@bumail/queue` and write the spec.
|
|
1097
|
+
|
|
1098
|
+
```sh
|
|
1099
|
+
bun add -d @bumail/queue
|
|
1100
|
+
```
|
|
1101
|
+
|
|
1102
|
+
```ts
|
|
1103
|
+
// my-store.spec.ts
|
|
1104
|
+
import { describeQueueStore } from '@bumail/queue/conformance';
|
|
1105
|
+
import { MyQueueStore } from './my-store';
|
|
1106
|
+
|
|
1107
|
+
describeQueueStore('MyQueueStore', {
|
|
1108
|
+
// a new store, empty: called once per test
|
|
1109
|
+
create: () => MyQueueStore.open({ url: process.env.MY_STORE_URL }),
|
|
1110
|
+
// another handle on the same queue, as a second connection or process
|
|
1111
|
+
share: (store) => (store as MyQueueStore).connectAgain(),
|
|
1112
|
+
// closes a store `create` made, after the test that used it
|
|
1113
|
+
dispose: (store) => (store as MyQueueStore).close(),
|
|
1114
|
+
});
|
|
1115
|
+
```
|
|
1116
|
+
|
|
1117
|
+
```sh
|
|
1118
|
+
bun test my-store.spec.ts
|
|
1119
|
+
```
|
|
1120
|
+
|
|
1121
|
+
A spec project typechecked with `tsc` needs `@types/bun` (for `bun:test`), as
|
|
1122
|
+
the example's `devDependencies` have it.
|
|
1123
|
+
|
|
1124
|
+
[`examples/custom-store`](https://github.com/softistx/bumail/tree/develop/examples/custom-store)
|
|
1125
|
+
in the repository holds a complete one, a store over the memory store with its
|
|
1126
|
+
spec, that passes.
|
|
1127
|
+
|
|
1128
|
+
### What it covers
|
|
1129
|
+
|
|
1130
|
+
| group | what is held |
|
|
1131
|
+
| --- | --- |
|
|
1132
|
+
| `items` | `add` keeps the envelope, every recipient `pending`, due at once; the null sender; `readMessage` and every item are copies; an unknown id, or one no store could hold, is `undefined`; `list` order and paging; `cancel`; `maxItems` and `QUEUE_FULL`; what is not an item is `INVALID`; the DSN parameters (`ret`, `envid`, `notify`, `orcpt`) and their limits |
|
|
1133
|
+
| `claims and leases` | `claim` takes the earliest due, then the oldest, and only what is due; an expired lease is claimed again and its old owner has lost it; `renew`; `reschedule` with and without an owner; a bad request is `INVALID` |
|
|
1134
|
+
| `outcomes` | `complete` records each recipient, the schedule and lets go of the lease; a finished item is dropped with its message; text with a NUL or a lone surrogate is refused; a final state never changes; the DSNs stored in the same step (new ids, in order, none on a lost lease, all refused when one is bad); `mayHaveReachedMx` and `mayHaveReachedFallback` recorded and kept |
|
|
1135
|
+
| `several workers` | many claimers on one queue deliver every item once; a crashed worker's items are claimed again when its leases expire |
|
|
1136
|
+
|
|
1137
|
+
### `share`: a second handle
|
|
1138
|
+
|
|
1139
|
+
The two `several workers` tests need `share`, another handle on **the
|
|
1140
|
+
same queue**: a second connection to the same database, as a second
|
|
1141
|
+
process would open. Without it they are registered as skipped, named
|
|
1142
|
+
`… (skipped: harness has no share)`, because one handle cannot show that
|
|
1143
|
+
a claim is atomic across handles.
|
|
1144
|
+
|
|
1145
|
+
A store that lives in one process, such as an in-memory one, may return a
|
|
1146
|
+
second object over the same data, as the example does. A **networked**
|
|
1147
|
+
store (PostgreSQL, Redis, any server) should pass a real second
|
|
1148
|
+
connection: that is where two workers race, and where a claim that reads
|
|
1149
|
+
then writes loses. Passing none for a store like that leaves the one
|
|
1150
|
+
property that matters unproved.
|
|
1151
|
+
|
|
1152
|
+
### `dispose`
|
|
1153
|
+
|
|
1154
|
+
`dispose(store)` runs after every test, for each store `create` made in
|
|
1155
|
+
that test, once the test is over (pass or fail). Use it to close a
|
|
1156
|
+
connection or remove a file. It may be async.
|
|
1157
|
+
|
|
1158
|
+
- Every created store is disposed, even when the disposal of another
|
|
1159
|
+
one fails.
|
|
1160
|
+
- One failure is rethrown as it is. Several in one test are thrown
|
|
1161
|
+
together as an `AggregateError` (`several stores failed to dispose`),
|
|
1162
|
+
each reason in its `errors`.
|
|
1163
|
+
- Handles returned by `share` are **not** passed to `dispose`: the
|
|
1164
|
+
harness closes them, for instance in the same `dispose`, from the store
|
|
1165
|
+
they were made from.
|
|
1051
1166
|
|
|
1052
1167
|
## Options
|
|
1053
1168
|
|
|
@@ -1077,5 +1192,6 @@ them yet.
|
|
|
1077
1192
|
| `pollInterval` | `number`, to 2147483647 | 5000 | ms between passes of `start()` |
|
|
1078
1193
|
| `owner` | `string` | a random UUID | this worker's name on its leases |
|
|
1079
1194
|
| `clock` | `{ now(): number }` | `Date.now` | the time |
|
|
1080
|
-
| `
|
|
1195
|
+
| `reuse` | `false \| { maxMessages?, idleSeconds? }` | `{ maxMessages: 100, idleSeconds: 5 }` | connection pool the queue owns and `stop()` closes; `false`: one connection per session; see [Reusing connections](#reusing-connections) |
|
|
1196
|
+
| `send` | `Sender` | the queue's pool, or `sendMail` with `reuse: false` | delivers one session; a custom one should return `dsnOffered` (leave it out and no `relayed` DSN is ever sent) |
|
|
1081
1197
|
| `random` | `() => number` | `Math.random` | the jitter |
|
package/docs/roadmap.md
CHANGED
|
@@ -6,7 +6,7 @@ only number on it.
|
|
|
6
6
|
|
|
7
7
|
## Now
|
|
8
8
|
|
|
9
|
-
Nothing under way.
|
|
9
|
+
Nothing is under way.
|
|
10
10
|
|
|
11
11
|
## Next
|
|
12
12
|
|
|
@@ -15,14 +15,11 @@ Nothing under way.
|
|
|
15
15
|
certificate checked against the policy's MX names, and the reports.
|
|
16
16
|
- **DANE (RFC 7672)** — TLSA records checked for MX hosts, once a
|
|
17
17
|
resolver that validates DNSSEC can be given to the queue.
|
|
18
|
-
- **One session for several messages** — the queue hands several items
|
|
19
|
-
for one domain to one SMTP session, once `@bumail/smtp`'s client reuses
|
|
20
|
-
connections.
|
|
21
|
-
- **The contract's specs, exported**, so a store written outside this
|
|
22
|
-
package can hold itself to them.
|
|
23
18
|
|
|
24
19
|
## Later
|
|
25
20
|
|
|
21
|
+
- **A suite that is not tied to `bun:test`** — the contract's specs run under
|
|
22
|
+
any test runner, for a store written where Bun is not the runner.
|
|
26
23
|
- **REQUIRETLS (RFC 8689)** — a message that asks for TLS all the way is
|
|
27
24
|
never sent in clear, and fails rather than downgrade.
|
|
28
25
|
- **Retries per recipient** — a schedule of its own for each recipient,
|
|
@@ -46,6 +43,23 @@ Nothing under way.
|
|
|
46
43
|
|
|
47
44
|
## Shipped
|
|
48
45
|
|
|
46
|
+
### 0.13.0
|
|
47
|
+
|
|
48
|
+
- **One session for several messages** — the queue delivers several
|
|
49
|
+
messages for one MX over one connection, using `@bumail/smtp`'s pool of
|
|
50
|
+
reusable connections. On by default (100 messages per connection, idle 5
|
|
51
|
+
seconds); `reuse: false` turns it off, and a `send` of your own is never
|
|
52
|
+
wrapped. `stop()` closes the pool, and the events may carry `reused`. The
|
|
53
|
+
`QueueStore` contract does not change.
|
|
54
|
+
|
|
55
|
+
### 0.12.0
|
|
56
|
+
|
|
57
|
+
- **The contract's specs, exported** — `@bumail/queue/conformance` exports
|
|
58
|
+
`describeQueueStore(name, { create, share?, dispose? })`, run under
|
|
59
|
+
`bun test`, so a queue store written outside this package runs the same
|
|
60
|
+
contract suite as the built-in ones; a capability a store lacks shows as a
|
|
61
|
+
skipped test with its reason. Additive.
|
|
62
|
+
|
|
49
63
|
### 0.11.0
|
|
50
64
|
|
|
51
65
|
- **A DSN recorded in the same step as the outcome** — the failure, relayed
|
package/docs/troubleshooting.md
CHANGED
|
@@ -28,6 +28,9 @@ parts shown as … vary.
|
|
|
28
28
|
- [`QueueError: timeouts.… must be a number of seconds above 0 and at most 2147483, not …`](#queueerror-timeouts-must-be-a-number-of-seconds-above-0-and-at-most-2147483-not-)
|
|
29
29
|
- [`QueueError: store must be a QueueStore, such as MemoryQueueStore`](#queueerror-store-must-be-a-queuestore-such-as-memoryqueuestore)
|
|
30
30
|
- [`QueueError: … must be an integer of at least …, not …`](#queueerror--must-be-an-integer-of-at-least--not-)
|
|
31
|
+
- [`QueueError: reuse must be false or an object of limits, not …`](#queueerror-reuse-must-be-false-or-an-object-of-limits-not-)
|
|
32
|
+
- [`QueueError: reuse.idleSeconds must be a number of seconds above 0 and at most 2147483, not …`](#queueerror-reuseidleseconds-must-be-a-number-of-seconds-above-0-and-at-most-2147483-not-)
|
|
33
|
+
- [`QueueError: reuse.maxMessages must be an integer of at least 1, not …`](#queueerror-reusemaxmessages-must-be-an-integer-of-at-least-1-not-)
|
|
31
34
|
- [`QueueError: dsn.returnContent must be 'headers' or 'full', not …`](#queueerror-dsnreturncontent-must-be-headers-or-full-not-)
|
|
32
35
|
- [`QueueError: createQueue() takes an options object`](#queueerror-createqueue-takes-an-options-object)
|
|
33
36
|
- [`QueueError: owner must be a non-empty string`](#queueerror-owner-must-be-a-non-empty-string)
|
|
@@ -89,6 +92,11 @@ parts shown as … vary.
|
|
|
89
92
|
- [`QueueError: reply.host must be a string`](#queueerror-replyhost-must-be-a-string)
|
|
90
93
|
- [`QueueError: … holds a NUL or a lone surrogate, which a store cannot keep`](#queueerror--holds-a-nul-or-a-lone-surrogate-which-a-store-cannot-keep)
|
|
91
94
|
|
|
95
|
+
**A store's spec** (`describeQueueStore`)
|
|
96
|
+
|
|
97
|
+
- [`AggregateError: several stores failed to dispose`](#aggregateerror-several-stores-failed-to-dispose)
|
|
98
|
+
- [`… (skipped: harness has no share)` in the test names](#-skipped-harness-has-no-share-in-the-test-names)
|
|
99
|
+
|
|
92
100
|
**Delivery**
|
|
93
101
|
|
|
94
102
|
- [A recipient stays `deferred` with `4.4.1` or `4.4.2`](#a-recipient-stays-deferred-with-441-or-442)
|
|
@@ -297,6 +305,29 @@ or `… must be a number from … to …, not …`. A number option out of its r
|
|
|
297
305
|
1), `dsn.delayAfter`, `limits.*` (`limits.maxReplyText` from 64 to
|
|
298
306
|
900). Times are milliseconds.
|
|
299
307
|
|
|
308
|
+
### `QueueError: reuse must be false or an object of limits, not …`
|
|
309
|
+
|
|
310
|
+
**Code:** `INVALID`. `reuse` was `true`, `null` or another value. Give
|
|
311
|
+
`false` for one connection per session, an object of limits, or leave it out
|
|
312
|
+
for the defaults.
|
|
313
|
+
|
|
314
|
+
```ts
|
|
315
|
+
createQueue({ store, hostname, resolver, reuse: { maxMessages: 50 } });
|
|
316
|
+
createQueue({ store, hostname, resolver, reuse: false });
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
### `QueueError: reuse.idleSeconds must be a number of seconds above 0 and at most 2147483, not …`
|
|
320
|
+
|
|
321
|
+
**Code:** `INVALID`. `reuse.idleSeconds` is in seconds, not milliseconds:
|
|
322
|
+
`5`, not `5000`. `reuse.maxMessages` has its own entry below.
|
|
323
|
+
|
|
324
|
+
### `QueueError: reuse.maxMessages must be an integer of at least 1, not …`
|
|
325
|
+
|
|
326
|
+
**Code:** `INVALID`. `reuse.maxMessages` is `0`, negative, fractional or not a
|
|
327
|
+
number. The pool owns the limits and checks them when `createQueue` runs;
|
|
328
|
+
the message is the pool's, prefixed with `reuse.`. Pass an integer of at
|
|
329
|
+
least 1, or leave it out for the default (100).
|
|
330
|
+
|
|
300
331
|
### `QueueError: dsn.returnContent must be 'headers' or 'full', not …`
|
|
301
332
|
|
|
302
333
|
**Code:** `INVALID`.
|
|
@@ -545,6 +576,43 @@ it.
|
|
|
545
576
|
default. The error from a transaction of your own on the same client is
|
|
546
577
|
yours to retry.
|
|
547
578
|
|
|
579
|
+
## Your own store's spec
|
|
580
|
+
|
|
581
|
+
### `AggregateError: several stores failed to dispose`
|
|
582
|
+
|
|
583
|
+
`describeQueueStore`, after a test. The test created more than one store
|
|
584
|
+
(a spec that calls `create` again, as the several-workers tests do) and
|
|
585
|
+
the `dispose` of more than one of them threw. The suite disposes every
|
|
586
|
+
store it created, collects the failures and throws them together; each
|
|
587
|
+
reason is in `error.errors`. A single failure is thrown as it is, not
|
|
588
|
+
wrapped.
|
|
589
|
+
|
|
590
|
+
**Fix:** read `error.errors`; each entry is one store's failure. The suite
|
|
591
|
+
calls `dispose` once per created store, so the causes are a store's own
|
|
592
|
+
`close` failing (each entry says why), or a `create` that hands back a
|
|
593
|
+
shared object, so that each test's `dispose` closes the same thing. Have
|
|
594
|
+
`create` return a fresh store each call. Handles from `share` are not passed
|
|
595
|
+
to `dispose`; close them in the harness.
|
|
596
|
+
|
|
597
|
+
```ts
|
|
598
|
+
create: () => new MyQueueStore(freshPath()), // a new store each call, never a shared one
|
|
599
|
+
```
|
|
600
|
+
|
|
601
|
+
### `… (skipped: harness has no share)` in the test names
|
|
602
|
+
|
|
603
|
+
`describeQueueStore`. The harness passed no `share`, so the two tests of
|
|
604
|
+
"several workers" (many claimers race, a crashed worker's items) are
|
|
605
|
+
registered as skipped. This is not a failure, but the atomicity of a claim
|
|
606
|
+
across handles is then unproved.
|
|
607
|
+
|
|
608
|
+
**Fix:** pass `share`, which returns another handle on the same queue (a
|
|
609
|
+
second connection to the same database), and give a networked store a real
|
|
610
|
+
second connection:
|
|
611
|
+
|
|
612
|
+
```ts
|
|
613
|
+
share: (store) => (store as MyQueueStore).connectAgain(),
|
|
614
|
+
```
|
|
615
|
+
|
|
548
616
|
## The `bun:sqlite` store
|
|
549
617
|
|
|
550
618
|
### `QueueError: A SQLite queue store needs a directory`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bumail/queue",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"description": "The outbound mail queue of a mail server: every recipient's state, retries with back-off, delivery status notifications (RFC 3464), leases for several workers, and a memory, a bun:sqlite, a PostgreSQL (Bun.sql) and a Redis (Bun.redis) store, delivering through @bumail/smtp/client",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -39,6 +39,11 @@
|
|
|
39
39
|
"import": "./dist/redis/index.js",
|
|
40
40
|
"default": "./dist/redis/index.js"
|
|
41
41
|
},
|
|
42
|
+
"./conformance": {
|
|
43
|
+
"types": "./dist/conformance/index.d.ts",
|
|
44
|
+
"import": "./dist/conformance/index.js",
|
|
45
|
+
"default": "./dist/conformance/index.js"
|
|
46
|
+
},
|
|
42
47
|
"./package.json": "./package.json"
|
|
43
48
|
},
|
|
44
49
|
"repository": {
|
|
@@ -61,18 +66,19 @@
|
|
|
61
66
|
"src/memory/index.ts",
|
|
62
67
|
"src/sqlite/index.ts",
|
|
63
68
|
"src/postgres/index.ts",
|
|
64
|
-
"src/redis/index.ts"
|
|
69
|
+
"src/redis/index.ts",
|
|
70
|
+
"src/conformance/index.ts"
|
|
65
71
|
]
|
|
66
72
|
},
|
|
67
73
|
"devDependencies": {
|
|
68
74
|
"@bumail/dns": "^0.2.2",
|
|
69
75
|
"@bumail/mime": "^0.2.0",
|
|
70
|
-
"@bumail/smtp": "^0.
|
|
76
|
+
"@bumail/smtp": "^0.12.0",
|
|
71
77
|
"@types/bun": "^1.4.2"
|
|
72
78
|
},
|
|
73
79
|
"peerDependencies": {
|
|
74
80
|
"@bumail/mime": "^0.2.0",
|
|
75
|
-
"@bumail/smtp": "^0.
|
|
81
|
+
"@bumail/smtp": "^0.12.0",
|
|
76
82
|
"typescript": "^6.0.3 || ^7.0.0"
|
|
77
83
|
},
|
|
78
84
|
"peerDependenciesMeta": {
|