@panorama-industries/effect-vercel-queue 0.0.0-stage → 0.1.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/LICENSE +21 -0
- package/README.md +13 -2
- package/dist/contracts/message-handling.d.ts +128 -0
- package/dist/contracts/message-handling.d.ts.map +1 -0
- package/dist/contracts/message-handling.js +4 -0
- package/dist/contracts/message-handling.js.map +1 -0
- package/dist/contracts/queue-api.d.ts +255 -0
- package/dist/contracts/queue-api.d.ts.map +1 -0
- package/dist/contracts/queue-api.js +18 -0
- package/dist/contracts/queue-api.js.map +1 -0
- package/dist/contracts/queue-config.d.ts +87 -0
- package/dist/contracts/queue-config.d.ts.map +1 -0
- package/dist/contracts/queue-config.js +7 -0
- package/dist/contracts/queue-config.js.map +1 -0
- package/dist/contracts/queue-consumer.d.ts +30 -0
- package/dist/contracts/queue-consumer.d.ts.map +1 -0
- package/dist/contracts/queue-consumer.js +15 -0
- package/dist/contracts/queue-consumer.js.map +1 -0
- package/dist/contracts/queue-domain.d.ts +171 -0
- package/dist/contracts/queue-domain.d.ts.map +1 -0
- package/dist/contracts/queue-domain.js +137 -0
- package/dist/contracts/queue-domain.js.map +1 -0
- package/dist/contracts/queue-poller.d.ts +169 -0
- package/dist/contracts/queue-poller.d.ts.map +1 -0
- package/dist/contracts/queue-poller.js +10 -0
- package/dist/contracts/queue-poller.js.map +1 -0
- package/dist/contracts/queue-producer.d.ts +23 -0
- package/dist/contracts/queue-producer.d.ts.map +1 -0
- package/dist/contracts/queue-producer.js +5 -0
- package/dist/contracts/queue-producer.js.map +1 -0
- package/dist/contracts/topic.d.ts +47 -0
- package/dist/contracts/topic.d.ts.map +1 -0
- package/dist/contracts/topic.js +34 -0
- package/dist/contracts/topic.js.map +1 -0
- package/dist/implementation/queue-api-live.d.ts +16 -0
- package/dist/implementation/queue-api-live.d.ts.map +1 -0
- package/dist/implementation/queue-api-live.js +326 -0
- package/dist/implementation/queue-api-live.js.map +1 -0
- package/dist/implementation/queue-config-live.d.ts +37 -0
- package/dist/implementation/queue-config-live.d.ts.map +1 -0
- package/dist/implementation/queue-config-live.js +99 -0
- package/dist/implementation/queue-config-live.js.map +1 -0
- package/dist/implementation/queue-consumer-live.d.ts +14 -0
- package/dist/implementation/queue-consumer-live.d.ts.map +1 -0
- package/dist/implementation/queue-consumer-live.js +56 -0
- package/dist/implementation/queue-consumer-live.js.map +1 -0
- package/dist/implementation/queue-live.d.ts +15 -0
- package/dist/implementation/queue-live.d.ts.map +1 -0
- package/dist/implementation/queue-live.js +16 -0
- package/dist/implementation/queue-live.js.map +1 -0
- package/dist/implementation/queue-poller-live.d.ts +14 -0
- package/dist/implementation/queue-poller-live.d.ts.map +1 -0
- package/dist/implementation/queue-poller-live.js +66 -0
- package/dist/implementation/queue-poller-live.js.map +1 -0
- package/dist/implementation/queue-producer-live.d.ts +9 -0
- package/dist/implementation/queue-producer-live.d.ts.map +1 -0
- package/dist/implementation/queue-producer-live.js +54 -0
- package/dist/implementation/queue-producer-live.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/cloud-event.d.ts +46 -0
- package/dist/internal/cloud-event.d.ts.map +1 -0
- package/dist/internal/cloud-event.js +140 -0
- package/dist/internal/cloud-event.js.map +1 -0
- package/dist/internal/lease.d.ts +23 -0
- package/dist/internal/lease.d.ts.map +1 -0
- package/dist/internal/lease.js +44 -0
- package/dist/internal/lease.js.map +1 -0
- package/dist/internal/multipart.d.ts +23 -0
- package/dist/internal/multipart.d.ts.map +1 -0
- package/dist/internal/multipart.js +205 -0
- package/dist/internal/multipart.js.map +1 -0
- package/dist/internal/process.d.ts +25 -0
- package/dist/internal/process.d.ts.map +1 -0
- package/dist/internal/process.js +95 -0
- package/dist/internal/process.js.map +1 -0
- package/dist/internal/queue-protocol.d.ts +38 -0
- package/dist/internal/queue-protocol.d.ts.map +1 -0
- package/dist/internal/queue-protocol.js +119 -0
- package/dist/internal/queue-protocol.js.map +1 -0
- package/dist/internal/version.d.ts +4 -0
- package/dist/internal/version.d.ts.map +1 -0
- package/dist/internal/version.js +4 -0
- package/dist/internal/version.js.map +1 -0
- package/dist/retry-policy.d.ts +26 -0
- package/dist/retry-policy.d.ts.map +1 -0
- package/dist/retry-policy.js +34 -0
- package/dist/retry-policy.js.map +1 -0
- package/dist/testing/index.d.ts +2 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +2 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/test-queue.d.ts +74 -0
- package/dist/testing/test-queue.d.ts.map +1 -0
- package/dist/testing/test-queue.js +253 -0
- package/dist/testing/test-queue.js.map +1 -0
- package/package.json +59 -3
- package/src/contracts/message-handling.ts +68 -0
- package/src/contracts/queue-api.ts +199 -0
- package/src/contracts/queue-config.ts +47 -0
- package/src/contracts/queue-consumer.ts +40 -0
- package/src/contracts/queue-domain.ts +202 -0
- package/src/contracts/queue-poller.ts +76 -0
- package/src/contracts/queue-producer.ts +40 -0
- package/src/contracts/topic.ts +76 -0
- package/src/implementation/queue-api-live.ts +637 -0
- package/src/implementation/queue-config-live.ts +178 -0
- package/src/implementation/queue-consumer-live.ts +112 -0
- package/src/implementation/queue-live.ts +32 -0
- package/src/implementation/queue-poller-live.ts +130 -0
- package/src/implementation/queue-producer-live.ts +89 -0
- package/src/index.ts +19 -0
- package/src/internal/cloud-event.ts +244 -0
- package/src/internal/lease.ts +84 -0
- package/src/internal/multipart.ts +240 -0
- package/src/internal/process.ts +194 -0
- package/src/internal/queue-protocol.ts +169 -0
- package/src/internal/version.ts +5 -0
- package/src/retry-policy.ts +48 -0
- package/src/testing/index.ts +1 -0
- package/src/testing/test-queue.ts +469 -0
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import { Data, Effect, Option, Stream } from "effect";
|
|
2
|
+
export class MultipartMixedError extends Data.TaggedError("MultipartMixedError") {
|
|
3
|
+
}
|
|
4
|
+
const maxHeaderSize = 65_536;
|
|
5
|
+
const encoder = new TextEncoder();
|
|
6
|
+
const latin1 = new TextDecoder("latin1");
|
|
7
|
+
export const boundaryFromContentType = (contentType) => {
|
|
8
|
+
const match = /boundary=(?:"([^"]+)"|([^;]+))/i.exec(contentType);
|
|
9
|
+
return Option.fromNullishOr(match?.[1] ?? match?.[2]);
|
|
10
|
+
};
|
|
11
|
+
const concatBytes = (chunks) => {
|
|
12
|
+
const out = new Uint8Array(chunks.reduce((total, chunk) => total + chunk.length, 0));
|
|
13
|
+
let offset = 0;
|
|
14
|
+
for (const chunk of chunks) {
|
|
15
|
+
out.set(chunk, offset);
|
|
16
|
+
offset += chunk.length;
|
|
17
|
+
}
|
|
18
|
+
return out;
|
|
19
|
+
};
|
|
20
|
+
export const encodeMultipartMixed = (boundary, parts) => concatBytes([
|
|
21
|
+
...parts.flatMap((part) => [
|
|
22
|
+
encoder.encode(`--${boundary}\r\n${part.headers.map(([name, value]) => `${name}: ${value}\r\n`).join("")}\r\n`),
|
|
23
|
+
part.body,
|
|
24
|
+
encoder.encode("\r\n"),
|
|
25
|
+
]),
|
|
26
|
+
encoder.encode(`--${boundary}--\r\n`),
|
|
27
|
+
]);
|
|
28
|
+
const indexOf = (haystack, needle, from) => {
|
|
29
|
+
const last = haystack.length - needle.length;
|
|
30
|
+
const first = needle[0];
|
|
31
|
+
outer: for (let i = Math.max(0, from); i <= last; i++) {
|
|
32
|
+
if (haystack[i] !== first)
|
|
33
|
+
continue;
|
|
34
|
+
for (let j = 1; j < needle.length; j++) {
|
|
35
|
+
if (haystack[i + j] !== needle[j])
|
|
36
|
+
continue outer;
|
|
37
|
+
}
|
|
38
|
+
return i;
|
|
39
|
+
}
|
|
40
|
+
return -1;
|
|
41
|
+
};
|
|
42
|
+
const startsWith = (haystack, needle) => haystack.length >= needle.length && indexOf(haystack.subarray(0, needle.length), needle, 0) === 0;
|
|
43
|
+
const parseHeaders = (bytes) => {
|
|
44
|
+
const headers = {};
|
|
45
|
+
for (const line of latin1.decode(bytes).trim().split(/\r?\n/)) {
|
|
46
|
+
const colon = line.indexOf(":");
|
|
47
|
+
if (colon <= 0)
|
|
48
|
+
continue;
|
|
49
|
+
const name = line.slice(0, colon).trim().toLowerCase();
|
|
50
|
+
const value = line.slice(colon + 1).trim();
|
|
51
|
+
headers[name] = name in headers ? `${headers[name]}, ${value}` : value;
|
|
52
|
+
}
|
|
53
|
+
return headers;
|
|
54
|
+
};
|
|
55
|
+
const crlfcrlf = encoder.encode("\r\n\r\n");
|
|
56
|
+
const lflf = encoder.encode("\n\n");
|
|
57
|
+
const growableBuffer = () => {
|
|
58
|
+
let storage = new Uint8Array(0);
|
|
59
|
+
let start = 0;
|
|
60
|
+
let end = 0;
|
|
61
|
+
return {
|
|
62
|
+
view: () => storage.subarray(start, end),
|
|
63
|
+
append: (chunk) => {
|
|
64
|
+
const length = end - start;
|
|
65
|
+
if (end + chunk.length > storage.length) {
|
|
66
|
+
const next = new Uint8Array(Math.max(storage.length * 2, length + chunk.length, 1024));
|
|
67
|
+
next.set(storage.subarray(start, end));
|
|
68
|
+
storage = next;
|
|
69
|
+
start = 0;
|
|
70
|
+
end = length;
|
|
71
|
+
}
|
|
72
|
+
storage.set(chunk, end);
|
|
73
|
+
end += chunk.length;
|
|
74
|
+
},
|
|
75
|
+
consume: (count) => {
|
|
76
|
+
start += count;
|
|
77
|
+
if (start === end) {
|
|
78
|
+
start = 0;
|
|
79
|
+
end = 0;
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
clear: () => {
|
|
83
|
+
start = 0;
|
|
84
|
+
end = 0;
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
};
|
|
88
|
+
const mixedParser = (boundary) => {
|
|
89
|
+
const opening = encoder.encode(`--${boundary}`);
|
|
90
|
+
const delimiter = encoder.encode(`\r\n--${boundary}`);
|
|
91
|
+
const buffer = growableBuffer();
|
|
92
|
+
let state = "start";
|
|
93
|
+
let searchFrom = 0;
|
|
94
|
+
let headers = {};
|
|
95
|
+
const failure = (message) => Effect.fail(new MultipartMixedError({ message }));
|
|
96
|
+
const step = (parts) => {
|
|
97
|
+
const bytes = buffer.view();
|
|
98
|
+
switch (state) {
|
|
99
|
+
case "start": {
|
|
100
|
+
if (bytes.length < opening.length)
|
|
101
|
+
return "wait";
|
|
102
|
+
if (!startsWith(bytes, opening)) {
|
|
103
|
+
return Option.some("Invalid multipart stream: missing initial boundary");
|
|
104
|
+
}
|
|
105
|
+
buffer.consume(opening.length);
|
|
106
|
+
state = "afterBoundary";
|
|
107
|
+
return Option.none();
|
|
108
|
+
}
|
|
109
|
+
case "afterBoundary": {
|
|
110
|
+
if (bytes.length < 2)
|
|
111
|
+
return "wait";
|
|
112
|
+
if (bytes[0] === 45 && bytes[1] === 45) {
|
|
113
|
+
state = "done";
|
|
114
|
+
buffer.clear();
|
|
115
|
+
return "wait";
|
|
116
|
+
}
|
|
117
|
+
if (bytes[0] === 13 && bytes[1] === 10) {
|
|
118
|
+
buffer.consume(2);
|
|
119
|
+
}
|
|
120
|
+
else if (bytes[0] === 10) {
|
|
121
|
+
buffer.consume(1);
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
return Option.some("Invalid character after multipart boundary");
|
|
125
|
+
}
|
|
126
|
+
state = "headers";
|
|
127
|
+
return Option.none();
|
|
128
|
+
}
|
|
129
|
+
case "headers": {
|
|
130
|
+
let end = -1;
|
|
131
|
+
let skip = 0;
|
|
132
|
+
if (bytes[0] === 13 && bytes[1] === 10) {
|
|
133
|
+
end = 0;
|
|
134
|
+
skip = 2;
|
|
135
|
+
}
|
|
136
|
+
else if (bytes[0] === 10) {
|
|
137
|
+
end = 0;
|
|
138
|
+
skip = 1;
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
const crlf = indexOf(bytes, crlfcrlf, 0);
|
|
142
|
+
const lf = indexOf(bytes, lflf, 0);
|
|
143
|
+
if (crlf !== -1 && (lf === -1 || crlf < lf)) {
|
|
144
|
+
end = crlf;
|
|
145
|
+
skip = 4;
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
end = lf;
|
|
149
|
+
skip = 2;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
if (end === -1) {
|
|
153
|
+
return bytes.length > maxHeaderSize
|
|
154
|
+
? Option.some("Multipart part headers are too large")
|
|
155
|
+
: "wait";
|
|
156
|
+
}
|
|
157
|
+
headers = parseHeaders(bytes.subarray(0, end));
|
|
158
|
+
buffer.consume(end + skip);
|
|
159
|
+
searchFrom = 0;
|
|
160
|
+
state = "body";
|
|
161
|
+
return Option.none();
|
|
162
|
+
}
|
|
163
|
+
case "body": {
|
|
164
|
+
const end = indexOf(bytes, delimiter, searchFrom);
|
|
165
|
+
if (end === -1) {
|
|
166
|
+
searchFrom = Math.max(0, bytes.length - delimiter.length + 1);
|
|
167
|
+
return "wait";
|
|
168
|
+
}
|
|
169
|
+
parts.push({ headers, body: bytes.slice(0, end) });
|
|
170
|
+
buffer.consume(end + delimiter.length);
|
|
171
|
+
state = "afterBoundary";
|
|
172
|
+
return Option.none();
|
|
173
|
+
}
|
|
174
|
+
case "done":
|
|
175
|
+
return "wait";
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
const push = (chunk) => {
|
|
179
|
+
if (state === "done")
|
|
180
|
+
return Effect.succeed([]);
|
|
181
|
+
buffer.append(chunk);
|
|
182
|
+
const parts = [];
|
|
183
|
+
while (true) {
|
|
184
|
+
const result = step(parts);
|
|
185
|
+
if (result === "wait")
|
|
186
|
+
return Effect.succeed(parts);
|
|
187
|
+
if (Option.isSome(result))
|
|
188
|
+
return failure(result.value);
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
const finish = Effect.suspend(() => {
|
|
192
|
+
if (state === "done")
|
|
193
|
+
return Effect.void;
|
|
194
|
+
return failure(state === "start"
|
|
195
|
+
? "Invalid multipart stream: missing initial boundary"
|
|
196
|
+
: "Unexpected end of multipart stream");
|
|
197
|
+
});
|
|
198
|
+
return { push, finish };
|
|
199
|
+
};
|
|
200
|
+
/** Parses a `multipart/mixed` body as it streams in, emitting each part once it is complete. */
|
|
201
|
+
export const decodeMultipartMixed = (boundary) => (source) => Stream.suspend(() => {
|
|
202
|
+
const parser = mixedParser(boundary);
|
|
203
|
+
return source.pipe(Stream.mapEffect(parser.push), Stream.flattenIterable, Stream.concat(Stream.fromEffectDrain(parser.finish)));
|
|
204
|
+
});
|
|
205
|
+
//# sourceMappingURL=multipart.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"multipart.js","sourceRoot":"","sources":["../../src/internal/multipart.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Tracer } from "effect";
|
|
2
|
+
import { Effect } from "effect";
|
|
3
|
+
import { Headers } from "effect/http";
|
|
4
|
+
import type { ConsumeOptions, MessageHandler } from "../contracts/message-handling.ts";
|
|
5
|
+
import type { QueueApi, QueueLeaseError } from "../contracts/queue-api.ts";
|
|
6
|
+
import type { ReceivedMessage } from "../contracts/queue-domain.ts";
|
|
7
|
+
import type { Topic } from "../contracts/topic.ts";
|
|
8
|
+
import type { LeaseDeadline } from "./lease.ts";
|
|
9
|
+
import { PayloadDecodeFailed } from "../contracts/queue-domain.ts";
|
|
10
|
+
export interface Delivery {
|
|
11
|
+
readonly message: ReceivedMessage;
|
|
12
|
+
readonly deadline: LeaseDeadline;
|
|
13
|
+
}
|
|
14
|
+
/** Errors a processed delivery can end with once its error policy answered `Fail`. */
|
|
15
|
+
export type ProcessError<E> = E | PayloadDecodeFailed | QueueLeaseError;
|
|
16
|
+
/**
|
|
17
|
+
* Leases, decodes, handles and settles one delivered message, following `@vercel/queue`'s
|
|
18
|
+
* `ConsumerGroup.processMessage`.
|
|
19
|
+
*/
|
|
20
|
+
export declare const processDelivery: <A, I, E, R, R2>(api: QueueApi["Service"], topic: Topic<A, I>, handler: MessageHandler<A, E, R>, options: ConsumeOptions<E, R2>, delivery: Delivery) => Effect.Effect<void, ProcessError<E>, R | R2>;
|
|
21
|
+
/** Links the producer's span, delivered in `x-vercel-queue-traceparent`, without parenting to it. */
|
|
22
|
+
export declare const producerLinks: (headers: Headers.Headers) => ReadonlyArray<Tracer.SpanLink>;
|
|
23
|
+
/** Runs `self` in a consumer-kind `vqs.process` span, as `@vercel/queue`'s `withConsumerSpan`. */
|
|
24
|
+
export declare const withProcessSpan: (links: ReadonlyArray<Tracer.SpanLink>) => <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>;
|
|
25
|
+
//# sourceMappingURL=process.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process.d.ts","sourceRoot":"","sources":["../../src/internal/process.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAErC,OAAO,EAAY,MAAM,EAAkB,MAAM,QAAQ,CAAC;AAC1D,OAAO,EAAE,OAAO,EAAoB,MAAM,aAAa,CAAC;AAExD,OAAO,KAAK,EAEV,cAAc,EACd,cAAc,EACf,MAAM,kCAAkC,CAAC;AAC1C,OAAO,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC3E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAGhD,OAAO,EAAmB,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAGpF,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;IAClC,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;CAClC;AAED,sFAAsF;AACtF,MAAM,MAAM,YAAY,CAAC,CAAC,IAAI,CAAC,GAAG,mBAAmB,GAAG,eAAe,CAAC;AAexE;;;GAGG;AACH,eAAO,MAAM,eAAe,GAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,OACvC,QAAQ,CAAC,SAAS,CAAC,SACjB,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,WACT,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,WACvB,cAAc,CAAC,CAAC,EAAE,EAAE,CAAC,YACpB,QAAQ,KACjB,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,CAsH7C,CAAC;AAIF,qGAAqG;AACrG,eAAO,MAAM,aAAa,YAAa,OAAO,CAAC,OAAO,KAAG,aAAa,CAAC,MAAM,CAAC,QAAQ,CAOrF,CAAC;AAEF,kGAAkG;AAClG,eAAO,MAAM,eAAe,UAClB,aAAa,CAAC,MAAM,CAAC,QAAQ,CAAC,MACrC,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAAG,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAQ1D,CAAC"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { Duration, Effect, Option, Schema } from "effect";
|
|
2
|
+
import { Headers, HttpTraceContext } from "effect/http";
|
|
3
|
+
import { RetryDirective } from "../contracts/message-handling.js";
|
|
4
|
+
import { MessageMetadata, PayloadDecodeFailed } from "../contracts/queue-domain.js";
|
|
5
|
+
import { keepLeaseAlive, leaseVisibilityTimeout } from "./lease.js";
|
|
6
|
+
const escalate = (forPolicy, error) => ({ forPolicy, error });
|
|
7
|
+
const toPolicy = (error) => escalate(Option.some(error), error);
|
|
8
|
+
/**
|
|
9
|
+
* Leases, decodes, handles and settles one delivered message, following `@vercel/queue`'s
|
|
10
|
+
* `ConsumerGroup.processMessage`.
|
|
11
|
+
*/
|
|
12
|
+
export const processDelivery = (api, topic, handler, options, delivery) => {
|
|
13
|
+
const { handle, metadata, body } = delivery.message;
|
|
14
|
+
const timeout = leaseVisibilityTimeout(options.visibilityTimeout);
|
|
15
|
+
const maxReruns = Math.max(0, Math.floor(options.experimentalMaxCoalescedReruns ?? 0));
|
|
16
|
+
const decode = Schema.decodeEffect(topic.wire)(body).pipe(Effect.mapError((error) => new PayloadDecodeFailed({
|
|
17
|
+
topic: handle.topic,
|
|
18
|
+
messageId: handle.messageId,
|
|
19
|
+
message: error.message,
|
|
20
|
+
})));
|
|
21
|
+
const runHandler = (payload, meta, deadline) => Effect.scoped(keepLeaseAlive(api, handle, timeout, deadline).pipe(Effect.andThen(handler(payload, meta)))).pipe(Effect.mapError(toPolicy));
|
|
22
|
+
const settleFailure = (error) => Effect.fail(escalate(Option.none(), error));
|
|
23
|
+
const acknowledge = (rerun, coalescedCount) => api
|
|
24
|
+
.acknowledge(handle, coalescedCount > 0 ? { experimentalIfCoalesced: coalescedCount } : undefined)
|
|
25
|
+
.pipe(Effect.as(Option.none()), Effect.catchReason("MessageNotAvailable", "ConcurrencyCoalescedPending", (reason, error) => rerun > maxReruns
|
|
26
|
+
? Effect.fail(escalate(Option.some(reason), error))
|
|
27
|
+
: Effect.succeed(Option.some(reason.coalescedCount))), Effect.catchTags({
|
|
28
|
+
MessageNotAvailable: settleFailure,
|
|
29
|
+
MessageNotFound: settleFailure,
|
|
30
|
+
VercelApiError: settleFailure,
|
|
31
|
+
ConsumerRegistryNotConfigured: settleFailure,
|
|
32
|
+
}));
|
|
33
|
+
const attempt = Effect.gen(function* () {
|
|
34
|
+
const payload = yield* Effect.mapError(decode, toPolicy);
|
|
35
|
+
yield* runHandler(payload, metadata, delivery.deadline);
|
|
36
|
+
let coalescedCount = 0;
|
|
37
|
+
for (let rerun = 1;; rerun++) {
|
|
38
|
+
const refused = yield* acknowledge(rerun, coalescedCount);
|
|
39
|
+
if (Option.isNone(refused))
|
|
40
|
+
return;
|
|
41
|
+
coalescedCount = refused.value;
|
|
42
|
+
yield* runHandler(payload, new MessageMetadata({
|
|
43
|
+
messageId: metadata.messageId,
|
|
44
|
+
deliveryCount: metadata.deliveryCount,
|
|
45
|
+
createdAt: metadata.createdAt,
|
|
46
|
+
expiresAt: metadata.expiresAt,
|
|
47
|
+
topic: metadata.topic,
|
|
48
|
+
consumerGroup: metadata.consumerGroup,
|
|
49
|
+
region: metadata.region,
|
|
50
|
+
...(metadata.experimentalHandoffCount === undefined
|
|
51
|
+
? {}
|
|
52
|
+
: { experimentalHandoffCount: metadata.experimentalHandoffCount }),
|
|
53
|
+
experimentalCoalesced: { rerun, coalescedCount },
|
|
54
|
+
}), Option.some("expired"));
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
const chooseDirective = (error) => options.onError === undefined
|
|
58
|
+
? Effect.succeed(RetryDirective.Fail())
|
|
59
|
+
: options
|
|
60
|
+
.onError(error, metadata)
|
|
61
|
+
.pipe(Effect.catchDefect((defect) => Effect.logWarning("Queue error policy failed; failing the delivery", defect).pipe(Effect.as(RetryDirective.Fail()))));
|
|
62
|
+
const applyDirective = (directive, error) => RetryDirective.$match(directive, {
|
|
63
|
+
Acknowledge: () => api
|
|
64
|
+
.acknowledge(handle)
|
|
65
|
+
.pipe(Effect.catch((cause) => Effect.logWarning("Failed to acknowledge message", cause))),
|
|
66
|
+
RetryAfter: ({ delay }) => api.changeVisibility(handle, delay).pipe(Effect.asVoid, Effect.catch((cause) => Effect.logWarning("Failed to reschedule message for retry", cause))),
|
|
67
|
+
ExperimentalHandoff: () => api.changeVisibility(handle, Duration.zero, { experimentalHandoff: true }).pipe(Effect.asVoid, Effect.catch((cause) => Effect.logWarning("Failed to hand off message", cause))),
|
|
68
|
+
Fail: () => Effect.fail(error),
|
|
69
|
+
});
|
|
70
|
+
return attempt.pipe(Effect.catch(({ forPolicy, error }) => Option.match(forPolicy, {
|
|
71
|
+
onNone: () => Effect.fail(error),
|
|
72
|
+
onSome: (cause) => chooseDirective(cause).pipe(Effect.flatMap((directive) => applyDirective(directive, error))),
|
|
73
|
+
})), Effect.annotateLogs({ module: "QueueConsumer", messageId: handle.messageId }));
|
|
74
|
+
};
|
|
75
|
+
const PRODUCER_TRACEPARENT = "x-vercel-queue-traceparent";
|
|
76
|
+
/** Links the producer's span, delivered in `x-vercel-queue-traceparent`, without parenting to it. */
|
|
77
|
+
export const producerLinks = (headers) => {
|
|
78
|
+
const traceparent = headers[PRODUCER_TRACEPARENT];
|
|
79
|
+
if (!traceparent)
|
|
80
|
+
return [];
|
|
81
|
+
return Option.match(HttpTraceContext.w3c(Headers.fromInput({ traceparent })), {
|
|
82
|
+
onNone: () => [],
|
|
83
|
+
onSome: (span) => [{ span, attributes: {} }],
|
|
84
|
+
});
|
|
85
|
+
};
|
|
86
|
+
/** Runs `self` in a consumer-kind `vqs.process` span, as `@vercel/queue`'s `withConsumerSpan`. */
|
|
87
|
+
export const withProcessSpan = (links) => (self) => Effect.withSpan(self, "vqs.process", {
|
|
88
|
+
kind: "consumer",
|
|
89
|
+
links,
|
|
90
|
+
attributes: {
|
|
91
|
+
"messaging.system": "vercel-queue",
|
|
92
|
+
"messaging.operation": "process",
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
//# sourceMappingURL=process.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process.js","sourceRoot":"","sources":["../../src/internal/process.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { DateTime, Duration, Option } from "effect";
|
|
2
|
+
import type { OutgoingMessage } from "../contracts/queue-api.ts";
|
|
3
|
+
export declare const errorCodeHeader = "Vqs-Error-Code";
|
|
4
|
+
export declare const apiBaseUrl: (url: URL) => string;
|
|
5
|
+
export declare const topicPath: (topic: string, ...segments: ReadonlyArray<string>) => string;
|
|
6
|
+
export declare const wholeSeconds: (input: Duration.Input) => number;
|
|
7
|
+
/** A case-insensitive header set with the same overwrite semantics as `Headers.set`. */
|
|
8
|
+
export declare class HeaderSet {
|
|
9
|
+
private readonly entries;
|
|
10
|
+
constructor(init?: Readonly<Record<string, string>>);
|
|
11
|
+
set(name: string, value: string): this;
|
|
12
|
+
delete(name: string): this;
|
|
13
|
+
get(name: string): string | undefined;
|
|
14
|
+
toRecord(): Record<string, string>;
|
|
15
|
+
/** Entries sorted by name, as `Headers` iterates them. */
|
|
16
|
+
sorted(): Array<readonly [string, string]>;
|
|
17
|
+
}
|
|
18
|
+
export declare const messageHeaders: (custom: Readonly<Record<string, string>>, message: OutgoingMessage) => HeaderSet;
|
|
19
|
+
export declare const retryAfterFromHeader: (value: string | undefined, nowMillis: number) => Option.Option<Duration.Duration>;
|
|
20
|
+
export interface ErrorBody {
|
|
21
|
+
readonly text: string;
|
|
22
|
+
readonly message: string;
|
|
23
|
+
readonly originalMessageId: Option.Option<string>;
|
|
24
|
+
}
|
|
25
|
+
export declare const errorBodyOf: (text: string, contentType: string | undefined) => ErrorBody;
|
|
26
|
+
export declare const coalescedPendingCount: (errorCode: string | undefined, coalescedHeader: string | undefined, text: string) => Option.Option<number>;
|
|
27
|
+
export interface QueuePartHeaders {
|
|
28
|
+
readonly messageId: string;
|
|
29
|
+
readonly receiptHandle: string;
|
|
30
|
+
readonly deliveryCount: number;
|
|
31
|
+
readonly timestamp: string;
|
|
32
|
+
readonly expiresAt: Option.Option<string>;
|
|
33
|
+
readonly contentType: string;
|
|
34
|
+
readonly handoffCount: Option.Option<number>;
|
|
35
|
+
}
|
|
36
|
+
export declare const queuePartHeaders: (headers: Readonly<Record<string, string>>) => Option.Option<QueuePartHeaders>;
|
|
37
|
+
export declare const parseDate: (value: string) => Option.Option<DateTime.Utc>;
|
|
38
|
+
//# sourceMappingURL=queue-protocol.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queue-protocol.d.ts","sourceRoot":"","sources":["../../src/internal/queue-protocol.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAqB,MAAM,QAAQ,CAAC;AAEvE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAEjE,eAAO,MAAM,eAAe,mBAAmB,CAAC;AAEhD,eAAO,MAAM,UAAU,QAAS,GAAG,KAAG,MAC2B,CAAC;AAElE,eAAO,MAAM,SAAS,UAAW,MAAM,eAAe,aAAa,CAAC,MAAM,CAAC,KAAG,MACK,CAAC;AAEpF,eAAO,MAAM,YAAY,UAAW,QAAQ,CAAC,KAAK,KAAG,MACiB,CAAC;AAIvE,wFAAwF;AACxF,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA6B;IAErD,YAAY,IAAI,GAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAM,EAEtD;IAED,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAGrC;IAED,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAGzB;IAED,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAEpC;IAED,QAAQ,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAEjC;IAED,0DAA0D;IAC1D,MAAM,IAAI,KAAK,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAEzC;CACF;AAOD,eAAO,MAAM,cAAc,WACjB,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,WAC/B,eAAe,KACvB,SAiBF,CAAC;AAEF,eAAO,MAAM,oBAAoB,UACxB,MAAM,GAAG,SAAS,aACd,MAAM,KAChB,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAQjC,CAAC;AAEF,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;CACnD;AAMD,eAAO,MAAM,WAAW,SAAU,MAAM,eAAe,MAAM,GAAG,SAAS,KAAG,SAoB3E,CAAC;AAOF,eAAO,MAAM,qBAAqB,cACrB,MAAM,GAAG,SAAS,mBACZ,MAAM,GAAG,SAAS,QAC7B,MAAM,KACX,MAAM,CAAC,MAAM,CAAC,MAAM,CAKtB,CAAC;AAEF,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC1C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;CAC9C;AAED,eAAO,MAAM,gBAAgB,YAClB,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,KACxC,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAgBhC,CAAC;AAEF,eAAO,MAAM,SAAS,UAAW,MAAM,KAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CACpC,CAAC"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { DateTime, Duration, Option, Predicate, Schema } from "effect";
|
|
2
|
+
export const errorCodeHeader = "Vqs-Error-Code";
|
|
3
|
+
export const apiBaseUrl = (url) => `${url.origin}${url.pathname.replace(/\/+$/, "")}/api/v3/topic`;
|
|
4
|
+
export const topicPath = (topic, ...segments) => [topic, ...segments].map((segment) => `/${encodeURIComponent(segment)}`).join("");
|
|
5
|
+
export const wholeSeconds = (input) => Math.ceil(Duration.toMillis(Duration.fromInputUnsafe(input)) / 1000);
|
|
6
|
+
const trimHeaderValue = (value) => value.replace(/^[\t\n\r ]+|[\t\n\r ]+$/g, "");
|
|
7
|
+
/** A case-insensitive header set with the same overwrite semantics as `Headers.set`. */
|
|
8
|
+
export class HeaderSet {
|
|
9
|
+
entries = new Map();
|
|
10
|
+
constructor(init = {}) {
|
|
11
|
+
for (const [name, value] of Object.entries(init))
|
|
12
|
+
this.set(name, value);
|
|
13
|
+
}
|
|
14
|
+
set(name, value) {
|
|
15
|
+
this.entries.set(name.toLowerCase(), trimHeaderValue(value));
|
|
16
|
+
return this;
|
|
17
|
+
}
|
|
18
|
+
delete(name) {
|
|
19
|
+
this.entries.delete(name.toLowerCase());
|
|
20
|
+
return this;
|
|
21
|
+
}
|
|
22
|
+
get(name) {
|
|
23
|
+
return this.entries.get(name.toLowerCase());
|
|
24
|
+
}
|
|
25
|
+
toRecord() {
|
|
26
|
+
return Object.fromEntries(this.entries);
|
|
27
|
+
}
|
|
28
|
+
/** Entries sorted by name, as `Headers` iterates them. */
|
|
29
|
+
sorted() {
|
|
30
|
+
return [...this.entries].toSorted(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
const isReservedMessageHeader = (name) => {
|
|
34
|
+
const lower = name.toLowerCase();
|
|
35
|
+
return lower === "authorization" || lower === "content-type" || lower.startsWith("vqs-");
|
|
36
|
+
};
|
|
37
|
+
export const messageHeaders = (custom, message) => {
|
|
38
|
+
const headers = new HeaderSet(custom).delete("authorization");
|
|
39
|
+
for (const [name, value] of Object.entries(message.headers ?? {})) {
|
|
40
|
+
if (!isReservedMessageHeader(name))
|
|
41
|
+
headers.set(name, value);
|
|
42
|
+
}
|
|
43
|
+
headers.set("content-type", message.contentType);
|
|
44
|
+
if (message.idempotencyKey)
|
|
45
|
+
headers.set("vqs-idempotency-key", message.idempotencyKey);
|
|
46
|
+
if (message.retention !== undefined) {
|
|
47
|
+
headers.set("vqs-retention-seconds", String(wholeSeconds(message.retention)));
|
|
48
|
+
}
|
|
49
|
+
if (message.delay !== undefined) {
|
|
50
|
+
headers.set("vqs-delay-seconds", String(wholeSeconds(message.delay)));
|
|
51
|
+
}
|
|
52
|
+
if (message.experimentalConcurrencyKey) {
|
|
53
|
+
headers.set("vqs-experimental-concurrency-key", message.experimentalConcurrencyKey);
|
|
54
|
+
}
|
|
55
|
+
return headers;
|
|
56
|
+
};
|
|
57
|
+
export const retryAfterFromHeader = (value, nowMillis) => {
|
|
58
|
+
if (!value)
|
|
59
|
+
return Option.none();
|
|
60
|
+
const seconds = Number(value);
|
|
61
|
+
if (Number.isFinite(seconds) && seconds >= 0)
|
|
62
|
+
return Option.some(Duration.seconds(seconds));
|
|
63
|
+
const dateMillis = Date.parse(value);
|
|
64
|
+
return Number.isNaN(dateMillis)
|
|
65
|
+
? Option.none()
|
|
66
|
+
: Option.some(Duration.millis(Math.max(0, dateMillis - nowMillis)));
|
|
67
|
+
};
|
|
68
|
+
const decodeJsonObject = Schema.decodeUnknownOption(Schema.fromJsonString(Schema.Record(Schema.String, Schema.Unknown)));
|
|
69
|
+
export const errorBodyOf = (text, contentType) => {
|
|
70
|
+
const plain = { text, message: text, originalMessageId: Option.none() };
|
|
71
|
+
if (!contentType?.toLowerCase().includes("json"))
|
|
72
|
+
return plain;
|
|
73
|
+
return Option.match(decodeJsonObject(text), {
|
|
74
|
+
onNone: () => plain,
|
|
75
|
+
onSome: (body) => {
|
|
76
|
+
const error = body["error"];
|
|
77
|
+
const message = Predicate.isString(error)
|
|
78
|
+
? error
|
|
79
|
+
: Predicate.isObject(error) && Predicate.isString(error["message"])
|
|
80
|
+
? error["message"]
|
|
81
|
+
: text;
|
|
82
|
+
const original = body["originalMessageId"];
|
|
83
|
+
return {
|
|
84
|
+
text,
|
|
85
|
+
message,
|
|
86
|
+
originalMessageId: Predicate.isString(original) ? Option.some(original) : Option.none(),
|
|
87
|
+
};
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
};
|
|
91
|
+
const positiveInt = (value) => Predicate.isNumber(value) && Number.isInteger(value) && value > 0
|
|
92
|
+
? Option.some(value)
|
|
93
|
+
: Option.none();
|
|
94
|
+
export const coalescedPendingCount = (errorCode, coalescedHeader, text) => {
|
|
95
|
+
if (errorCode !== "concurrency_coalesced_pending")
|
|
96
|
+
return Option.none();
|
|
97
|
+
return Option.orElse(positiveInt(Number(coalescedHeader ?? null)), () => Option.flatMap(decodeJsonObject(text), (body) => positiveInt(body["coalescedCount"])));
|
|
98
|
+
};
|
|
99
|
+
export const queuePartHeaders = (headers) => {
|
|
100
|
+
const messageId = headers["vqs-message-id"];
|
|
101
|
+
const timestamp = headers["vqs-timestamp"];
|
|
102
|
+
const receiptHandle = headers["vqs-receipt-handle"];
|
|
103
|
+
if (!messageId || !timestamp || !receiptHandle)
|
|
104
|
+
return Option.none();
|
|
105
|
+
const deliveryCount = Number.parseInt(headers["vqs-delivery-count"] || "0", 10);
|
|
106
|
+
if (Number.isNaN(deliveryCount))
|
|
107
|
+
return Option.none();
|
|
108
|
+
return Option.some({
|
|
109
|
+
messageId,
|
|
110
|
+
receiptHandle,
|
|
111
|
+
deliveryCount,
|
|
112
|
+
timestamp,
|
|
113
|
+
expiresAt: Option.fromUndefinedOr(headers["vqs-expires-at"] || undefined),
|
|
114
|
+
contentType: headers["content-type"] || "application/octet-stream",
|
|
115
|
+
handoffCount: positiveInt(Number(headers["vqs-experimental-handoff-count"] || Number.NaN)),
|
|
116
|
+
});
|
|
117
|
+
};
|
|
118
|
+
export const parseDate = (value) => DateTime.make(new Date(value));
|
|
119
|
+
//# sourceMappingURL=queue-protocol.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queue-protocol.js","sourceRoot":"","sources":["../../src/internal/queue-protocol.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/internal/version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,WAAW,6CAA6C,CAAC;AAEtE,eAAO,MAAM,cAAc,UAAU,CAAC;AAEtC,eAAO,MAAM,SAAS,mDAAqC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/internal/version.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,WAAW,GAAG,0CAA0C,CAAC;AAEtE,MAAM,CAAC,MAAM,cAAc,GAAG,OAAO,CAAC;AAEtC,MAAM,CAAC,MAAM,SAAS,GAAG,GAAG,WAAW,IAAI,cAAc,EAAE,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Effect, Schedule } from "effect";
|
|
2
|
+
import type { MessageMetadata } from "./contracts/queue-domain.ts";
|
|
3
|
+
import { RetryDirective } from "./contracts/message-handling.ts";
|
|
4
|
+
/**
|
|
5
|
+
* Build an `onError` policy that redelivers failed messages on a `Schedule`.
|
|
6
|
+
*
|
|
7
|
+
* The n-th failed delivery (`deliveryCount` minus experimental handoffs, which do not count as
|
|
8
|
+
* retries) waits for the schedule's n-th delay: the policy answers `RetryAfter(delay)` while the
|
|
9
|
+
* schedule continues and `onExhausted` once it is done. The schedule receives the error as input
|
|
10
|
+
* and is stepped from a fresh state on every call, all at the current time, so elapsed-time
|
|
11
|
+
* schedules see no elapsed time.
|
|
12
|
+
*
|
|
13
|
+
* ```ts
|
|
14
|
+
* consumer.handler(Orders, fulfil, {
|
|
15
|
+
* onError: retryOnSchedule(Schedule.exponential("1 second").pipe(Schedule.upTo({ times: 5 }))),
|
|
16
|
+
* });
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* @param schedule - Delay of each retry; its outputs are ignored.
|
|
20
|
+
* @param options.onExhausted - Directive once the schedule is done. Default: `Acknowledge`, so the
|
|
21
|
+
* message is dropped.
|
|
22
|
+
*/
|
|
23
|
+
export declare const retryOnSchedule: <Out, In, R>(schedule: Schedule.Schedule<Out, In, never, R>, options?: {
|
|
24
|
+
readonly onExhausted?: RetryDirective;
|
|
25
|
+
}) => (error: In, metadata: MessageMetadata) => Effect.Effect<RetryDirective, never, R>;
|
|
26
|
+
//# sourceMappingURL=retry-policy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry-policy.d.ts","sourceRoot":"","sources":["../src/retry-policy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,MAAM,EAAgB,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAE/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAEnE,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAEjE;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,eAAe,GACzB,GAAG,EAAE,EAAE,EAAE,CAAC,YACC,QAAQ,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,YACpC;IAAE,QAAQ,CAAC,WAAW,CAAC,EAAE,cAAc,CAAA;CAAE,aAE7C,EAAE,YAAY,eAAe,KAAG,MAAM,CAAC,MAAM,CAAC,cAAc,EAAE,KAAK,EAAE,CAAC,CAiB1E,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Clock, Effect, Option, Pull, Schedule } from "effect";
|
|
2
|
+
import { RetryDirective } from "./contracts/message-handling.js";
|
|
3
|
+
/**
|
|
4
|
+
* Build an `onError` policy that redelivers failed messages on a `Schedule`.
|
|
5
|
+
*
|
|
6
|
+
* The n-th failed delivery (`deliveryCount` minus experimental handoffs, which do not count as
|
|
7
|
+
* retries) waits for the schedule's n-th delay: the policy answers `RetryAfter(delay)` while the
|
|
8
|
+
* schedule continues and `onExhausted` once it is done. The schedule receives the error as input
|
|
9
|
+
* and is stepped from a fresh state on every call, all at the current time, so elapsed-time
|
|
10
|
+
* schedules see no elapsed time.
|
|
11
|
+
*
|
|
12
|
+
* ```ts
|
|
13
|
+
* consumer.handler(Orders, fulfil, {
|
|
14
|
+
* onError: retryOnSchedule(Schedule.exponential("1 second").pipe(Schedule.upTo({ times: 5 }))),
|
|
15
|
+
* });
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* @param schedule - Delay of each retry; its outputs are ignored.
|
|
19
|
+
* @param options.onExhausted - Directive once the schedule is done. Default: `Acknowledge`, so the
|
|
20
|
+
* message is dropped.
|
|
21
|
+
*/
|
|
22
|
+
export const retryOnSchedule = (schedule, options) => (error, metadata) => Effect.gen(function* () {
|
|
23
|
+
const step = yield* Schedule.toStep(schedule);
|
|
24
|
+
const now = yield* Clock.currentTimeMillis;
|
|
25
|
+
const attempt = Math.max(1, metadata.deliveryCount - (metadata.experimentalHandoffCount ?? 0));
|
|
26
|
+
let delay = Option.none();
|
|
27
|
+
for (let n = 0; n < attempt; n++) {
|
|
28
|
+
delay = yield* step(now, error).pipe(Effect.map(([, duration]) => Option.some(RetryDirective.RetryAfter({ delay: duration }))), Pull.catchDone(() => Effect.succeed(Option.none())));
|
|
29
|
+
if (Option.isNone(delay))
|
|
30
|
+
break;
|
|
31
|
+
}
|
|
32
|
+
return Option.getOrElse(delay, () => options?.onExhausted ?? RetryDirective.Acknowledge());
|
|
33
|
+
});
|
|
34
|
+
//# sourceMappingURL=retry-policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry-policy.js","sourceRoot":"","sources":["../src/retry-policy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAI/D,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAEjE;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,CAAC,MAAM,eAAe,GAC1B,CACE,QAA8C,EAC9C,OAAmD,EACnD,EAAE,CACJ,CAAC,KAAS,EAAE,QAAyB,EAA2C,EAAE,CAChF,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC9C,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC,iBAAiB,CAAC;IAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CACtB,CAAC,EACD,QAAQ,CAAC,aAAa,GAAG,CAAC,QAAQ,CAAC,wBAAwB,IAAI,CAAC,CAAC,CAClE,CAAC;IACF,IAAI,KAAK,GAAG,MAAM,CAAC,IAAI,EAAkB,CAAC;IAC1C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC;QACjC,KAAK,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,IAAI,CAClC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EACzF,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAkB,CAAC,CAAC,CACpE,CAAC;QACF,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC;YAAE,MAAM;IAClC,CAAC;IACD,OAAO,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,WAAW,IAAI,cAAc,CAAC,WAAW,EAAE,CAAC,CAAC;AAC7F,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC"}
|