@owlmeans/queue 0.1.18-rc.11 → 0.1.18-rc.13
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 +5 -4
- package/agent-meta/manifest.json +2 -2
- package/agent-meta/skills/queue/SKILL.md +30 -10
- package/build/bridge.d.ts +4 -2
- package/build/bridge.d.ts.map +1 -1
- package/build/bridge.js +14 -3
- package/build/bridge.js.map +1 -1
- package/build/errors.d.ts +1 -1
- package/build/errors.js +1 -1
- package/build/index.d.ts +1 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js +1 -0
- package/build/index.js.map +1 -1
- package/build/protocol.d.ts +11 -0
- package/build/protocol.d.ts.map +1 -0
- package/build/protocol.js +59 -0
- package/build/protocol.js.map +1 -0
- package/build/types.d.ts +8 -0
- package/build/types.d.ts.map +1 -1
- package/build/worker.d.ts +1 -1
- package/build/worker.js +1 -1
- package/package.json +10 -9
- package/src/bridge.ts +14 -4
- package/src/errors.ts +1 -1
- package/src/index.ts +1 -0
- package/src/protocol.ts +81 -0
- package/src/types.ts +9 -0
- package/src/worker.ts +1 -1
- package/tests/protocol.spec.ts +58 -0
package/README.md
CHANGED
|
@@ -44,16 +44,17 @@ same binary run as a producer in one deployment and a worker in another.
|
|
|
44
44
|
## Declaring a queued entrypoint
|
|
45
45
|
|
|
46
46
|
```typescript
|
|
47
|
+
import { contract, protocol, typed } from '@owlmeans/entrypoint'
|
|
47
48
|
import { job } from '@owlmeans/route'
|
|
48
49
|
|
|
49
|
-
|
|
50
|
+
protocol(
|
|
50
51
|
route(agent.story.develop, '/:id/develop',
|
|
51
52
|
job({ parent: agent.story.base, service: AGENT, queue: AGENT_WORK, timeout: 30_000 })),
|
|
52
|
-
|
|
53
|
+
contract.request({ params: typed<StoryParams>(StoryParamsSchema) }, typed()),
|
|
53
54
|
)
|
|
54
55
|
```
|
|
55
56
|
|
|
56
|
-
It is served
|
|
57
|
+
It is served by binding its shared job protocol and called with `call()` like any backend entrypoint. Add
|
|
57
58
|
`reply: false` to return as soon as the job is accepted — the call resolves `Accepted` with
|
|
58
59
|
`{ id, queue }`, which is what a long pipeline wants.
|
|
59
60
|
|
|
@@ -132,7 +133,7 @@ This package ships embedded agent skills under `agent-meta/`. After installing y
|
|
|
132
133
|
your project's skill store (`.agents/skills/`):
|
|
133
134
|
|
|
134
135
|
```sh
|
|
135
|
-
npx @owlmeans/agent-skills@^0.1.18-rc.
|
|
136
|
+
npx @owlmeans/agent-skills@^0.1.18-rc.16
|
|
136
137
|
```
|
|
137
138
|
|
|
138
139
|
The embedded files are version-matched to this package release. Do not edit them
|
package/agent-meta/manifest.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 2,
|
|
3
3
|
"package": "@owlmeans/queue",
|
|
4
|
-
"version": "0.1.18-rc.
|
|
5
|
-
"generatedAt": "2026-09-
|
|
4
|
+
"version": "0.1.18-rc.13",
|
|
5
|
+
"generatedAt": "2026-09-12T12:32:46.383Z",
|
|
6
6
|
"canonicalRepo": "https://github.com/owlmeans/common",
|
|
7
7
|
"entries": [
|
|
8
8
|
{
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: queue
|
|
3
|
-
description: How to use @owlmeans/queue — job queues as resources,
|
|
3
|
+
description: How to use @owlmeans/queue — protocol-object enqueue/wait, job queues as resources, QUEUE declarations, producer/consumer split, single-flight job ids, lifecycle hooks, and processor rules. Auto-invoked when importing queue types or declaring a job protocol.
|
|
4
4
|
user-invocable: false
|
|
5
5
|
---
|
|
6
6
|
<!-- AUTO-GENERATED — do not edit. Regenerate via sync-agent-meta. -->
|
|
@@ -8,7 +8,7 @@ user-invocable: false
|
|
|
8
8
|
# @owlmeans/queue
|
|
9
9
|
|
|
10
10
|
**Layer:** Infra
|
|
11
|
-
**Install:** `"@owlmeans/queue": "^0.1.18-rc.
|
|
11
|
+
**Install:** `"@owlmeans/queue": "^0.1.18-rc.13"` in `dependencies`
|
|
12
12
|
|
|
13
13
|
Contracts only. It carries no broker code — a driver package (`@owlmeans/redis-queue`) implements
|
|
14
14
|
them. Depend on this one from a shared contract package; depend on the driver only where the
|
|
@@ -16,9 +16,11 @@ application wires itself up.
|
|
|
16
16
|
|
|
17
17
|
## The one idea
|
|
18
18
|
|
|
19
|
-
A queued call is an
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
A queued call is an immutable entrypoint protocol whose route names `RouteProtocols.QUEUE`.
|
|
20
|
+
Ordinary calls use `ctx.entrypoint(protocol).call(request)`. Code that needs broker options or a
|
|
21
|
+
job handle uses `enqueueProtocol(ctx, protocol, request, options)` and
|
|
22
|
+
`waitForProtocol(ctx, protocol, job)`. Both derive queue and job name from the protocol object and
|
|
23
|
+
preserve its exact request/reply pair; raw strings and non-QUEUE declarations are rejected.
|
|
22
24
|
|
|
23
25
|
That is what makes it worth having: moving a service-to-service call onto the broker is a change
|
|
24
26
|
to a declaration, not to the places that call it, and the broker holds the work across a restart of
|
|
@@ -30,7 +32,7 @@ Queues and the jobs they accept live in the SHARED backend package, so producers
|
|
|
30
32
|
read one list:
|
|
31
33
|
|
|
32
34
|
```typescript
|
|
33
|
-
declareQueue(cfg, AGENT_WORK, [
|
|
35
|
+
declareQueue(cfg, AGENT_WORK, [story.develop.alias], {
|
|
34
36
|
worker: { concurrency: 3, lockDuration: 60_000 }
|
|
35
37
|
})
|
|
36
38
|
```
|
|
@@ -48,16 +50,32 @@ listenQueues(cfg, AGENT_WORK, AGENT_OPS) // absent ⇒ producer only
|
|
|
48
50
|
Keep them apart. A declaration is an address; `listen` is a deployment fact. If a worker bound
|
|
49
51
|
whatever it could serve, every deployment of the same binary would consume everything it imports.
|
|
50
52
|
|
|
51
|
-
A queued entrypoint is
|
|
53
|
+
A queued entrypoint is an immutable protocol with `job()` in place of `backend()`:
|
|
52
54
|
|
|
53
55
|
```typescript
|
|
54
|
-
|
|
56
|
+
protocol(
|
|
55
57
|
route(agent.story.develop, '/:id/develop',
|
|
56
58
|
job({ parent: agent.story.base, service: AGENT, queue: AGENT_WORK, timeout: 30_000 })),
|
|
57
|
-
|
|
59
|
+
contract.request({ params: typed<StoryParams>(StoryParamsSchema) }, typed()),
|
|
58
60
|
)
|
|
59
61
|
```
|
|
60
62
|
|
|
63
|
+
The alias appears in `declareQueue(...jobs)` only because the broker is a string-keyed adapter.
|
|
64
|
+
Application producers and handlers keep the protocol object.
|
|
65
|
+
|
|
66
|
+
When an admission record owns single flight, select the job id atomically first, then enqueue it:
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
const queued = await enqueueProtocol(context, tokenBalance.reconcile, {
|
|
70
|
+
body: { projectionId },
|
|
71
|
+
}, { id: claimId, delay: 250, attempts: 3, backoff: { type: 'exponential', delay: 250 } })
|
|
72
|
+
const result = await waitForProtocol(context, tokenBalance.reconcile, queued)
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Per-call `id`, delay, attempts, backoff and retention belong here; putting them into an alias-based
|
|
76
|
+
helper forfeits protocol inference. `queueJobOf(request)` exposes `{ id, name, queue, attempt }` to
|
|
77
|
+
the rare protocol handler that must compare a broker job with its persisted claim.
|
|
78
|
+
|
|
61
79
|
`reply: false` makes it fire-and-forget: the call resolves `Accepted` with `{ id, queue }` as soon
|
|
62
80
|
as the BROKER has accepted the enqueue — before any worker has picked the job up, so the resolution
|
|
63
81
|
says the job exists and nothing about it having started. That is what a long pipeline wants; watch
|
|
@@ -162,6 +180,8 @@ listens to, grouped by queue, which is what a driver binds.
|
|
|
162
180
|
|
|
163
181
|
| Export | Description |
|
|
164
182
|
|--------|-------------|
|
|
183
|
+
| `enqueueProtocol` / `waitForProtocol` | Typed protocol-object enqueue and result wait; validates protocol kind and queue configuration. |
|
|
184
|
+
| `queueJobOf(request)` / `QueueJobMeta` | Explicit broker identity boundary for a protocol handler, including `touch()` for long work. |
|
|
165
185
|
| `declareQueue` / `listenQueues` | Configuration — what exists, and what this process consumes |
|
|
166
186
|
| `queueOf` / `queueOfJob` / `isListening` | Reading it back; `queueOf` throws `UnknownQueue` |
|
|
167
187
|
| `QueueConfig` / `QueueDeclaration` / `QueueWorkerOptions` / `JobOptions` | The configuration shapes |
|
|
@@ -193,5 +213,5 @@ listens to, grouped by queue, which is what a driver binds.
|
|
|
193
213
|
- `redis-queue` — the BullMQ driver; integration tests for queue behaviour live there
|
|
194
214
|
- `server-job` / `client-job` — exposing a queue's jobs to an application's UI (list, cancel,
|
|
195
215
|
progress over a socket), without touching the contracts here
|
|
196
|
-
- `entrypoint` — declarations,
|
|
216
|
+
- `entrypoint` — protocol declarations, bindings, and the transport lookup
|
|
197
217
|
- `resource` — the criteria and paging semantics `list` follows
|
package/build/bridge.d.ts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import type { AbstractRequest } from '@owlmeans/entrypoint';
|
|
2
2
|
import type { BasicContext } from '@owlmeans/context';
|
|
3
|
-
import type { Config, Context, JobContext, JobEnvelope, JobReply } from './types.js';
|
|
3
|
+
import type { Config, Context, JobContext, JobEnvelope, JobReply, QueueJobMeta } from './types.js';
|
|
4
4
|
/**
|
|
5
5
|
* Rebuild the request the producer described. A queued call is still a call: the same guards, the
|
|
6
6
|
* same filter, the same handler run against it — only the wire is different.
|
|
7
7
|
*/
|
|
8
|
-
export declare const requestOf: (envelope: JobEnvelope, path: string, context?: BasicContext<any
|
|
8
|
+
export declare const requestOf: (envelope: JobEnvelope, path: string, context?: BasicContext<any>, job?: QueueJobMeta) => AbstractRequest;
|
|
9
|
+
/** Read broker identity only where an entrypoint truly needs to bind work to an admission claim. */
|
|
10
|
+
export declare const queueJobOf: (request: unknown) => QueueJobMeta | null;
|
|
9
11
|
/**
|
|
10
12
|
* Freshness is judged from when the job was ENQUEUED, not from now.
|
|
11
13
|
*
|
package/build/bridge.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAkC,MAAM,sBAAsB,CAAA;AAC3F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAMrD,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAkC,MAAM,sBAAsB,CAAA;AAC3F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAMrD,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAGlG;;;GAGG;AACH,eAAO,MAAM,SAAS,aACV,WAAW,QAAQ,MAAM,YAAY,YAAY,CAAC,GAAG,CAAC,QAAQ,YAAY,KACnF,eAWD,CAAA;AAEF,oGAAoG;AACpG,eAAO,MAAM,UAAU,YAAa,OAAO,KAAG,YAAY,GAAG,IAK5D,CAAA;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,WAAW,aAAc,WAAW,QAAQ,MAAM,KAAG,IAQjE,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,SAAS,GAAU,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC,WAC3D,CAAC,OAAO,UAAU,CAAC,WAAW,CAAC,KACvC,OAAO,CAAC,QAAQ,CA2DlB,CAAA"}
|
package/build/bridge.js
CHANGED
|
@@ -7,7 +7,7 @@ import { EnvelopeExpired, JobNotServed } from './errors.js';
|
|
|
7
7
|
* Rebuild the request the producer described. A queued call is still a call: the same guards, the
|
|
8
8
|
* same filter, the same handler run against it — only the wire is different.
|
|
9
9
|
*/
|
|
10
|
-
export const requestOf = (envelope, path, context) => ({
|
|
10
|
+
export const requestOf = (envelope, path, context, job) => ({
|
|
11
11
|
alias: envelope.alias,
|
|
12
12
|
params: (envelope.params ?? {}),
|
|
13
13
|
body: envelope.body,
|
|
@@ -17,8 +17,17 @@ export const requestOf = (envelope, path, context) => ({
|
|
|
17
17
|
// Handlers reach their context through `original._ctx`, which the HTTP boundary sets on the raw
|
|
18
18
|
// Fastify request. There is no raw request here, so the shape is supplied deliberately — a
|
|
19
19
|
// handler must not have to know which transport delivered it.
|
|
20
|
-
original: context != null ? { _ctx: context } : undefined,
|
|
20
|
+
original: context != null || job != null ? { _ctx: context, _job: job } : undefined,
|
|
21
21
|
});
|
|
22
|
+
/** Read broker identity only where an entrypoint truly needs to bind work to an admission claim. */
|
|
23
|
+
export const queueJobOf = (request) => {
|
|
24
|
+
if (request == null || typeof request !== 'object' || !('original' in request))
|
|
25
|
+
return null;
|
|
26
|
+
const original = request.original;
|
|
27
|
+
if (original == null || typeof original !== 'object' || !('_job' in original))
|
|
28
|
+
return null;
|
|
29
|
+
return original._job ?? null;
|
|
30
|
+
};
|
|
22
31
|
/**
|
|
23
32
|
* Freshness is judged from when the job was ENQUEUED, not from now.
|
|
24
33
|
*
|
|
@@ -53,7 +62,9 @@ export const handleJob = async (context, job) => {
|
|
|
53
62
|
if (entrypoint.handle == null) {
|
|
54
63
|
throw new JobNotServed(envelope.alias);
|
|
55
64
|
}
|
|
56
|
-
const request = requestOf(envelope, entrypoint.path(), context
|
|
65
|
+
const request = requestOf(envelope, entrypoint.path(), context, {
|
|
66
|
+
id: job.id, name: job.name, queue: job.queue, attempt: job.attempt, touch: job.touch,
|
|
67
|
+
});
|
|
57
68
|
const response = provideResponse();
|
|
58
69
|
const guards = entrypoint.getGuards();
|
|
59
70
|
if (guards.length > 0) {
|
package/build/bridge.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bridge.js","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAEzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAEhD,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE3D;;;GAGG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CACvB,QAAqB,EAAE,IAAY,EAAE,OAA2B,
|
|
1
|
+
{"version":3,"file":"bridge.js","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"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"}
|
package/build/errors.d.ts
CHANGED
|
@@ -40,7 +40,7 @@ export declare class QueueNotListening extends QueueError {
|
|
|
40
40
|
}
|
|
41
41
|
/**
|
|
42
42
|
* The job named an entrypoint this process does not serve. Unlike a missing queue this is not a
|
|
43
|
-
* declaration problem: the alias exists, but nothing here
|
|
43
|
+
* declaration problem: the alias exists, but nothing here bound it, so the job was taken by a
|
|
44
44
|
* worker that cannot run it.
|
|
45
45
|
*/
|
|
46
46
|
export declare class JobNotServed extends QueueError {
|
package/build/errors.js
CHANGED
|
@@ -57,7 +57,7 @@ export class QueueNotListening extends QueueError {
|
|
|
57
57
|
}
|
|
58
58
|
/**
|
|
59
59
|
* The job named an entrypoint this process does not serve. Unlike a missing queue this is not a
|
|
60
|
-
* declaration problem: the alias exists, but nothing here
|
|
60
|
+
* declaration problem: the alias exists, but nothing here bound it, so the job was taken by a
|
|
61
61
|
* worker that cannot run it.
|
|
62
62
|
*/
|
|
63
63
|
export class JobNotServed extends QueueError {
|
package/build/index.d.ts
CHANGED
package/build/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,eAAe,CAAA"}
|
package/build/index.js
CHANGED
package/build/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,eAAe,CAAA"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { EntrypointProtocolDeclaration, RequestOf, ResponseOf } from '@owlmeans/entrypoint';
|
|
2
|
+
import type { Config, Context, JobEnvelope, JobOptions, JobRecord, JobReply, QueueAppend } from './types.js';
|
|
3
|
+
type QueueContext = Context<Config> & QueueAppend;
|
|
4
|
+
/** Enqueue an immutable QUEUE protocol while preserving its exact request and response types. */
|
|
5
|
+
export declare const enqueueProtocol: <Protocol extends EntrypointProtocolDeclaration>(context: QueueContext, declaration: Protocol, request: RequestOf<Protocol>, options?: JobOptions) => Promise<JobRecord<JobEnvelope, JobReply<ResponseOf<Protocol>>>>;
|
|
6
|
+
/** Wait for a protocol job and unwrap the typed entrypoint reply. */
|
|
7
|
+
export declare const waitForProtocol: <Protocol extends EntrypointProtocolDeclaration>(context: QueueContext, declaration: Protocol, job: string | JobRecord<JobEnvelope, JobReply<ResponseOf<Protocol>>>, options?: {
|
|
8
|
+
timeout?: number;
|
|
9
|
+
}) => Promise<ResponseOf<Protocol>>;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=protocol.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,6BAA6B,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AAMhG,OAAO,KAAK,EACV,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,EAC3E,MAAM,YAAY,CAAA;AAEnB,KAAK,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,WAAW,CAAA;AAuBjD,iGAAiG;AACjG,eAAO,MAAM,eAAe,GAAU,QAAQ,SAAS,6BAA6B,WACzE,YAAY,eACR,QAAQ,WACZ,SAAS,CAAC,QAAQ,CAAC,YAClB,UAAU,KACnB,OAAO,CAAC,SAAS,CAAC,WAAW,EAAE,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAkBhE,CAAA;AAED,qEAAqE;AACrE,eAAO,MAAM,eAAe,GAAU,QAAQ,SAAS,6BAA6B,WACzE,YAAY,eACR,QAAQ,OAChB,MAAM,GAAG,SAAS,CAAC,WAAW,EAAE,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,YAC1D;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,KAC7B,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,CAe9B,CAAA"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { isEntrypointProtocol } from '@owlmeans/entrypoint';
|
|
2
|
+
import { ResilientError } from '@owlmeans/error';
|
|
3
|
+
import { RouteProtocols } from '@owlmeans/route';
|
|
4
|
+
import { queueOf } from './config.js';
|
|
5
|
+
import { UnknownQueue } from './errors.js';
|
|
6
|
+
const queueFor = (context, declaration) => {
|
|
7
|
+
if (declaration == null || typeof declaration !== 'object' || !isEntrypointProtocol(declaration)) {
|
|
8
|
+
throw new UnknownQueue('protocol declaration required');
|
|
9
|
+
}
|
|
10
|
+
if (declaration.route.route.protocol !== RouteProtocols.QUEUE) {
|
|
11
|
+
throw new UnknownQueue(`${declaration.alias}: not a QUEUE protocol`);
|
|
12
|
+
}
|
|
13
|
+
const queue = declaration.route.route.queue;
|
|
14
|
+
if (queue == null) {
|
|
15
|
+
throw new UnknownQueue(`${declaration.alias}: route declares no queue`);
|
|
16
|
+
}
|
|
17
|
+
const configured = queueOf(context.cfg, queue);
|
|
18
|
+
if (!configured.jobs.includes(declaration.alias)) {
|
|
19
|
+
throw new UnknownQueue(`${queue}:${declaration.alias}`);
|
|
20
|
+
}
|
|
21
|
+
return { protocol: declaration, queue };
|
|
22
|
+
};
|
|
23
|
+
/** Enqueue an immutable QUEUE protocol while preserving its exact request and response types. */
|
|
24
|
+
export const enqueueProtocol = async (context, declaration, request, options) => {
|
|
25
|
+
const { protocol, queue } = queueFor(context, declaration);
|
|
26
|
+
const shaped = (request ?? {});
|
|
27
|
+
const envelope = {
|
|
28
|
+
alias: protocol.alias,
|
|
29
|
+
params: shaped.params,
|
|
30
|
+
body: shaped.body,
|
|
31
|
+
query: shaped.query,
|
|
32
|
+
headers: shaped.headers,
|
|
33
|
+
enqueuedAt: new Date().toISOString(),
|
|
34
|
+
};
|
|
35
|
+
return await context.jobs(queue).create({
|
|
36
|
+
queue,
|
|
37
|
+
name: protocol.alias,
|
|
38
|
+
data: envelope,
|
|
39
|
+
opts: options,
|
|
40
|
+
});
|
|
41
|
+
};
|
|
42
|
+
/** Wait for a protocol job and unwrap the typed entrypoint reply. */
|
|
43
|
+
export const waitForProtocol = async (context, declaration, job, options) => {
|
|
44
|
+
const { protocol, queue } = queueFor(context, declaration);
|
|
45
|
+
if (typeof job !== 'string' && (job.queue !== queue || job.name !== protocol.alias)) {
|
|
46
|
+
throw new UnknownQueue(`${job.queue}:${job.name}`);
|
|
47
|
+
}
|
|
48
|
+
const id = typeof job === 'string' ? job : job.id;
|
|
49
|
+
if (id == null) {
|
|
50
|
+
throw new UnknownQueue(`${queue}:${protocol.alias}: missing job id`);
|
|
51
|
+
}
|
|
52
|
+
const reply = await context.jobs(queue)
|
|
53
|
+
.wait(id, options);
|
|
54
|
+
if (reply.error != null) {
|
|
55
|
+
throw ResilientError.ensure(reply.error);
|
|
56
|
+
}
|
|
57
|
+
return reply.value;
|
|
58
|
+
};
|
|
59
|
+
//# sourceMappingURL=protocol.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAA;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AACrC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAO1C,MAAM,QAAQ,GAAG,CAAC,OAAqB,EAAE,WAAoB,EAG3D,EAAE;IACF,IAAI,WAAW,IAAI,IAAI,IAAI,OAAO,WAAW,KAAK,QAAQ,IAAI,CAAC,oBAAoB,CAAC,WAAW,CAAC,EAAE,CAAC;QACjG,MAAM,IAAI,YAAY,CAAC,+BAA+B,CAAC,CAAA;IACzD,CAAC;IACD,IAAI,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,KAAK,cAAc,CAAC,KAAK,EAAE,CAAC;QAC9D,MAAM,IAAI,YAAY,CAAC,GAAG,WAAW,CAAC,KAAK,wBAAwB,CAAC,CAAA;IACtE,CAAC;IACD,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAA;IAC3C,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;QAClB,MAAM,IAAI,YAAY,CAAC,GAAG,WAAW,CAAC,KAAK,2BAA2B,CAAC,CAAA;IACzE,CAAC;IACD,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;IAC9C,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;QACjD,MAAM,IAAI,YAAY,CAAC,GAAG,KAAK,IAAI,WAAW,CAAC,KAAK,EAAE,CAAC,CAAA;IACzD,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE,CAAA;AACzC,CAAC,CAAA;AAED,iGAAiG;AACjG,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,EAClC,OAAqB,EACrB,WAAqB,EACrB,OAA4B,EAC5B,OAAoB,EAC6C,EAAE;IACnE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC,CAAA;IAC1D,MAAM,MAAM,GAAG,CAAC,OAAO,IAAI,EAAE,CAAuC,CAAA;IACpE,MAAM,QAAQ,GAAgB;QAC5B,KAAK,EAAE,QAAQ,CAAC,KAAK;QACrB,MAAM,EAAE,MAAM,CAAC,MAA6C;QAC5D,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,KAAK,EAAE,MAAM,CAAC,KAA4C;QAC1D,OAAO,EAAE,MAAM,CAAC,OAAyD;QACzE,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACrC,CAAA;IAED,OAAO,MAAM,OAAO,CAAC,IAAI,CAA8C,KAAK,CAAC,CAAC,MAAM,CAAC;QACnF,KAAK;QACL,IAAI,EAAE,QAAQ,CAAC,KAAK;QACpB,IAAI,EAAE,QAAQ;QACd,IAAI,EAAE,OAAO;KACd,CAAC,CAAA;AACJ,CAAC,CAAA;AAED,qEAAqE;AACrE,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,EAClC,OAAqB,EACrB,WAAqB,EACrB,GAAoE,EACpE,OAA8B,EACC,EAAE;IACjC,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC,CAAA;IAC1D,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,GAAG,CAAC,KAAK,KAAK,KAAK,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACpF,MAAM,IAAI,YAAY,CAAC,GAAG,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC,CAAA;IACpD,CAAC;IACD,MAAM,EAAE,GAAG,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAA;IACjD,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC;QACf,MAAM,IAAI,YAAY,CAAC,GAAG,KAAK,IAAI,QAAQ,CAAC,KAAK,kBAAkB,CAAC,CAAA;IACtE,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,IAAI,CAA8C,KAAK,CAAC;SACjF,IAAI,CAAC,EAAE,EAAE,OAAO,CAAC,CAAA;IACpB,IAAI,KAAK,CAAC,KAAK,IAAI,IAAI,EAAE,CAAC;QACxB,MAAM,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC,KAAuB,CAAC,CAAA;IAC5D,CAAC;IACD,OAAO,KAAK,CAAC,KAA6B,CAAA;AAC5C,CAAC,CAAA"}
|
package/build/types.d.ts
CHANGED
|
@@ -201,6 +201,14 @@ export interface JobEnvelope {
|
|
|
201
201
|
/** When the producer enqueued it — freshness is judged here, not at processing time. */
|
|
202
202
|
enqueuedAt?: string;
|
|
203
203
|
}
|
|
204
|
+
export interface QueueJobMeta {
|
|
205
|
+
id: string;
|
|
206
|
+
name: string;
|
|
207
|
+
queue: string;
|
|
208
|
+
attempt: number;
|
|
209
|
+
/** Renew the broker lock for protocol handlers whose work can outlive one lock duration. */
|
|
210
|
+
touch: () => Promise<void>;
|
|
211
|
+
}
|
|
204
212
|
/** What a processor returns for an entrypoint job, so the caller can rebuild the reply. */
|
|
205
213
|
export interface JobReply<T = unknown> {
|
|
206
214
|
value?: T;
|
package/build/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/build/worker.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import type { Config, Context, JobEnvelope, JobProcessor } from './types.js';
|
|
|
5
5
|
* Every queued entrypoint this process both SERVES and LISTENS to, grouped by queue.
|
|
6
6
|
*
|
|
7
7
|
* Both halves are required and they answer different questions. Serving is about code — the alias
|
|
8
|
-
* was
|
|
8
|
+
* was bound here, so a handler exists. Listening is about deployment — this process was
|
|
9
9
|
* configured to consume that queue. A worker that bound queues by what it can serve would make
|
|
10
10
|
* every deployment of the same binary a worker for everything it happens to import.
|
|
11
11
|
*/
|
package/build/worker.js
CHANGED
|
@@ -6,7 +6,7 @@ import { DEFAULT_ALIAS } from './consts.js';
|
|
|
6
6
|
* Every queued entrypoint this process both SERVES and LISTENS to, grouped by queue.
|
|
7
7
|
*
|
|
8
8
|
* Both halves are required and they answer different questions. Serving is about code — the alias
|
|
9
|
-
* was
|
|
9
|
+
* was bound here, so a handler exists. Listening is about deployment — this process was
|
|
10
10
|
* configured to consume that queue. A worker that bound queues by what it can serve would make
|
|
11
11
|
* every deployment of the same binary a worker for everything it happens to import.
|
|
12
12
|
*/
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@owlmeans/queue",
|
|
3
|
-
"version": "0.1.18-rc.
|
|
3
|
+
"version": "0.1.18-rc.13",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"build": "tsc -b",
|
|
8
8
|
"dev": "sleep 234 && nodemon -e ts,tsx,json --watch src --exec \"tsc -p ./tsconfig.json\"",
|
|
9
|
-
"watch": "tsc -b -w --preserveWatchOutput --pretty"
|
|
9
|
+
"watch": "tsc -b -w --preserveWatchOutput --pretty",
|
|
10
|
+
"test": "bun test ./tests"
|
|
10
11
|
},
|
|
11
12
|
"main": "build/index.js",
|
|
12
13
|
"module": "build/index.js",
|
|
@@ -30,12 +31,12 @@
|
|
|
30
31
|
"access": "public"
|
|
31
32
|
},
|
|
32
33
|
"dependencies": {
|
|
33
|
-
"@owlmeans/auth": "^0.1.18-rc.
|
|
34
|
-
"@owlmeans/auth-common": "^0.1.18-rc.
|
|
35
|
-
"@owlmeans/context": "^0.1.18-rc.
|
|
36
|
-
"@owlmeans/entrypoint": "^0.1.18-rc.
|
|
37
|
-
"@owlmeans/error": "^0.1.18-rc.
|
|
38
|
-
"@owlmeans/resource": "^0.1.18-rc.
|
|
39
|
-
"@owlmeans/route": "^0.1.18-rc.
|
|
34
|
+
"@owlmeans/auth": "^0.1.18-rc.13",
|
|
35
|
+
"@owlmeans/auth-common": "^0.1.18-rc.17",
|
|
36
|
+
"@owlmeans/context": "^0.1.18-rc.12",
|
|
37
|
+
"@owlmeans/entrypoint": "^0.1.18-rc.15",
|
|
38
|
+
"@owlmeans/error": "^0.1.18-rc.12",
|
|
39
|
+
"@owlmeans/resource": "^0.1.18-rc.13",
|
|
40
|
+
"@owlmeans/route": "^0.1.18-rc.13"
|
|
40
41
|
}
|
|
41
42
|
}
|
package/src/bridge.ts
CHANGED
|
@@ -5,7 +5,7 @@ import type { Auth } from '@owlmeans/auth'
|
|
|
5
5
|
import { AuthorizationError } from '@owlmeans/auth'
|
|
6
6
|
import { attachEntity } from '@owlmeans/auth-common'
|
|
7
7
|
import { ResilientError } from '@owlmeans/error'
|
|
8
|
-
import type { Config, Context, JobContext, JobEnvelope, JobReply } from './types.js'
|
|
8
|
+
import type { Config, Context, JobContext, JobEnvelope, JobReply, QueueJobMeta } from './types.js'
|
|
9
9
|
import { EnvelopeExpired, JobNotServed } from './errors.js'
|
|
10
10
|
|
|
11
11
|
/**
|
|
@@ -13,7 +13,7 @@ import { EnvelopeExpired, JobNotServed } from './errors.js'
|
|
|
13
13
|
* same filter, the same handler run against it — only the wire is different.
|
|
14
14
|
*/
|
|
15
15
|
export const requestOf = (
|
|
16
|
-
envelope: JobEnvelope, path: string, context?: BasicContext<any
|
|
16
|
+
envelope: JobEnvelope, path: string, context?: BasicContext<any>, job?: QueueJobMeta,
|
|
17
17
|
): AbstractRequest => ({
|
|
18
18
|
alias: envelope.alias,
|
|
19
19
|
params: (envelope.params ?? {}) as AbstractRequest['params'],
|
|
@@ -24,9 +24,17 @@ export const requestOf = (
|
|
|
24
24
|
// Handlers reach their context through `original._ctx`, which the HTTP boundary sets on the raw
|
|
25
25
|
// Fastify request. There is no raw request here, so the shape is supplied deliberately — a
|
|
26
26
|
// handler must not have to know which transport delivered it.
|
|
27
|
-
original: context != null ? { _ctx: context } : undefined,
|
|
27
|
+
original: context != null || job != null ? { _ctx: context, _job: job } : undefined,
|
|
28
28
|
})
|
|
29
29
|
|
|
30
|
+
/** Read broker identity only where an entrypoint truly needs to bind work to an admission claim. */
|
|
31
|
+
export const queueJobOf = (request: unknown): QueueJobMeta | null => {
|
|
32
|
+
if (request == null || typeof request !== 'object' || !('original' in request)) return null
|
|
33
|
+
const original = (request as { original?: unknown }).original
|
|
34
|
+
if (original == null || typeof original !== 'object' || !('_job' in original)) return null
|
|
35
|
+
return (original as { _job?: QueueJobMeta })._job ?? null
|
|
36
|
+
}
|
|
37
|
+
|
|
30
38
|
/**
|
|
31
39
|
* Freshness is judged from when the job was ENQUEUED, not from now.
|
|
32
40
|
*
|
|
@@ -67,7 +75,9 @@ export const handleJob = async <C extends Config, T extends Context<C>>(
|
|
|
67
75
|
throw new JobNotServed(envelope.alias)
|
|
68
76
|
}
|
|
69
77
|
|
|
70
|
-
const request = requestOf(envelope, entrypoint.path(), context
|
|
78
|
+
const request = requestOf(envelope, entrypoint.path(), context, {
|
|
79
|
+
id: job.id, name: job.name, queue: job.queue, attempt: job.attempt, touch: job.touch,
|
|
80
|
+
})
|
|
71
81
|
const response = provideResponse<unknown>()
|
|
72
82
|
|
|
73
83
|
const guards = entrypoint.getGuards()
|
package/src/errors.ts
CHANGED
|
@@ -70,7 +70,7 @@ export class QueueNotListening extends QueueError {
|
|
|
70
70
|
|
|
71
71
|
/**
|
|
72
72
|
* The job named an entrypoint this process does not serve. Unlike a missing queue this is not a
|
|
73
|
-
* declaration problem: the alias exists, but nothing here
|
|
73
|
+
* declaration problem: the alias exists, but nothing here bound it, so the job was taken by a
|
|
74
74
|
* worker that cannot run it.
|
|
75
75
|
*/
|
|
76
76
|
export class JobNotServed extends QueueError {
|
package/src/index.ts
CHANGED
package/src/protocol.ts
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import type { EntrypointProtocolDeclaration, RequestOf, ResponseOf } from '@owlmeans/entrypoint'
|
|
2
|
+
import { isEntrypointProtocol } from '@owlmeans/entrypoint'
|
|
3
|
+
import { ResilientError } from '@owlmeans/error'
|
|
4
|
+
import { RouteProtocols } from '@owlmeans/route'
|
|
5
|
+
import { queueOf } from './config.js'
|
|
6
|
+
import { UnknownQueue } from './errors.js'
|
|
7
|
+
import type {
|
|
8
|
+
Config, Context, JobEnvelope, JobOptions, JobRecord, JobReply, QueueAppend,
|
|
9
|
+
} from './types.js'
|
|
10
|
+
|
|
11
|
+
type QueueContext = Context<Config> & QueueAppend
|
|
12
|
+
|
|
13
|
+
const queueFor = (context: QueueContext, declaration: unknown): {
|
|
14
|
+
protocol: EntrypointProtocolDeclaration
|
|
15
|
+
queue: string
|
|
16
|
+
} => {
|
|
17
|
+
if (declaration == null || typeof declaration !== 'object' || !isEntrypointProtocol(declaration)) {
|
|
18
|
+
throw new UnknownQueue('protocol declaration required')
|
|
19
|
+
}
|
|
20
|
+
if (declaration.route.route.protocol !== RouteProtocols.QUEUE) {
|
|
21
|
+
throw new UnknownQueue(`${declaration.alias}: not a QUEUE protocol`)
|
|
22
|
+
}
|
|
23
|
+
const queue = declaration.route.route.queue
|
|
24
|
+
if (queue == null) {
|
|
25
|
+
throw new UnknownQueue(`${declaration.alias}: route declares no queue`)
|
|
26
|
+
}
|
|
27
|
+
const configured = queueOf(context.cfg, queue)
|
|
28
|
+
if (!configured.jobs.includes(declaration.alias)) {
|
|
29
|
+
throw new UnknownQueue(`${queue}:${declaration.alias}`)
|
|
30
|
+
}
|
|
31
|
+
return { protocol: declaration, queue }
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Enqueue an immutable QUEUE protocol while preserving its exact request and response types. */
|
|
35
|
+
export const enqueueProtocol = async <Protocol extends EntrypointProtocolDeclaration>(
|
|
36
|
+
context: QueueContext,
|
|
37
|
+
declaration: Protocol,
|
|
38
|
+
request: RequestOf<Protocol>,
|
|
39
|
+
options?: JobOptions,
|
|
40
|
+
): Promise<JobRecord<JobEnvelope, JobReply<ResponseOf<Protocol>>>> => {
|
|
41
|
+
const { protocol, queue } = queueFor(context, declaration)
|
|
42
|
+
const shaped = (request ?? {}) as unknown as Record<string, unknown>
|
|
43
|
+
const envelope: JobEnvelope = {
|
|
44
|
+
alias: protocol.alias,
|
|
45
|
+
params: shaped.params as Record<string, unknown> | undefined,
|
|
46
|
+
body: shaped.body,
|
|
47
|
+
query: shaped.query as Record<string, unknown> | undefined,
|
|
48
|
+
headers: shaped.headers as Record<string, string | undefined> | undefined,
|
|
49
|
+
enqueuedAt: new Date().toISOString(),
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return await context.jobs<JobEnvelope, JobReply<ResponseOf<Protocol>>>(queue).create({
|
|
53
|
+
queue,
|
|
54
|
+
name: protocol.alias,
|
|
55
|
+
data: envelope,
|
|
56
|
+
opts: options,
|
|
57
|
+
})
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** Wait for a protocol job and unwrap the typed entrypoint reply. */
|
|
61
|
+
export const waitForProtocol = async <Protocol extends EntrypointProtocolDeclaration>(
|
|
62
|
+
context: QueueContext,
|
|
63
|
+
declaration: Protocol,
|
|
64
|
+
job: string | JobRecord<JobEnvelope, JobReply<ResponseOf<Protocol>>>,
|
|
65
|
+
options?: { timeout?: number },
|
|
66
|
+
): Promise<ResponseOf<Protocol>> => {
|
|
67
|
+
const { protocol, queue } = queueFor(context, declaration)
|
|
68
|
+
if (typeof job !== 'string' && (job.queue !== queue || job.name !== protocol.alias)) {
|
|
69
|
+
throw new UnknownQueue(`${job.queue}:${job.name}`)
|
|
70
|
+
}
|
|
71
|
+
const id = typeof job === 'string' ? job : job.id
|
|
72
|
+
if (id == null) {
|
|
73
|
+
throw new UnknownQueue(`${queue}:${protocol.alias}: missing job id`)
|
|
74
|
+
}
|
|
75
|
+
const reply = await context.jobs<JobEnvelope, JobReply<ResponseOf<Protocol>>>(queue)
|
|
76
|
+
.wait(id, options)
|
|
77
|
+
if (reply.error != null) {
|
|
78
|
+
throw ResilientError.ensure(reply.error as Error | string)
|
|
79
|
+
}
|
|
80
|
+
return reply.value as ResponseOf<Protocol>
|
|
81
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -210,6 +210,15 @@ export interface JobEnvelope {
|
|
|
210
210
|
enqueuedAt?: string
|
|
211
211
|
}
|
|
212
212
|
|
|
213
|
+
export interface QueueJobMeta {
|
|
214
|
+
id: string
|
|
215
|
+
name: string
|
|
216
|
+
queue: string
|
|
217
|
+
attempt: number
|
|
218
|
+
/** Renew the broker lock for protocol handlers whose work can outlive one lock duration. */
|
|
219
|
+
touch: () => Promise<void>
|
|
220
|
+
}
|
|
221
|
+
|
|
213
222
|
/** What a processor returns for an entrypoint job, so the caller can rebuild the reply. */
|
|
214
223
|
export interface JobReply<T = unknown> {
|
|
215
224
|
value?: T
|
package/src/worker.ts
CHANGED
|
@@ -10,7 +10,7 @@ import { DEFAULT_ALIAS } from './consts.js'
|
|
|
10
10
|
* Every queued entrypoint this process both SERVES and LISTENS to, grouped by queue.
|
|
11
11
|
*
|
|
12
12
|
* Both halves are required and they answer different questions. Serving is about code — the alias
|
|
13
|
-
* was
|
|
13
|
+
* was bound here, so a handler exists. Listening is about deployment — this process was
|
|
14
14
|
* configured to consume that queue. A worker that bound queues by what it can serve would make
|
|
15
15
|
* every deployment of the same binary a worker for everything it happens to import.
|
|
16
16
|
*/
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { describe, expect, test } from 'bun:test'
|
|
2
|
+
import { contract, protocol, schema } from '@owlmeans/entrypoint'
|
|
3
|
+
import { job, route } from '@owlmeans/route'
|
|
4
|
+
import type { JSONSchemaType } from 'ajv'
|
|
5
|
+
import { enqueueProtocol, waitForProtocol, type JobRecord } from '../src/index.js'
|
|
6
|
+
|
|
7
|
+
interface Input { value: number }
|
|
8
|
+
interface Output { doubled: number }
|
|
9
|
+
const InputSchema = schema<Input>({
|
|
10
|
+
type: 'object', properties: { value: { type: 'number' } }, required: ['value'], additionalProperties: false,
|
|
11
|
+
} as JSONSchemaType<Input>)
|
|
12
|
+
const OutputSchema = schema<Output>({
|
|
13
|
+
type: 'object', properties: { doubled: { type: 'number' } }, required: ['doubled'], additionalProperties: false,
|
|
14
|
+
} as JSONSchemaType<Output>)
|
|
15
|
+
const declaration = protocol(
|
|
16
|
+
route('test:double', '/double', job({ queue: 'test' })),
|
|
17
|
+
contract(InputSchema, OutputSchema),
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
const context = (reply: unknown = { value: { doubled: 6 } }) => {
|
|
21
|
+
const created: Partial<JobRecord>[] = []
|
|
22
|
+
return {
|
|
23
|
+
cfg: { queue: { queues: [{ name: 'test', jobs: [declaration.alias] }] } },
|
|
24
|
+
jobs: () => ({
|
|
25
|
+
create: async (record: Partial<JobRecord>) => {
|
|
26
|
+
created.push(record)
|
|
27
|
+
return { ...record, id: 'job-1' } as JobRecord
|
|
28
|
+
},
|
|
29
|
+
wait: async () => reply,
|
|
30
|
+
}),
|
|
31
|
+
created,
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
describe('protocol-aware queue calls', () => {
|
|
36
|
+
test('derives the broker address and keeps per-call options', async () => {
|
|
37
|
+
const ctx = context()
|
|
38
|
+
const queued = await enqueueProtocol(ctx as never, declaration, { body: { value: 3 } }, {
|
|
39
|
+
delay: 250, attempts: 3, id: 'projection-1',
|
|
40
|
+
})
|
|
41
|
+
expect(queued.queue).toBe('test')
|
|
42
|
+
expect(ctx.created[0]?.name).toBe(declaration.alias)
|
|
43
|
+
expect(ctx.created[0]?.opts).toEqual({ delay: 250, attempts: 3, id: 'projection-1' })
|
|
44
|
+
expect(await waitForProtocol(ctx as never, declaration, queued as never)).toEqual({ doubled: 6 })
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
test('rejects raw aliases and non-queue declarations at runtime', async () => {
|
|
48
|
+
await expect(enqueueProtocol(context() as never, declaration.alias as never, {} as never)).rejects.toThrow()
|
|
49
|
+
const http = protocol(route('test:http', '/http'), contract())
|
|
50
|
+
await expect(enqueueProtocol(context() as never, http, {})).rejects.toThrow()
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
test('rejects a job from another queue or protocol', async () => {
|
|
54
|
+
await expect(waitForProtocol(context() as never, declaration, {
|
|
55
|
+
id: 'x', queue: 'other', name: declaration.alias, data: {},
|
|
56
|
+
} as never)).rejects.toThrow()
|
|
57
|
+
})
|
|
58
|
+
})
|