@nestarc/webhook 0.10.0 → 0.12.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 +87 -7
- package/dist/adapters/prisma-delivery.repository.d.ts +2 -1
- package/dist/adapters/prisma-delivery.repository.d.ts.map +1 -1
- package/dist/adapters/prisma-delivery.repository.js +69 -1
- package/dist/adapters/prisma-delivery.repository.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/interfaces/webhook-options.interface.d.ts +90 -2
- package/dist/interfaces/webhook-options.interface.d.ts.map +1 -1
- package/dist/ports/webhook-delivery.repository.d.ts +8 -0
- package/dist/ports/webhook-delivery.repository.d.ts.map +1 -1
- package/dist/webhook.circuit-breaker.d.ts +5 -0
- package/dist/webhook.circuit-breaker.d.ts.map +1 -1
- package/dist/webhook.circuit-breaker.js +80 -21
- package/dist/webhook.circuit-breaker.js.map +1 -1
- package/dist/webhook.delivery-worker.d.ts +18 -0
- package/dist/webhook.delivery-worker.d.ts.map +1 -1
- package/dist/webhook.delivery-worker.js +224 -28
- package/dist/webhook.delivery-worker.js.map +1 -1
- package/dist/webhook.retry-classifier.d.ts +3 -0
- package/dist/webhook.retry-classifier.d.ts.map +1 -0
- package/dist/webhook.retry-classifier.js +17 -0
- package/dist/webhook.retry-classifier.js.map +1 -0
- package/package.json +1 -1
- package/src/sql/create-webhook-tables.sql +6 -0
- package/src/sql/migrations/v0.12.0.sql +10 -0
package/README.md
CHANGED
|
@@ -26,7 +26,7 @@ Outbound webhook delivery for NestJS — HMAC signing, exponential retry, circui
|
|
|
26
26
|
- **SSRF defense** — DNS resolution validation at registration and dispatch time
|
|
27
27
|
- **Ports/adapters architecture** — swap Prisma or fetch with custom implementations
|
|
28
28
|
- **Stale delivery recovery** — lease-based reaper recovers crashed worker deliveries
|
|
29
|
-
- **Notification hooks** —
|
|
29
|
+
- **Notification hooks** — retry, degraded, failed, and disabled callbacks for observability and alerting
|
|
30
30
|
|
|
31
31
|
## Installation
|
|
32
32
|
|
|
@@ -76,11 +76,12 @@ import { WebhookModule } from '@nestarc/webhook';
|
|
|
76
76
|
// See "Async configuration" below for NestJS DI wiring.
|
|
77
77
|
prisma: prismaService,
|
|
78
78
|
delivery: {
|
|
79
|
-
timeout:
|
|
80
|
-
maxRetries:
|
|
79
|
+
timeout: 30_000,
|
|
80
|
+
maxRetries: 6,
|
|
81
81
|
jitter: true,
|
|
82
82
|
},
|
|
83
83
|
circuitBreaker: {
|
|
84
|
+
degradedThreshold: 3,
|
|
84
85
|
failureThreshold: 5,
|
|
85
86
|
cooldownMinutes: 60,
|
|
86
87
|
},
|
|
@@ -88,6 +89,18 @@ import { WebhookModule } from '@nestarc/webhook';
|
|
|
88
89
|
interval: 5000,
|
|
89
90
|
batchSize: 50,
|
|
90
91
|
},
|
|
92
|
+
onDeliveryRetryScheduled: (ctx) => {
|
|
93
|
+
// Internal observability: a retry was persisted with ctx.nextAttemptAt.
|
|
94
|
+
},
|
|
95
|
+
onEndpointDegraded: (ctx) => {
|
|
96
|
+
// Alert candidate: endpoint reached the degraded threshold before disablement.
|
|
97
|
+
},
|
|
98
|
+
onDeliveryFailed: (ctx) => {
|
|
99
|
+
// Terminal delivery failure only.
|
|
100
|
+
},
|
|
101
|
+
onEndpointDisabled: (ctx) => {
|
|
102
|
+
// Endpoint transitioned from active to inactive.
|
|
103
|
+
},
|
|
91
104
|
}),
|
|
92
105
|
],
|
|
93
106
|
})
|
|
@@ -201,19 +214,80 @@ export class WebhookController {
|
|
|
201
214
|
| `delivery.maxRetries` | `5` | Maximum delivery attempts |
|
|
202
215
|
| `delivery.jitter` | `true` | Add random jitter to retry delays |
|
|
203
216
|
| `circuitBreaker.failureThreshold` | `5` | Consecutive failures before disabling endpoint |
|
|
217
|
+
| `circuitBreaker.degradedThreshold` | — | Consecutive failures before firing `onEndpointDegraded`. Disabled unless configured. Must be lower than `failureThreshold`. |
|
|
204
218
|
| `circuitBreaker.cooldownMinutes` | `60` | Minutes before attempting recovery |
|
|
205
219
|
| `polling.enabled` | `true` | Set to `false` to disable the polling loop (API-only mode) |
|
|
206
220
|
| `polling.interval` | `5000` | Delivery worker poll interval (ms) |
|
|
207
|
-
| `polling.batchSize` | `50` | Max
|
|
221
|
+
| `polling.batchSize` | `50` | Max rows claimed in one database claim |
|
|
208
222
|
| `polling.staleSendingMinutes` | `5` | Minutes before a stuck SENDING delivery is recovered |
|
|
223
|
+
| `polling.maxConcurrency` | `polling.batchSize` | Max delivery dispatches in flight per worker process |
|
|
224
|
+
| `polling.drainWhileBacklogged` | `false` | Keep claiming additional batches inside one poll while backlog and capacity remain |
|
|
225
|
+
| `polling.maxDrainLoopsPerPoll` | `1`, or `10` when drain mode is enabled | Max claim loops inside one poll cycle |
|
|
226
|
+
| `polling.drainLoopDelayMs` | `0` | Optional delay between drain loops |
|
|
209
227
|
| `allowPrivateUrls` | `false` | Allow private/internal URLs (dev/test only) |
|
|
210
228
|
| `secretVault` | `PlaintextSecretVault` | Custom vault for encrypting/decrypting endpoint secrets at rest |
|
|
211
|
-
| `onDeliveryFailed` | — | Fire-and-forget callback when a delivery exhausts
|
|
212
|
-
| `
|
|
229
|
+
| `onDeliveryFailed` | — | Fire-and-forget callback when a delivery exhausts retries or receives a non-retryable response. Receives `DeliveryFailedContext` (`tenantId` is `null` for global endpoints). See **Delivery failure classification** below. |
|
|
230
|
+
| `onDeliveryRetryScheduled` | — | Fire-and-forget callback after a retriable failed attempt is persisted with `nextAttemptAt`. Receives `DeliveryRetryScheduledContext`. Does not fire for terminal failures. |
|
|
231
|
+
| `onEndpointDegraded` | — | Fire-and-forget callback when consecutive failures reach `circuitBreaker.degradedThreshold` before endpoint disablement. Receives `EndpointDegradedContext`. |
|
|
232
|
+
| `onEndpointDisabled` | — | Fire-and-forget callback when the circuit breaker disables an endpoint. Fires only on active-to-inactive transition after failures meet or exceed `failureThreshold`. |
|
|
213
233
|
|
|
214
234
|
The retry schedule is fixed exponential (`30s`, `5m`, `30m`, `2h`, `24h`). Use `delivery.jitter` to enable or disable random jitter.
|
|
215
235
|
|
|
216
|
-
|
|
236
|
+
### Worker Capacity And Observer Metrics
|
|
237
|
+
|
|
238
|
+
The delivery worker keeps the previous default behavior: one poll claims up to `polling.batchSize` rows and waits for those deliveries before the next interval. Set `polling.maxConcurrency` to cap in-flight dispatches below or above a claim size, and set `polling.drainWhileBacklogged: true` when a worker should continue draining queued deliveries inside the same poll cycle.
|
|
239
|
+
|
|
240
|
+
```ts
|
|
241
|
+
WebhookModule.forRoot({
|
|
242
|
+
prisma,
|
|
243
|
+
polling: {
|
|
244
|
+
interval: 1_000,
|
|
245
|
+
batchSize: 100,
|
|
246
|
+
maxConcurrency: 200,
|
|
247
|
+
drainWhileBacklogged: true,
|
|
248
|
+
maxDrainLoopsPerPoll: 10,
|
|
249
|
+
},
|
|
250
|
+
workerObserver: {
|
|
251
|
+
onPollComplete(result) {
|
|
252
|
+
metrics.count('webhook.worker.claimed', result.claimed);
|
|
253
|
+
metrics.count('webhook.worker.sent', result.sent);
|
|
254
|
+
metrics.count('webhook.worker.retried', result.retried);
|
|
255
|
+
metrics.gauge('webhook.worker.poll.duration_ms', result.durationMs);
|
|
256
|
+
},
|
|
257
|
+
onDeliveryComplete(result) {
|
|
258
|
+
metrics.count(`webhook.delivery.${result.status}`, 1);
|
|
259
|
+
},
|
|
260
|
+
onPollError(error) {
|
|
261
|
+
logger.error({ error }, 'webhook worker poll failed');
|
|
262
|
+
},
|
|
263
|
+
},
|
|
264
|
+
});
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
Observer callbacks are best-effort. Exceptions thrown by observer callbacks are logged and do not fail delivery processing.
|
|
268
|
+
|
|
269
|
+
Backlog diagnostics are available on repository implementations that support `getBacklogSummary()`:
|
|
270
|
+
|
|
271
|
+
```ts
|
|
272
|
+
const summary = await deliveryRepository.getBacklogSummary?.();
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
The summary includes `pendingCount`, `sendingCount`, `runnablePendingCount`, `oldestPendingAgeMs`, and `oldestRunnableAgeMs`.
|
|
276
|
+
|
|
277
|
+
Webhook receiver responses are classified before scheduling another attempt:
|
|
278
|
+
|
|
279
|
+
| Response | Behavior |
|
|
280
|
+
|---|---|
|
|
281
|
+
| `2xx` | Mark delivery `SENT` |
|
|
282
|
+
| `3xx` | Retry while attempts remain |
|
|
283
|
+
| `408`, `409`, `425`, `429` | Retry while attempts remain |
|
|
284
|
+
| Other `4xx` | Mark delivery `FAILED` after the current attempt |
|
|
285
|
+
| `5xx` | Retry while attempts remain |
|
|
286
|
+
| Network, DNS, timeout, or dispatch error | Retry while attempts remain |
|
|
287
|
+
|
|
288
|
+
Permanent `4xx` failures still record the response status/body, append a failed attempt log, count as a circuit-breaker failure, clear `nextAttemptAt`, and trigger `onDeliveryFailed`.
|
|
289
|
+
|
|
290
|
+
**Delivery failure classification.** `DeliveryFailedContext.failureKind` categorizes why a delivery was abandoned after retries are exhausted or a non-retryable receiver response is observed:
|
|
217
291
|
|
|
218
292
|
| `failureKind` | When | Extra fields |
|
|
219
293
|
|---|---|---|
|
|
@@ -221,6 +295,12 @@ The retry schedule is fixed exponential (`30s`, `5m`, `30m`, `2h`, `24h`). Use `
|
|
|
221
295
|
| `dispatch_error` | Dispatcher threw (DNS failure, ECONNREFUSED, timeout) | — |
|
|
222
296
|
| `http_error` | Endpoint responded with non-2xx status | `responseStatus` |
|
|
223
297
|
|
|
298
|
+
Retryable HTTP responses only trigger `onDeliveryFailed` after the attempt budget is exhausted. Non-retryable receiver responses trigger it after the current attempt. Callback errors are logged and never change persisted delivery state.
|
|
299
|
+
|
|
300
|
+
`onDeliveryRetryScheduled` fires earlier, after a retryable failed attempt has been persisted with its next attempt time. It is intended for internal observability and includes the same failure classification fields as `DeliveryFailedContext`, plus `nextAttemptAt`.
|
|
301
|
+
|
|
302
|
+
`onEndpointDegraded` fires only when `circuitBreaker.degradedThreshold` is configured, the endpoint is still active, and the consecutive failure count exactly reaches that degraded threshold. It does not replace `onEndpointDisabled`, which still fires only when the endpoint transitions from active to inactive at `failureThreshold`.
|
|
303
|
+
|
|
224
304
|
```ts
|
|
225
305
|
onDeliveryFailed: (ctx) => {
|
|
226
306
|
if (ctx.failureKind === 'url_validation') {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ClaimedDelivery, PendingDelivery, WebhookDeliveryRepository, WebhookTransaction } from '../ports/webhook-delivery.repository';
|
|
1
|
+
import { ClaimedDelivery, DeliveryBacklogSummary, PendingDelivery, WebhookDeliveryRepository, WebhookTransaction } from '../ports/webhook-delivery.repository';
|
|
2
2
|
import { DeliveryAttemptRecord, DeliveryLogFilters, DeliveryRecord, DeliveryResult } from '../interfaces/webhook-delivery.interface';
|
|
3
3
|
import { WebhookSecretVault } from '../ports/webhook-secret-vault';
|
|
4
4
|
type AttemptLogClient = {
|
|
@@ -16,6 +16,7 @@ export declare class PrismaDeliveryRepository implements WebhookDeliveryReposito
|
|
|
16
16
|
markFailed(deliveryId: string, attempts: number, result: DeliveryResult): Promise<void>;
|
|
17
17
|
markRetry(deliveryId: string, attempts: number, nextAt: Date, result: DeliveryResult): Promise<void>;
|
|
18
18
|
recoverStaleSending(stalenessMinutes: number): Promise<number>;
|
|
19
|
+
getBacklogSummary(): Promise<DeliveryBacklogSummary>;
|
|
19
20
|
getDeliveryLogs(endpointId: string, filters?: DeliveryLogFilters): Promise<DeliveryRecord[]>;
|
|
20
21
|
getDeliveryAttempts(deliveryId: string): Promise<DeliveryAttemptRecord[]>;
|
|
21
22
|
retryDelivery(deliveryId: string): Promise<boolean>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prisma-delivery.repository.d.ts","sourceRoot":"","sources":["../../src/adapters/prisma-delivery.repository.ts"],"names":[],"mappings":"AACA,OAAO,EACL,eAAe,EACf,eAAe,EACf,yBAAyB,EACzB,kBAAkB,EACnB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,cAAc,EACd,cAAc,EACf,MAAM,0CAA0C,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAGnE,KAAK,gBAAgB,GAAG;IACtB,WAAW,EAAE,CAAC,CAAC,GAAG,OAAO,EACvB,OAAO,EAAE,oBAAoB,EAC7B,GAAG,MAAM,EAAE,OAAO,EAAE,KACjB,OAAO,CAAC,CAAC,CAAC,CAAC;CACjB,CAAC;
|
|
1
|
+
{"version":3,"file":"prisma-delivery.repository.d.ts","sourceRoot":"","sources":["../../src/adapters/prisma-delivery.repository.ts"],"names":[],"mappings":"AACA,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,eAAe,EACf,yBAAyB,EACzB,kBAAkB,EACnB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,cAAc,EACd,cAAc,EACf,MAAM,0CAA0C,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAGnE,KAAK,gBAAgB,GAAG;IACtB,WAAW,EAAE,CAAC,CAAC,GAAG,OAAO,EACvB,OAAO,EAAE,oBAAoB,EAC7B,GAAG,MAAM,EAAE,OAAO,EAAE,KACjB,OAAO,CAAC,CAAC,CAAC,CAAC;CACjB,CAAC;AA4CF,qBACa,wBAAyB,YAAW,yBAAyB;IAEtE,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,GAAG;IAC9B,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,kBAAkB;gBAD1B,MAAM,EAAE,GAAG,EACX,KAAK,CAAC,EAAE,kBAAkB,YAAA;IAGzC,6BAA6B,CACjC,EAAE,EAAE,GAAG,EACP,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EAAE,EACrB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC;IAqCV,gBAAgB,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,kBAAkB,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAI3E,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IAqBrE,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IA4CnE,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAcrF,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBvF,SAAS,CACb,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,IAAI,EACZ,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,IAAI,CAAC;IAeV,mBAAmB,CAAC,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IA2D9D,iBAAiB,IAAI,OAAO,CAAC,sBAAsB,CAAC;IAwEpD,eAAe,CACnB,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC,cAAc,EAAE,CAAC;IAmDtB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,EAAE,CAAC;IAkBzE,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAQnD,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;cA+B5D,gBAAgB,CAC9B,MAAM,EAAE,gBAAgB,EACxB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,SAAS,GAAG,MAAM,GAAG,QAAQ,EACrC,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,IAAI,CAAC;CA0BjB"}
|
|
@@ -31,6 +31,13 @@ function truncateAttemptResponseBody(body) {
|
|
|
31
31
|
responseBodyTruncated: true,
|
|
32
32
|
};
|
|
33
33
|
}
|
|
34
|
+
function normalizeBacklogNumber(value, field) {
|
|
35
|
+
const normalized = Number(value);
|
|
36
|
+
if (!Number.isFinite(normalized)) {
|
|
37
|
+
throw new Error(`Invalid backlog summary ${field}: ${String(value)}`);
|
|
38
|
+
}
|
|
39
|
+
return normalized;
|
|
40
|
+
}
|
|
34
41
|
let PrismaDeliveryRepository = class PrismaDeliveryRepository {
|
|
35
42
|
prisma;
|
|
36
43
|
vault;
|
|
@@ -145,6 +152,7 @@ let PrismaDeliveryRepository = class PrismaDeliveryRepository {
|
|
|
145
152
|
UPDATE webhook_deliveries
|
|
146
153
|
SET status = 'FAILED', attempts = ${attempts},
|
|
147
154
|
last_attempt_at = NOW(), completed_at = NOW(),
|
|
155
|
+
next_attempt_at = NULL,
|
|
148
156
|
response_status = ${result.statusCode ?? null},
|
|
149
157
|
response_body = ${result.body ?? null},
|
|
150
158
|
latency_ms = ${result.latencyMs},
|
|
@@ -193,7 +201,7 @@ let PrismaDeliveryRepository = class PrismaDeliveryRepository {
|
|
|
193
201
|
last_error = ${STALE_SENDING_RECOVERY_ERROR}
|
|
194
202
|
WHERE status = 'SENDING'
|
|
195
203
|
AND claimed_at IS NOT NULL
|
|
196
|
-
AND claimed_at
|
|
204
|
+
AND claimed_at < NOW() - ${interval}::interval
|
|
197
205
|
RETURNING id, attempts, status
|
|
198
206
|
),
|
|
199
207
|
attempt_log AS (
|
|
@@ -225,6 +233,66 @@ let PrismaDeliveryRepository = class PrismaDeliveryRepository {
|
|
|
225
233
|
LEFT JOIN attempt_log ON attempt_log.delivery_id = recovered.id`;
|
|
226
234
|
return recovered.length;
|
|
227
235
|
}
|
|
236
|
+
async getBacklogSummary() {
|
|
237
|
+
const rows = await this.prisma.$queryRaw `
|
|
238
|
+
WITH backlog AS (
|
|
239
|
+
SELECT
|
|
240
|
+
COUNT(*) FILTER (WHERE status = 'PENDING') AS "pendingCount",
|
|
241
|
+
COUNT(*) FILTER (WHERE status = 'SENDING') AS "sendingCount",
|
|
242
|
+
COUNT(*) FILTER (
|
|
243
|
+
WHERE status = 'PENDING'
|
|
244
|
+
AND next_attempt_at <= NOW()
|
|
245
|
+
) AS "runnablePendingCount",
|
|
246
|
+
MIN(next_attempt_at) FILTER (
|
|
247
|
+
WHERE status = 'PENDING'
|
|
248
|
+
) AS "oldestPendingAt",
|
|
249
|
+
MIN(next_attempt_at) FILTER (
|
|
250
|
+
WHERE status = 'PENDING'
|
|
251
|
+
AND next_attempt_at <= NOW()
|
|
252
|
+
) AS "oldestRunnableAt"
|
|
253
|
+
FROM webhook_deliveries
|
|
254
|
+
)
|
|
255
|
+
SELECT
|
|
256
|
+
"pendingCount",
|
|
257
|
+
"sendingCount",
|
|
258
|
+
"runnablePendingCount",
|
|
259
|
+
CASE
|
|
260
|
+
WHEN "oldestPendingAt" IS NULL THEN NULL
|
|
261
|
+
ELSE GREATEST(
|
|
262
|
+
0,
|
|
263
|
+
FLOOR(EXTRACT(EPOCH FROM (NOW() - "oldestPendingAt")) * 1000)::bigint
|
|
264
|
+
)
|
|
265
|
+
END AS "oldestPendingAgeMs",
|
|
266
|
+
CASE
|
|
267
|
+
WHEN "oldestRunnableAt" IS NULL THEN NULL
|
|
268
|
+
ELSE GREATEST(
|
|
269
|
+
0,
|
|
270
|
+
FLOOR(EXTRACT(EPOCH FROM (NOW() - "oldestRunnableAt")) * 1000)::bigint
|
|
271
|
+
)
|
|
272
|
+
END AS "oldestRunnableAgeMs"
|
|
273
|
+
FROM backlog`;
|
|
274
|
+
const row = rows[0];
|
|
275
|
+
if (!row) {
|
|
276
|
+
return {
|
|
277
|
+
pendingCount: 0,
|
|
278
|
+
sendingCount: 0,
|
|
279
|
+
runnablePendingCount: 0,
|
|
280
|
+
oldestPendingAgeMs: null,
|
|
281
|
+
oldestRunnableAgeMs: null,
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
return {
|
|
285
|
+
pendingCount: normalizeBacklogNumber(row.pendingCount, 'pendingCount'),
|
|
286
|
+
sendingCount: normalizeBacklogNumber(row.sendingCount, 'sendingCount'),
|
|
287
|
+
runnablePendingCount: normalizeBacklogNumber(row.runnablePendingCount, 'runnablePendingCount'),
|
|
288
|
+
oldestPendingAgeMs: row.oldestPendingAgeMs == null
|
|
289
|
+
? null
|
|
290
|
+
: normalizeBacklogNumber(row.oldestPendingAgeMs, 'oldestPendingAgeMs'),
|
|
291
|
+
oldestRunnableAgeMs: row.oldestRunnableAgeMs == null
|
|
292
|
+
? null
|
|
293
|
+
: normalizeBacklogNumber(row.oldestRunnableAgeMs, 'oldestRunnableAgeMs'),
|
|
294
|
+
};
|
|
295
|
+
}
|
|
228
296
|
async getDeliveryLogs(endpointId, filters) {
|
|
229
297
|
const conditions = ['d.endpoint_id = $1::uuid'];
|
|
230
298
|
const values = [endpointId];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prisma-delivery.repository.js","sourceRoot":"","sources":["../../src/adapters/prisma-delivery.repository.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA4C;
|
|
1
|
+
{"version":3,"file":"prisma-delivery.repository.js","sourceRoot":"","sources":["../../src/adapters/prisma-delivery.repository.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -16,7 +16,7 @@ export { WebhookDeliveryAdminService } from './webhook.delivery-admin.service';
|
|
|
16
16
|
export { WebhookAdminService } from './webhook.admin.service';
|
|
17
17
|
export type { WebhookEventRepository } from './ports/webhook-event.repository';
|
|
18
18
|
export type { WebhookEndpointRepository, ResolvedCreateEndpointInput, ResolvedRotateEndpointSecretInput, } from './ports/webhook-endpoint.repository';
|
|
19
|
-
export type { WebhookDeliveryRepository, ClaimedDelivery, PendingDelivery, WebhookTransaction, } from './ports/webhook-delivery.repository';
|
|
19
|
+
export type { WebhookDeliveryRepository, ClaimedDelivery, DeliveryBacklogSummary, PendingDelivery, WebhookTransaction, } from './ports/webhook-delivery.repository';
|
|
20
20
|
export type { WebhookHttpClient } from './ports/webhook-http-client';
|
|
21
21
|
export type { WebhookSecretVault } from './ports/webhook-secret-vault';
|
|
22
22
|
export { PrismaEventRepository } from './adapters/prisma-event.repository';
|
|
@@ -24,7 +24,7 @@ export { PrismaEndpointRepository } from './adapters/prisma-endpoint.repository'
|
|
|
24
24
|
export { PrismaDeliveryRepository } from './adapters/prisma-delivery.repository';
|
|
25
25
|
export { FetchHttpClient } from './adapters/fetch-http-client';
|
|
26
26
|
export { PlaintextSecretVault } from './adapters/plaintext-secret-vault';
|
|
27
|
-
export type { WebhookModuleOptions, WebhookModuleAsyncOptions, WebhookOptionsFactory, DeliveryOptions, CircuitBreakerOptions, PollingOptions, DeliveryFailedContext, DeliveryFailureKind, EndpointDisabledContext, } from './interfaces/webhook-options.interface';
|
|
27
|
+
export type { WebhookModuleOptions, WebhookModuleAsyncOptions, WebhookOptionsFactory, DeliveryOptions, CircuitBreakerOptions, PollingOptions, WebhookPollContext, WebhookPollResult, WebhookDeliveryProcessingStatus, WebhookDeliveryProcessingResult, WebhookWorkerObserver, DeliveryFailedContext, DeliveryFailureKind, DeliveryRetryScheduledContext, EndpointDisabledContext, EndpointDegradedContext, } from './interfaces/webhook-options.interface';
|
|
28
28
|
export type { EndpointRecord, EndpointRecordWithSecret, CreateEndpointDto, UpdateEndpointDto, RotateEndpointSecretDto, } from './interfaces/webhook-endpoint.interface';
|
|
29
29
|
export type { DeliveryStatus, DeliveryAttemptStatus, DeliveryRecord, DeliveryAttemptRecord, EventRecord, DeliveryResult, DeliveryLogFilters, } from './interfaces/webhook-delivery.interface';
|
|
30
30
|
export { WEBHOOK_MODULE_OPTIONS, WEBHOOK_EVENT_REPOSITORY, WEBHOOK_ENDPOINT_REPOSITORY, WEBHOOK_DELIVERY_REPOSITORY, WEBHOOK_HTTP_CLIENT, WEBHOOK_SECRET_VAULT, DEFAULT_BACKOFF_SCHEDULE, DEFAULT_DELIVERY_TIMEOUT, DEFAULT_MAX_RETRIES, DEFAULT_POLLING_INTERVAL, DEFAULT_POLLING_BATCH_SIZE, DEFAULT_CIRCUIT_BREAKER_THRESHOLD, DEFAULT_CIRCUIT_BREAKER_COOLDOWN_MINUTES, ENDPOINT_DISABLED_REASON_CONSECUTIVE_FAILURES_EXCEEDED, DEFAULT_STALE_SENDING_MINUTES, } from './webhook.constants';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGjD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,6GAA6G;AAC7G,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,6GAA6G;AAC7G,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,6GAA6G;AAC7G,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,KAAK,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACxE,6GAA6G;AAC7G,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAG/C,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAC/E,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAC/E,4IAA4I;AAC5I,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAG9D,YAAY,EAAE,sBAAsB,EAAE,MAAM,kCAAkC,CAAC;AAC/E,YAAY,EACV,yBAAyB,EACzB,2BAA2B,EAC3B,iCAAiC,GAClC,MAAM,qCAAqC,CAAC;AAC7C,YAAY,EACV,yBAAyB,EACzB,eAAe,EACf,eAAe,EACf,kBAAkB,GACnB,MAAM,qCAAqC,CAAC;AAC7C,YAAY,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AACrE,YAAY,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAGvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAC3E,OAAO,EAAE,wBAAwB,EAAE,MAAM,uCAAuC,CAAC;AACjF,OAAO,EAAE,wBAAwB,EAAE,MAAM,uCAAuC,CAAC;AACjF,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAGzE,YAAY,EACV,oBAAoB,EACpB,yBAAyB,EACzB,qBAAqB,EACrB,eAAe,EACf,qBAAqB,EACrB,cAAc,EACd,qBAAqB,EACrB,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,wCAAwC,CAAC;AAGhD,YAAY,EACV,cAAc,EACd,wBAAwB,EACxB,iBAAiB,EACjB,iBAAiB,EACjB,uBAAuB,GACxB,MAAM,yCAAyC,CAAC;AAEjD,YAAY,EACV,cAAc,EACd,qBAAqB,EACrB,cAAc,EACd,qBAAqB,EACrB,WAAW,EACX,cAAc,EACd,kBAAkB,GACnB,MAAM,yCAAyC,CAAC;AAGjD,OAAO,EACL,sBAAsB,EACtB,wBAAwB,EACxB,2BAA2B,EAC3B,2BAA2B,EAC3B,mBAAmB,EACnB,oBAAoB,EACpB,wBAAwB,EACxB,wBAAwB,EACxB,mBAAmB,EACnB,wBAAwB,EACxB,0BAA0B,EAC1B,iCAAiC,EACjC,wCAAwC,EACxC,sDAAsD,EACtD,6BAA6B,GAC9B,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAGlE,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,yBAAyB,EACzB,KAAK,0BAA0B,GAChC,MAAM,yBAAyB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGjD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,6GAA6G;AAC7G,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,6GAA6G;AAC7G,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,6GAA6G;AAC7G,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,KAAK,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACxE,6GAA6G;AAC7G,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAG/C,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAC/E,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAC/E,4IAA4I;AAC5I,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAG9D,YAAY,EAAE,sBAAsB,EAAE,MAAM,kCAAkC,CAAC;AAC/E,YAAY,EACV,yBAAyB,EACzB,2BAA2B,EAC3B,iCAAiC,GAClC,MAAM,qCAAqC,CAAC;AAC7C,YAAY,EACV,yBAAyB,EACzB,eAAe,EACf,sBAAsB,EACtB,eAAe,EACf,kBAAkB,GACnB,MAAM,qCAAqC,CAAC;AAC7C,YAAY,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AACrE,YAAY,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAGvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAC3E,OAAO,EAAE,wBAAwB,EAAE,MAAM,uCAAuC,CAAC;AACjF,OAAO,EAAE,wBAAwB,EAAE,MAAM,uCAAuC,CAAC;AACjF,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAGzE,YAAY,EACV,oBAAoB,EACpB,yBAAyB,EACzB,qBAAqB,EACrB,eAAe,EACf,qBAAqB,EACrB,cAAc,EACd,kBAAkB,EAClB,iBAAiB,EACjB,+BAA+B,EAC/B,+BAA+B,EAC/B,qBAAqB,EACrB,qBAAqB,EACrB,mBAAmB,EACnB,6BAA6B,EAC7B,uBAAuB,EACvB,uBAAuB,GACxB,MAAM,wCAAwC,CAAC;AAGhD,YAAY,EACV,cAAc,EACd,wBAAwB,EACxB,iBAAiB,EACjB,iBAAiB,EACjB,uBAAuB,GACxB,MAAM,yCAAyC,CAAC;AAEjD,YAAY,EACV,cAAc,EACd,qBAAqB,EACrB,cAAc,EACd,qBAAqB,EACrB,WAAW,EACX,cAAc,EACd,kBAAkB,GACnB,MAAM,yCAAyC,CAAC;AAGjD,OAAO,EACL,sBAAsB,EACtB,wBAAwB,EACxB,2BAA2B,EAC3B,2BAA2B,EAC3B,mBAAmB,EACnB,oBAAoB,EACpB,wBAAwB,EACxB,wBAAwB,EACxB,mBAAmB,EACnB,wBAAwB,EACxB,0BAA0B,EAC1B,iCAAiC,EACjC,wCAAwC,EACxC,sDAAsD,EACtD,6BAA6B,GAC9B,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAGlE,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,yBAAyB,EACzB,KAAK,0BAA0B,GAChC,MAAM,yBAAyB,CAAC"}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,SAAS;AACT,mDAAiD;AAAxC,+GAAA,aAAa,OAAA;AAEtB,gBAAgB;AAChB,qDAAmD;AAA1C,iHAAA,cAAc,OAAA;AACvB,6GAA6G;AAC7G,qEAAkE;AAAzD,gIAAA,qBAAqB,OAAA;AAC9B,6GAA6G;AAC7G,2DAAyD;AAAhD,uHAAA,iBAAiB,OAAA;AAC1B,6GAA6G;AAC7G,+DAA4D;AAAnD,0HAAA,kBAAkB,OAAA;AAC3B,mDAAwE;AAA/D,+GAAA,aAAa,OAAA;AACtB,6GAA6G;AAC7G,qEAAkE;AAAzD,gIAAA,qBAAqB,OAAA;AAC9B,iDAA+C;AAAtC,6GAAA,YAAY,OAAA;AAErB,iBAAiB;AACjB,mFAA+E;AAAtE,6IAAA,2BAA2B,OAAA;AACpC,mFAA+E;AAAtE,6IAAA,2BAA2B,OAAA;AACpC,4IAA4I;AAC5I,iEAA8D;AAArD,4HAAA,mBAAmB,OAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,SAAS;AACT,mDAAiD;AAAxC,+GAAA,aAAa,OAAA;AAEtB,gBAAgB;AAChB,qDAAmD;AAA1C,iHAAA,cAAc,OAAA;AACvB,6GAA6G;AAC7G,qEAAkE;AAAzD,gIAAA,qBAAqB,OAAA;AAC9B,6GAA6G;AAC7G,2DAAyD;AAAhD,uHAAA,iBAAiB,OAAA;AAC1B,6GAA6G;AAC7G,+DAA4D;AAAnD,0HAAA,kBAAkB,OAAA;AAC3B,mDAAwE;AAA/D,+GAAA,aAAa,OAAA;AACtB,6GAA6G;AAC7G,qEAAkE;AAAzD,gIAAA,qBAAqB,OAAA;AAC9B,iDAA+C;AAAtC,6GAAA,YAAY,OAAA;AAErB,iBAAiB;AACjB,mFAA+E;AAAtE,6IAAA,2BAA2B,OAAA;AACpC,mFAA+E;AAAtE,6IAAA,2BAA2B,OAAA;AACpC,4IAA4I;AAC5I,iEAA8D;AAArD,4HAAA,mBAAmB,OAAA;AAmB5B,mBAAmB;AACnB,8EAA2E;AAAlE,gIAAA,qBAAqB,OAAA;AAC9B,oFAAiF;AAAxE,sIAAA,wBAAwB,OAAA;AACjC,oFAAiF;AAAxE,sIAAA,wBAAwB,OAAA;AACjC,kEAA+D;AAAtD,oHAAA,eAAe,OAAA;AACxB,4EAAyE;AAAhE,8HAAA,oBAAoB,OAAA;AAyC7B,qBAAqB;AACrB,yDAgB6B;AAf3B,2HAAA,sBAAsB,OAAA;AACtB,6HAAA,wBAAwB,OAAA;AACxB,gIAAA,2BAA2B,OAAA;AAC3B,gIAAA,2BAA2B,OAAA;AAC3B,wHAAA,mBAAmB,OAAA;AACnB,yHAAA,oBAAoB,OAAA;AACpB,6HAAA,wBAAwB,OAAA;AACxB,6HAAA,wBAAwB,OAAA;AACxB,wHAAA,mBAAmB,OAAA;AACnB,6HAAA,wBAAwB,OAAA;AACxB,+HAAA,0BAA0B,OAAA;AAC1B,sIAAA,iCAAiC,OAAA;AACjC,6IAAA,wCAAwC,OAAA;AACxC,2JAAA,sDAAsD,OAAA;AACtD,kIAAA,6BAA6B,OAAA;AAI/B,iBAAiB;AACjB,iEAKiC;AAJ/B,2HAAA,kBAAkB,OAAA;AAClB,+HAAA,sBAAsB,OAAA;AACtB,kIAAA,yBAAyB,OAAA"}
|
|
@@ -15,6 +15,7 @@ export interface DeliveryOptions {
|
|
|
15
15
|
}
|
|
16
16
|
export interface CircuitBreakerOptions {
|
|
17
17
|
failureThreshold?: number;
|
|
18
|
+
degradedThreshold?: number;
|
|
18
19
|
cooldownMinutes?: number;
|
|
19
20
|
}
|
|
20
21
|
export interface PollingOptions {
|
|
@@ -24,9 +25,60 @@ export interface PollingOptions {
|
|
|
24
25
|
batchSize?: number;
|
|
25
26
|
/** Minutes before a SENDING delivery is considered stale and reset to PENDING. Default: 5 */
|
|
26
27
|
staleSendingMinutes?: number;
|
|
28
|
+
/** Maximum delivery dispatches in flight per worker process. Default: batchSize */
|
|
29
|
+
maxConcurrency?: number;
|
|
30
|
+
/** When true, one poll cycle keeps claiming while backlog and capacity remain. Default: false */
|
|
31
|
+
drainWhileBacklogged?: boolean;
|
|
32
|
+
/** Maximum claim/drain loops inside one poll cycle. Default: 1, or 10 when drainWhileBacklogged is true */
|
|
33
|
+
maxDrainLoopsPerPoll?: number;
|
|
34
|
+
/** Optional sleep between continuous drain loops. Default: 0 */
|
|
35
|
+
drainLoopDelayMs?: number;
|
|
36
|
+
}
|
|
37
|
+
export interface WebhookPollContext {
|
|
38
|
+
batchSize: number;
|
|
39
|
+
maxConcurrency: number;
|
|
40
|
+
drainWhileBacklogged: boolean;
|
|
41
|
+
maxDrainLoopsPerPoll: number;
|
|
42
|
+
drainLoopDelayMs: number;
|
|
43
|
+
activeDeliveries: number;
|
|
44
|
+
}
|
|
45
|
+
export interface WebhookPollResult {
|
|
46
|
+
claimed: number;
|
|
47
|
+
enriched: number;
|
|
48
|
+
sent: number;
|
|
49
|
+
failed: number;
|
|
50
|
+
retried: number;
|
|
51
|
+
recoveredStale: number;
|
|
52
|
+
durationMs: number;
|
|
53
|
+
loops: number;
|
|
54
|
+
}
|
|
55
|
+
export type WebhookDeliveryProcessingStatus = 'sent' | 'failed' | 'retried';
|
|
56
|
+
export interface WebhookDeliveryProcessingResult {
|
|
57
|
+
deliveryId: string;
|
|
58
|
+
endpointId: string;
|
|
59
|
+
eventId: string;
|
|
60
|
+
tenantId: string | null;
|
|
61
|
+
attempts: number;
|
|
62
|
+
maxAttempts: number;
|
|
63
|
+
status: WebhookDeliveryProcessingStatus;
|
|
64
|
+
responseStatus: number | null;
|
|
65
|
+
lastError: string | null;
|
|
66
|
+
latencyMs: number | null;
|
|
67
|
+
nextAttemptAt?: Date;
|
|
68
|
+
failureKind?: DeliveryFailureKind;
|
|
69
|
+
validationReason?: WebhookUrlValidationReason;
|
|
70
|
+
validationUrl?: string;
|
|
71
|
+
resolvedIp?: string;
|
|
72
|
+
}
|
|
73
|
+
export interface WebhookWorkerObserver {
|
|
74
|
+
onPollStart?(context: WebhookPollContext): void;
|
|
75
|
+
onPollComplete?(result: WebhookPollResult): void;
|
|
76
|
+
onDeliveryComplete?(result: WebhookDeliveryProcessingResult): void;
|
|
77
|
+
onPollError?(error: unknown): void;
|
|
27
78
|
}
|
|
28
79
|
/**
|
|
29
|
-
* Category of failure that caused the delivery to
|
|
80
|
+
* Category of failure that caused the delivery to stop after retry exhaustion
|
|
81
|
+
* or after a non-retryable receiver response.
|
|
30
82
|
* - `url_validation`: SSRF defense rejected the URL (private/loopback/link-local/etc.)
|
|
31
83
|
* - `dispatch_error`: dispatcher threw an exception (timeout, ECONNREFUSED, etc.)
|
|
32
84
|
* - `http_error`: endpoint responded with a non-2xx status code
|
|
@@ -51,6 +103,26 @@ export interface DeliveryFailedContext {
|
|
|
51
103
|
/** Set only when `failureKind === 'url_validation'` and DNS resolution was involved. */
|
|
52
104
|
resolvedIp?: string;
|
|
53
105
|
}
|
|
106
|
+
export interface DeliveryRetryScheduledContext {
|
|
107
|
+
deliveryId: string;
|
|
108
|
+
endpointId: string;
|
|
109
|
+
eventId: string;
|
|
110
|
+
/** Null when the endpoint is not scoped to a tenant. */
|
|
111
|
+
tenantId: string | null;
|
|
112
|
+
attempts: number;
|
|
113
|
+
maxAttempts: number;
|
|
114
|
+
nextAttemptAt: Date;
|
|
115
|
+
lastError: string | null;
|
|
116
|
+
responseStatus: number | null;
|
|
117
|
+
/** High-level classification for the failed attempt that scheduled the retry. */
|
|
118
|
+
failureKind?: DeliveryFailureKind;
|
|
119
|
+
/** Set only when `failureKind === 'url_validation'` — structured reason from `WebhookUrlValidationError`. */
|
|
120
|
+
validationReason?: WebhookUrlValidationReason;
|
|
121
|
+
/** Set only when `failureKind === 'url_validation'` — URL that triggered validation failure. */
|
|
122
|
+
validationUrl?: string;
|
|
123
|
+
/** Set only when `failureKind === 'url_validation'` and DNS resolution was involved. */
|
|
124
|
+
resolvedIp?: string;
|
|
125
|
+
}
|
|
54
126
|
export interface EndpointDisabledContext {
|
|
55
127
|
endpointId: string;
|
|
56
128
|
/** Null when the endpoint is not scoped to a tenant. */
|
|
@@ -59,12 +131,24 @@ export interface EndpointDisabledContext {
|
|
|
59
131
|
reason: EndpointDisabledReason;
|
|
60
132
|
consecutiveFailures: number;
|
|
61
133
|
}
|
|
134
|
+
export interface EndpointDegradedContext {
|
|
135
|
+
endpointId: string;
|
|
136
|
+
/** Null when the endpoint is not scoped to a tenant. */
|
|
137
|
+
tenantId: string | null;
|
|
138
|
+
url: string;
|
|
139
|
+
reason: 'consecutive_failures_degraded';
|
|
140
|
+
consecutiveFailures: number;
|
|
141
|
+
degradedThreshold: number;
|
|
142
|
+
failureThreshold: number;
|
|
143
|
+
}
|
|
62
144
|
export interface WebhookModuleOptions<TPrisma = unknown> {
|
|
63
145
|
/** PrismaClient instance — used by default Prisma adapters. Not needed if all custom repositories are provided. */
|
|
64
146
|
prisma?: TPrisma;
|
|
65
147
|
delivery?: DeliveryOptions;
|
|
66
148
|
circuitBreaker?: CircuitBreakerOptions;
|
|
67
149
|
polling?: PollingOptions;
|
|
150
|
+
/** Best-effort worker lifecycle and delivery metrics observer. Observer errors are logged and ignored. */
|
|
151
|
+
workerObserver?: WebhookWorkerObserver;
|
|
68
152
|
/** Allow private/internal URLs for endpoints. Only enable in development/testing. Default: false */
|
|
69
153
|
allowPrivateUrls?: boolean;
|
|
70
154
|
/** Custom port overrides — provide these to replace default Prisma/fetch adapters. */
|
|
@@ -74,8 +158,12 @@ export interface WebhookModuleOptions<TPrisma = unknown> {
|
|
|
74
158
|
httpClient?: WebhookHttpClient;
|
|
75
159
|
/** Custom secret vault for encrypting/decrypting endpoint signing secrets at rest. Default: PlaintextSecretVault (no-op). */
|
|
76
160
|
secretVault?: WebhookSecretVault;
|
|
77
|
-
/** Called when a delivery exhausts
|
|
161
|
+
/** Called when a delivery exhausts retry attempts or receives a non-retryable response. Fire-and-forget — errors are logged, not propagated. */
|
|
78
162
|
onDeliveryFailed?: (context: DeliveryFailedContext) => void | Promise<void>;
|
|
163
|
+
/** Called after a retriable failed attempt is persisted with a next attempt time. Fire-and-forget — errors are logged, not propagated. */
|
|
164
|
+
onDeliveryRetryScheduled?: (context: DeliveryRetryScheduledContext) => void | Promise<void>;
|
|
165
|
+
/** Called when consecutive failures reach the configured degraded threshold before endpoint disablement. Fire-and-forget — errors are logged, not propagated. */
|
|
166
|
+
onEndpointDegraded?: (context: EndpointDegradedContext) => void | Promise<void>;
|
|
79
167
|
/** Called when the circuit breaker disables an endpoint. Fire-and-forget — errors are logged, not propagated. */
|
|
80
168
|
onEndpointDisabled?: (context: EndpointDisabledContext) => void | Promise<void>;
|
|
81
169
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webhook-options.interface.d.ts","sourceRoot":"","sources":["../../src/interfaces/webhook-options.interface.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,cAAc,EACd,yBAAyB,EACzB,IAAI,EACL,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAC;AAC3E,OAAO,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAC;AACjF,OAAO,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAC;AACjF,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAC;AAEtE,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wFAAwF;IACxF,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,qBAAqB;IACpC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC7B,sIAAsI;IACtI,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6FAA6F;IAC7F,mBAAmB,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"webhook-options.interface.d.ts","sourceRoot":"","sources":["../../src/interfaces/webhook-options.interface.ts"],"names":[],"mappings":"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"}
|
|
@@ -21,6 +21,13 @@ export interface PendingDelivery extends ClaimedDelivery {
|
|
|
21
21
|
eventType: string;
|
|
22
22
|
payload: Record<string, unknown>;
|
|
23
23
|
}
|
|
24
|
+
export interface DeliveryBacklogSummary {
|
|
25
|
+
pendingCount: number;
|
|
26
|
+
sendingCount: number;
|
|
27
|
+
runnablePendingCount: number;
|
|
28
|
+
oldestPendingAgeMs: number | null;
|
|
29
|
+
oldestRunnableAgeMs: number | null;
|
|
30
|
+
}
|
|
24
31
|
export interface WebhookDeliveryRepository {
|
|
25
32
|
/**
|
|
26
33
|
* Creates queued delivery rows inside the provided transaction.
|
|
@@ -37,6 +44,7 @@ export interface WebhookDeliveryRepository {
|
|
|
37
44
|
markRetry(deliveryId: string, attempts: number, nextAt: Date, result: DeliveryResult): Promise<void>;
|
|
38
45
|
/** @returns number of stale SENDING deliveries recovered or failed. */
|
|
39
46
|
recoverStaleSending(stalenessMinutes: number): Promise<number>;
|
|
47
|
+
getBacklogSummary?(): Promise<DeliveryBacklogSummary>;
|
|
40
48
|
getDeliveryLogs(endpointId: string, filters?: DeliveryLogFilters): Promise<DeliveryRecord[]>;
|
|
41
49
|
/** @returns attempts sorted by attemptNumber ASC. */
|
|
42
50
|
getDeliveryAttempts(deliveryId: string): Promise<DeliveryAttemptRecord[]>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webhook-delivery.repository.d.ts","sourceRoot":"","sources":["../../src/ports/webhook-delivery.repository.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,cAAc,EACd,cAAc,EACf,MAAM,0CAA0C,CAAC;AAElD,OAAO,CAAC,MAAM,uBAAuB,EAAE,OAAO,MAAM,CAAC;AAErD,+DAA+D;AAC/D,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,CAAC,CAAC,uBAAuB,CAAC,EAAE,oBAAoB,CAAC;CAC1D,CAAC;AAEF,0FAA0F;AAC1F,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,4GAA4G;AAC5G,MAAM,WAAW,eAAgB,SAAQ,eAAe;IACtD,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,yBAAyB;IACxC;;;OAGG;IACH,6BAA6B,CAC3B,EAAE,EAAE,kBAAkB,EACtB,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EAAE,EACrB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjB,8GAA8G;IAC9G,gBAAgB,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,kBAAkB,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAE5E,sGAAsG;IACtG,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;IACtE,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;IAEpE,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtF,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxF,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAErG,uEAAuE;IACvE,mBAAmB,CAAC,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/D,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;IAC7F,qDAAqD;IACrD,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,EAAE,CAAC,CAAC;IAC1E,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACpD,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACxE"}
|
|
1
|
+
{"version":3,"file":"webhook-delivery.repository.d.ts","sourceRoot":"","sources":["../../src/ports/webhook-delivery.repository.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,9 +9,14 @@ export declare class WebhookCircuitBreaker {
|
|
|
9
9
|
private readonly options;
|
|
10
10
|
private readonly logger;
|
|
11
11
|
private readonly failureThreshold;
|
|
12
|
+
private readonly degradedThreshold;
|
|
12
13
|
private readonly cooldownMinutes;
|
|
13
14
|
constructor(endpointRepo: WebhookEndpointRepository, options: WebhookModuleOptions);
|
|
14
15
|
afterDelivery(endpointId: string, success: boolean, meta: DeliveryEndpointMeta): Promise<void>;
|
|
16
|
+
private maybeFireEndpointDegradedHook;
|
|
17
|
+
private fireEndpointDegradedHook;
|
|
18
|
+
private fireEndpointDisabledHook;
|
|
19
|
+
private logError;
|
|
15
20
|
recoverEligibleEndpoints(): Promise<number>;
|
|
16
21
|
}
|
|
17
22
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webhook.circuit-breaker.d.ts","sourceRoot":"","sources":["../src/webhook.circuit-breaker.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,oBAAoB,EAAE,MAAM,wCAAwC,CAAC;AAC9E,OAAO,EAAE,yBAAyB,EAAE,MAAM,qCAAqC,CAAC;AAEhF,UAAU,oBAAoB;IAC5B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,GAAG,EAAE,MAAM,CAAC;CACb;AAED,qBACa,qBAAqB;
|
|
1
|
+
{"version":3,"file":"webhook.circuit-breaker.d.ts","sourceRoot":"","sources":["../src/webhook.circuit-breaker.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,oBAAoB,EAAE,MAAM,wCAAwC,CAAC;AAC9E,OAAO,EAAE,yBAAyB,EAAE,MAAM,qCAAqC,CAAC;AAEhF,UAAU,oBAAoB;IAC5B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,GAAG,EAAE,MAAM,CAAC;CACb;AAED,qBACa,qBAAqB;IAQ9B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAE7B,OAAO,CAAC,QAAQ,CAAC,OAAO;IAT1B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0C;IACjE,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAqB;IACvD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;gBAItB,YAAY,EAAE,yBAAyB,EAEvC,OAAO,EAAE,oBAAoB;IAS1C,aAAa,CACjB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,oBAAoB,GACzB,OAAO,CAAC,IAAI,CAAC;YAyBF,6BAA6B;IA6B3C,OAAO,CAAC,wBAAwB;IA2BhC,OAAO,CAAC,wBAAwB;IAwBhC,OAAO,CAAC,QAAQ;IAQV,wBAAwB,IAAI,OAAO,CAAC,MAAM,CAAC;CASlD"}
|
|
@@ -21,42 +21,101 @@ let WebhookCircuitBreaker = WebhookCircuitBreaker_1 = class WebhookCircuitBreake
|
|
|
21
21
|
options;
|
|
22
22
|
logger = new common_1.Logger(WebhookCircuitBreaker_1.name);
|
|
23
23
|
failureThreshold;
|
|
24
|
+
degradedThreshold;
|
|
24
25
|
cooldownMinutes;
|
|
25
26
|
constructor(endpointRepo, options) {
|
|
26
27
|
this.endpointRepo = endpointRepo;
|
|
27
28
|
this.options = options;
|
|
28
29
|
this.failureThreshold =
|
|
29
30
|
options.circuitBreaker?.failureThreshold ?? webhook_constants_1.DEFAULT_CIRCUIT_BREAKER_THRESHOLD;
|
|
31
|
+
this.degradedThreshold = options.circuitBreaker?.degradedThreshold;
|
|
30
32
|
this.cooldownMinutes =
|
|
31
33
|
options.circuitBreaker?.cooldownMinutes ?? webhook_constants_1.DEFAULT_CIRCUIT_BREAKER_COOLDOWN_MINUTES;
|
|
32
34
|
}
|
|
33
35
|
async afterDelivery(endpointId, success, meta) {
|
|
34
36
|
if (success) {
|
|
35
37
|
await this.endpointRepo.resetFailures(endpointId);
|
|
38
|
+
return;
|
|
36
39
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
void Promise.resolve(this.options.onEndpointDisabled({
|
|
48
|
-
endpointId,
|
|
49
|
-
tenantId: meta.tenantId,
|
|
50
|
-
url: meta.url,
|
|
51
|
-
reason: webhook_constants_1.ENDPOINT_DISABLED_REASON_CONSECUTIVE_FAILURES_EXCEEDED,
|
|
52
|
-
consecutiveFailures: failures,
|
|
53
|
-
})).catch((hookError) => {
|
|
54
|
-
this.logger.error(`onEndpointDisabled callback error: ${hookError}`);
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
}
|
|
40
|
+
const failures = await this.endpointRepo.incrementFailures(endpointId);
|
|
41
|
+
await this.maybeFireEndpointDegradedHook(endpointId, failures, meta);
|
|
42
|
+
if (failures >= this.failureThreshold) {
|
|
43
|
+
const disabled = await this.endpointRepo.disableEndpoint(endpointId, webhook_constants_1.ENDPOINT_DISABLED_REASON_CONSECUTIVE_FAILURES_EXCEEDED);
|
|
44
|
+
if (!disabled)
|
|
45
|
+
return;
|
|
46
|
+
this.logger.warn(`Endpoint ${endpointId} disabled: ${webhook_constants_1.ENDPOINT_DISABLED_REASON_CONSECUTIVE_FAILURES_EXCEEDED} (threshold=${this.failureThreshold})`);
|
|
47
|
+
// Fire only on active->inactive transition to prevent duplicate notifications
|
|
48
|
+
// and still notify if a prior disable attempt failed at the exact threshold.
|
|
49
|
+
this.fireEndpointDisabledHook(endpointId, failures, meta);
|
|
58
50
|
}
|
|
59
51
|
}
|
|
52
|
+
async maybeFireEndpointDegradedHook(endpointId, failures, meta) {
|
|
53
|
+
if (!this.options.onEndpointDegraded)
|
|
54
|
+
return;
|
|
55
|
+
const degradedThreshold = this.degradedThreshold;
|
|
56
|
+
if (degradedThreshold === undefined)
|
|
57
|
+
return;
|
|
58
|
+
if (degradedThreshold >= this.failureThreshold)
|
|
59
|
+
return;
|
|
60
|
+
if (failures !== degradedThreshold)
|
|
61
|
+
return;
|
|
62
|
+
let endpoint;
|
|
63
|
+
try {
|
|
64
|
+
endpoint = await this.endpointRepo.getEndpoint(endpointId);
|
|
65
|
+
}
|
|
66
|
+
catch (hookError) {
|
|
67
|
+
this.logError('onEndpointDegraded lookup error', hookError);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
if (!endpoint?.active)
|
|
71
|
+
return;
|
|
72
|
+
this.fireEndpointDegradedHook(endpointId, failures, degradedThreshold, meta);
|
|
73
|
+
}
|
|
74
|
+
fireEndpointDegradedHook(endpointId, failures, degradedThreshold, meta) {
|
|
75
|
+
if (!this.options.onEndpointDegraded)
|
|
76
|
+
return;
|
|
77
|
+
try {
|
|
78
|
+
void Promise.resolve(this.options.onEndpointDegraded({
|
|
79
|
+
endpointId,
|
|
80
|
+
tenantId: meta.tenantId,
|
|
81
|
+
url: meta.url,
|
|
82
|
+
reason: 'consecutive_failures_degraded',
|
|
83
|
+
consecutiveFailures: failures,
|
|
84
|
+
degradedThreshold,
|
|
85
|
+
failureThreshold: this.failureThreshold,
|
|
86
|
+
})).catch((hookError) => {
|
|
87
|
+
this.logError('onEndpointDegraded callback error', hookError);
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
catch (hookError) {
|
|
91
|
+
this.logError('onEndpointDegraded callback error', hookError);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
fireEndpointDisabledHook(endpointId, failures, meta) {
|
|
95
|
+
if (!this.options.onEndpointDisabled)
|
|
96
|
+
return;
|
|
97
|
+
try {
|
|
98
|
+
void Promise.resolve(this.options.onEndpointDisabled({
|
|
99
|
+
endpointId,
|
|
100
|
+
tenantId: meta.tenantId,
|
|
101
|
+
url: meta.url,
|
|
102
|
+
reason: webhook_constants_1.ENDPOINT_DISABLED_REASON_CONSECUTIVE_FAILURES_EXCEEDED,
|
|
103
|
+
consecutiveFailures: failures,
|
|
104
|
+
})).catch((hookError) => {
|
|
105
|
+
this.logError('onEndpointDisabled callback error', hookError);
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
catch (hookError) {
|
|
109
|
+
this.logError('onEndpointDisabled callback error', hookError);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
logError(message, error) {
|
|
113
|
+
if (error instanceof Error) {
|
|
114
|
+
this.logger.error(`${message}: ${error.message}`, error.stack);
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
this.logger.error(`${message}: ${String(error)}`);
|
|
118
|
+
}
|
|
60
119
|
async recoverEligibleEndpoints() {
|
|
61
120
|
const count = await this.endpointRepo.recoverEligibleEndpoints(this.cooldownMinutes);
|
|
62
121
|
if (count > 0) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webhook.circuit-breaker.js","sourceRoot":"","sources":["../src/webhook.circuit-breaker.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAA4D;AAC5D,2DAM6B;AAUtB,IAAM,qBAAqB,6BAA3B,MAAM,qBAAqB;
|
|
1
|
+
{"version":3,"file":"webhook.circuit-breaker.js","sourceRoot":"","sources":["../src/webhook.circuit-breaker.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,16 +12,34 @@ export declare class WebhookDeliveryWorker implements OnModuleDestroy {
|
|
|
12
12
|
private readonly options;
|
|
13
13
|
private readonly logger;
|
|
14
14
|
private readonly batchSize;
|
|
15
|
+
private readonly maxConcurrency;
|
|
16
|
+
private readonly drainWhileBacklogged;
|
|
17
|
+
private readonly maxDrainLoopsPerPoll;
|
|
18
|
+
private readonly drainLoopDelayMs;
|
|
15
19
|
private readonly staleSendingMinutes;
|
|
20
|
+
private readonly activeDeliveryTasks;
|
|
16
21
|
private isShuttingDown;
|
|
17
22
|
private isPolling;
|
|
18
23
|
private activePollCycle;
|
|
19
24
|
private activeDeliveries;
|
|
20
25
|
constructor(deliveryRepo: WebhookDeliveryRepository, dispatcher: WebhookDispatcher, retryPolicy: WebhookRetryPolicy, circuitBreaker: WebhookCircuitBreaker, options: WebhookModuleOptions);
|
|
21
26
|
poll(): Promise<void>;
|
|
27
|
+
private sleep;
|
|
28
|
+
private waitForAvailableCapacity;
|
|
22
29
|
private runPollCycle;
|
|
30
|
+
private scheduleDelivery;
|
|
23
31
|
private processDelivery;
|
|
32
|
+
private positiveInteger;
|
|
33
|
+
private nonNegativeInteger;
|
|
34
|
+
private availableCapacity;
|
|
35
|
+
private createPollContext;
|
|
36
|
+
private createEmptyPollResult;
|
|
37
|
+
private notifyObserver;
|
|
38
|
+
private createDeliveryProcessingResult;
|
|
39
|
+
private updateCircuitBreakerAfterDelivery;
|
|
40
|
+
private fireDeliveryRetryScheduledHook;
|
|
24
41
|
private fireDeliveryFailedHook;
|
|
42
|
+
private classifyExceptionFailure;
|
|
25
43
|
private classifyResultFailure;
|
|
26
44
|
private logError;
|
|
27
45
|
onModuleDestroy(): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webhook.delivery-worker.d.ts","sourceRoot":"","sources":["../src/webhook.delivery-worker.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8B,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC7E,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAO5D,OAAO,
|
|
1
|
+
{"version":3,"file":"webhook.delivery-worker.d.ts","sourceRoot":"","sources":["../src/webhook.delivery-worker.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8B,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC7E,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAO5D,OAAO,EAGL,oBAAoB,EAGrB,MAAM,wCAAwC,CAAC;AAEhD,OAAO,EAEL,yBAAyB,EAC1B,MAAM,qCAAqC,CAAC;AAc7C,qBACa,qBAAsB,YAAW,eAAe;IAkBzD,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAE/B,OAAO,CAAC,QAAQ,CAAC,OAAO;IAtB1B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0C;IACjE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAU;IAC/C,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAS;IAC9C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAS;IAC7C,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAEhC;IACJ,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,eAAe,CAA8B;IACrD,OAAO,CAAC,gBAAgB,CAAK;gBAIV,YAAY,EAAE,yBAAyB,EACvC,UAAU,EAAE,iBAAiB,EAC7B,WAAW,EAAE,kBAAkB,EAC/B,cAAc,EAAE,qBAAqB,EAErC,OAAO,EAAE,oBAAoB;IAwB1C,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;YAiBb,KAAK;YAKL,wBAAwB;YAUxB,YAAY;IA+D1B,OAAO,CAAC,gBAAgB;YAmBV,eAAe;IA+J7B,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,kBAAkB;IAM1B,OAAO,CAAC,iBAAiB;IAIzB,OAAO,CAAC,iBAAiB;IAWzB,OAAO,CAAC,qBAAqB;IAa7B,OAAO,CAAC,cAAc;IA8BtB,OAAO,CAAC,8BAA8B;YAwBxB,iCAAiC;IAkB/C,OAAO,CAAC,8BAA8B;IAgCtC,OAAO,CAAC,sBAAsB;IA8B9B,OAAO,CAAC,wBAAwB;IAgBhC,OAAO,CAAC,qBAAqB;IAM7B,OAAO,CAAC,QAAQ;IAQV,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;CAqBvC"}
|
|
@@ -19,6 +19,7 @@ const webhook_circuit_breaker_1 = require("./webhook.circuit-breaker");
|
|
|
19
19
|
const webhook_dispatcher_1 = require("./webhook.dispatcher");
|
|
20
20
|
const webhook_retry_policy_1 = require("./webhook.retry-policy");
|
|
21
21
|
const webhook_constants_1 = require("./webhook.constants");
|
|
22
|
+
const webhook_retry_classifier_1 = require("./webhook.retry-classifier");
|
|
22
23
|
const webhook_url_validator_1 = require("./webhook.url-validator");
|
|
23
24
|
let WebhookDeliveryWorker = WebhookDeliveryWorker_1 = class WebhookDeliveryWorker {
|
|
24
25
|
deliveryRepo;
|
|
@@ -28,7 +29,12 @@ let WebhookDeliveryWorker = WebhookDeliveryWorker_1 = class WebhookDeliveryWorke
|
|
|
28
29
|
options;
|
|
29
30
|
logger = new common_1.Logger(WebhookDeliveryWorker_1.name);
|
|
30
31
|
batchSize;
|
|
32
|
+
maxConcurrency;
|
|
33
|
+
drainWhileBacklogged;
|
|
34
|
+
maxDrainLoopsPerPoll;
|
|
35
|
+
drainLoopDelayMs;
|
|
31
36
|
staleSendingMinutes;
|
|
37
|
+
activeDeliveryTasks = new Set();
|
|
32
38
|
isShuttingDown = false;
|
|
33
39
|
isPolling = false;
|
|
34
40
|
activePollCycle = null;
|
|
@@ -39,7 +45,12 @@ let WebhookDeliveryWorker = WebhookDeliveryWorker_1 = class WebhookDeliveryWorke
|
|
|
39
45
|
this.retryPolicy = retryPolicy;
|
|
40
46
|
this.circuitBreaker = circuitBreaker;
|
|
41
47
|
this.options = options;
|
|
42
|
-
this.batchSize = options.polling?.batchSize
|
|
48
|
+
this.batchSize = this.positiveInteger(options.polling?.batchSize, webhook_constants_1.DEFAULT_POLLING_BATCH_SIZE);
|
|
49
|
+
this.maxConcurrency = this.positiveInteger(options.polling?.maxConcurrency, this.batchSize);
|
|
50
|
+
this.drainWhileBacklogged =
|
|
51
|
+
options.polling?.drainWhileBacklogged ?? false;
|
|
52
|
+
this.maxDrainLoopsPerPoll = this.positiveInteger(options.polling?.maxDrainLoopsPerPoll, this.drainWhileBacklogged ? 10 : 1);
|
|
53
|
+
this.drainLoopDelayMs = this.nonNegativeInteger(options.polling?.drainLoopDelayMs, 0);
|
|
43
54
|
this.staleSendingMinutes =
|
|
44
55
|
options.polling?.staleSendingMinutes ?? webhook_constants_1.DEFAULT_STALE_SENDING_MINUTES;
|
|
45
56
|
}
|
|
@@ -61,48 +72,118 @@ let WebhookDeliveryWorker = WebhookDeliveryWorker_1 = class WebhookDeliveryWorke
|
|
|
61
72
|
this.isPolling = false;
|
|
62
73
|
}
|
|
63
74
|
}
|
|
75
|
+
async sleep(ms) {
|
|
76
|
+
if (ms <= 0)
|
|
77
|
+
return;
|
|
78
|
+
await new Promise((resolve) => setTimeout(resolve, ms));
|
|
79
|
+
}
|
|
80
|
+
async waitForAvailableCapacity() {
|
|
81
|
+
while (!this.isShuttingDown &&
|
|
82
|
+
this.availableCapacity() <= 0 &&
|
|
83
|
+
this.activeDeliveryTasks.size > 0) {
|
|
84
|
+
await Promise.race(this.activeDeliveryTasks);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
64
87
|
async runPollCycle() {
|
|
88
|
+
const startedAt = Date.now();
|
|
89
|
+
const pollResult = this.createEmptyPollResult();
|
|
90
|
+
const pollTasks = [];
|
|
91
|
+
this.notifyObserver('onPollStart', this.createPollContext());
|
|
65
92
|
try {
|
|
66
93
|
await this.circuitBreaker.recoverEligibleEndpoints();
|
|
67
94
|
// Recover deliveries stuck in SENDING from crashed workers
|
|
68
95
|
const recovered = await this.deliveryRepo.recoverStaleSending(this.staleSendingMinutes);
|
|
96
|
+
pollResult.recoveredStale = recovered;
|
|
69
97
|
if (recovered > 0) {
|
|
70
98
|
this.logger.warn(`Recovered ${recovered} stale SENDING deliveries`);
|
|
71
99
|
}
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
100
|
+
const maxLoops = this.drainWhileBacklogged
|
|
101
|
+
? this.maxDrainLoopsPerPoll
|
|
102
|
+
: 1;
|
|
103
|
+
for (let loop = 0; loop < maxLoops && !this.isShuttingDown; loop++) {
|
|
104
|
+
if (loop > 0) {
|
|
105
|
+
await this.sleep(this.drainLoopDelayMs);
|
|
106
|
+
if (this.isShuttingDown)
|
|
107
|
+
break;
|
|
108
|
+
}
|
|
109
|
+
await this.waitForAvailableCapacity();
|
|
110
|
+
if (this.isShuttingDown)
|
|
111
|
+
break;
|
|
112
|
+
const claimSize = Math.min(this.batchSize, this.availableCapacity());
|
|
113
|
+
if (claimSize <= 0)
|
|
114
|
+
break;
|
|
115
|
+
const claimed = await this.deliveryRepo.claimPendingDeliveries(claimSize);
|
|
116
|
+
if (claimed.length === 0)
|
|
117
|
+
break;
|
|
118
|
+
pollResult.claimed += claimed.length;
|
|
119
|
+
pollResult.loops++;
|
|
120
|
+
const deliveries = await this.deliveryRepo.enrichDeliveries(claimed.map((d) => d.id));
|
|
121
|
+
pollResult.enriched += deliveries.length;
|
|
122
|
+
for (const delivery of deliveries) {
|
|
123
|
+
pollTasks.push(this.scheduleDelivery(delivery, pollResult));
|
|
124
|
+
}
|
|
125
|
+
if (!this.drainWhileBacklogged)
|
|
126
|
+
break;
|
|
127
|
+
}
|
|
128
|
+
await Promise.all(pollTasks);
|
|
77
129
|
}
|
|
78
130
|
catch (error) {
|
|
131
|
+
this.notifyObserver('onPollError', error);
|
|
79
132
|
this.logError('Poll cycle failed', error);
|
|
80
133
|
}
|
|
134
|
+
finally {
|
|
135
|
+
pollResult.durationMs = Date.now() - startedAt;
|
|
136
|
+
this.notifyObserver('onPollComplete', pollResult);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
scheduleDelivery(delivery, pollResult) {
|
|
140
|
+
const task = this.processDelivery(delivery).then((result) => {
|
|
141
|
+
if (result) {
|
|
142
|
+
pollResult[result.status]++;
|
|
143
|
+
this.notifyObserver('onDeliveryComplete', result);
|
|
144
|
+
}
|
|
145
|
+
return result;
|
|
146
|
+
});
|
|
147
|
+
this.activeDeliveryTasks.add(task);
|
|
148
|
+
task.finally(() => {
|
|
149
|
+
this.activeDeliveryTasks.delete(task);
|
|
150
|
+
});
|
|
151
|
+
return task;
|
|
81
152
|
}
|
|
82
153
|
async processDelivery(delivery) {
|
|
83
154
|
this.activeDeliveries++;
|
|
155
|
+
let dispatchReturned = false;
|
|
84
156
|
try {
|
|
85
157
|
const result = await this.dispatcher.dispatch(delivery);
|
|
158
|
+
dispatchReturned = true;
|
|
86
159
|
const newAttempts = delivery.attempts + 1;
|
|
87
160
|
// Persist delivery state — if this fails, catch resets to PENDING (safe)
|
|
161
|
+
const retryable = (0, webhook_retry_classifier_1.isRetryableDeliveryResult)(result);
|
|
88
162
|
if (result.success) {
|
|
89
163
|
await this.deliveryRepo.markSent(delivery.id, newAttempts, result);
|
|
164
|
+
await this.updateCircuitBreakerAfterDelivery(delivery, true);
|
|
165
|
+
return this.createDeliveryProcessingResult(delivery, newAttempts, 'sent', result);
|
|
166
|
+
}
|
|
167
|
+
else if (!retryable) {
|
|
168
|
+
await this.deliveryRepo.markFailed(delivery.id, newAttempts, result);
|
|
169
|
+
this.logger.warn(`Delivery ${delivery.id} failed with non-retryable HTTP status ${result.statusCode} (${newAttempts}/${delivery.maxAttempts})`);
|
|
170
|
+
this.fireDeliveryFailedHook(delivery, newAttempts, result.error ?? null, result.statusCode ?? null, this.classifyResultFailure(result));
|
|
171
|
+
await this.updateCircuitBreakerAfterDelivery(delivery, false);
|
|
172
|
+
return this.createDeliveryProcessingResult(delivery, newAttempts, 'failed', result, this.classifyResultFailure(result));
|
|
90
173
|
}
|
|
91
174
|
else if (newAttempts >= delivery.maxAttempts) {
|
|
92
175
|
await this.deliveryRepo.markFailed(delivery.id, newAttempts, result);
|
|
93
176
|
this.logger.warn(`Delivery ${delivery.id} exhausted retries (${newAttempts}/${delivery.maxAttempts})`);
|
|
94
177
|
this.fireDeliveryFailedHook(delivery, newAttempts, result.error ?? null, result.statusCode ?? null, this.classifyResultFailure(result));
|
|
178
|
+
await this.updateCircuitBreakerAfterDelivery(delivery, false);
|
|
179
|
+
return this.createDeliveryProcessingResult(delivery, newAttempts, 'failed', result, this.classifyResultFailure(result));
|
|
95
180
|
}
|
|
96
181
|
else {
|
|
97
182
|
const nextAt = this.retryPolicy.nextAttemptAt(newAttempts);
|
|
98
183
|
await this.deliveryRepo.markRetry(delivery.id, newAttempts, nextAt, result);
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
await this.circuitBreaker.afterDelivery(delivery.endpointId, result.success, { tenantId: delivery.tenantId, url: delivery.url });
|
|
103
|
-
}
|
|
104
|
-
catch (cbError) {
|
|
105
|
-
this.logError(`Circuit breaker update failed for ${delivery.endpointId}`, cbError);
|
|
184
|
+
this.fireDeliveryRetryScheduledHook(delivery, newAttempts, nextAt, result.error ?? null, result.statusCode ?? null, this.classifyResultFailure(result));
|
|
185
|
+
await this.updateCircuitBreakerAfterDelivery(delivery, false);
|
|
186
|
+
return this.createDeliveryProcessingResult(delivery, newAttempts, 'retried', result, this.classifyResultFailure(result), nextAt);
|
|
106
187
|
}
|
|
107
188
|
}
|
|
108
189
|
catch (error) {
|
|
@@ -115,48 +196,163 @@ let WebhookDeliveryWorker = WebhookDeliveryWorker_1 = class WebhookDeliveryWorke
|
|
|
115
196
|
latencyMs: 0,
|
|
116
197
|
error: error instanceof Error ? error.message : String(error),
|
|
117
198
|
};
|
|
199
|
+
const meta = this.classifyExceptionFailure(error, delivery);
|
|
200
|
+
const dispatcherException = !dispatchReturned;
|
|
118
201
|
if (newAttempts >= delivery.maxAttempts) {
|
|
119
202
|
await this.deliveryRepo.markFailed(delivery.id, newAttempts, errorResult);
|
|
120
203
|
this.logger.warn(`Delivery ${delivery.id} exhausted retries on exception (${newAttempts}/${delivery.maxAttempts})`);
|
|
121
|
-
const meta = error instanceof webhook_url_validator_1.WebhookUrlValidationError
|
|
122
|
-
? {
|
|
123
|
-
failureKind: 'url_validation',
|
|
124
|
-
validationReason: error.reason,
|
|
125
|
-
validationUrl: error.url ?? delivery.url,
|
|
126
|
-
resolvedIp: error.resolvedIp,
|
|
127
|
-
}
|
|
128
|
-
: { failureKind: 'dispatch_error' };
|
|
129
204
|
this.fireDeliveryFailedHook(delivery, newAttempts, errorResult.error ?? null, null, meta);
|
|
205
|
+
if (dispatcherException) {
|
|
206
|
+
await this.updateCircuitBreakerAfterDelivery(delivery, false);
|
|
207
|
+
}
|
|
208
|
+
return this.createDeliveryProcessingResult(delivery, newAttempts, 'failed', errorResult, meta);
|
|
130
209
|
}
|
|
131
210
|
else {
|
|
132
211
|
const nextAt = this.retryPolicy.nextAttemptAt(newAttempts);
|
|
133
212
|
await this.deliveryRepo.markRetry(delivery.id, newAttempts, nextAt, errorResult);
|
|
213
|
+
if (dispatcherException) {
|
|
214
|
+
this.fireDeliveryRetryScheduledHook(delivery, newAttempts, nextAt, errorResult.error ?? null, null, meta);
|
|
215
|
+
await this.updateCircuitBreakerAfterDelivery(delivery, false);
|
|
216
|
+
}
|
|
217
|
+
return this.createDeliveryProcessingResult(delivery, newAttempts, 'retried', errorResult, meta, nextAt);
|
|
134
218
|
}
|
|
135
219
|
}
|
|
136
220
|
catch (fallbackError) {
|
|
137
221
|
this.logError(`Delivery ${delivery.id} fallback error handling failed`, fallbackError);
|
|
222
|
+
return null;
|
|
138
223
|
}
|
|
139
224
|
}
|
|
140
225
|
finally {
|
|
141
226
|
this.activeDeliveries--;
|
|
142
227
|
}
|
|
143
228
|
}
|
|
144
|
-
|
|
145
|
-
|
|
229
|
+
positiveInteger(value, fallback) {
|
|
230
|
+
return typeof value === 'number' && Number.isInteger(value) && value > 0
|
|
231
|
+
? value
|
|
232
|
+
: fallback;
|
|
233
|
+
}
|
|
234
|
+
nonNegativeInteger(value, fallback) {
|
|
235
|
+
return typeof value === 'number' && Number.isInteger(value) && value >= 0
|
|
236
|
+
? value
|
|
237
|
+
: fallback;
|
|
238
|
+
}
|
|
239
|
+
availableCapacity() {
|
|
240
|
+
return Math.max(0, this.maxConcurrency - this.activeDeliveryTasks.size);
|
|
241
|
+
}
|
|
242
|
+
createPollContext() {
|
|
243
|
+
return {
|
|
244
|
+
batchSize: this.batchSize,
|
|
245
|
+
maxConcurrency: this.maxConcurrency,
|
|
246
|
+
drainWhileBacklogged: this.drainWhileBacklogged,
|
|
247
|
+
maxDrainLoopsPerPoll: this.maxDrainLoopsPerPoll,
|
|
248
|
+
drainLoopDelayMs: this.drainLoopDelayMs,
|
|
249
|
+
activeDeliveries: this.activeDeliveries,
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
createEmptyPollResult() {
|
|
253
|
+
return {
|
|
254
|
+
claimed: 0,
|
|
255
|
+
enriched: 0,
|
|
256
|
+
sent: 0,
|
|
257
|
+
failed: 0,
|
|
258
|
+
retried: 0,
|
|
259
|
+
recoveredStale: 0,
|
|
260
|
+
durationMs: 0,
|
|
261
|
+
loops: 0,
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
notifyObserver(callbackName, payload) {
|
|
265
|
+
const callback = this.options.workerObserver?.[callbackName];
|
|
266
|
+
if (!callback)
|
|
146
267
|
return;
|
|
147
|
-
|
|
268
|
+
try {
|
|
269
|
+
void Promise.resolve(callback(payload)).catch((observerError) => {
|
|
270
|
+
this.logError(`workerObserver.${String(callbackName)} callback error`, observerError);
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
catch (observerError) {
|
|
274
|
+
this.logError(`workerObserver.${String(callbackName)} callback error`, observerError);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
createDeliveryProcessingResult(delivery, attempts, status, result, meta = {}, nextAttemptAt) {
|
|
278
|
+
return {
|
|
148
279
|
deliveryId: delivery.id,
|
|
149
280
|
endpointId: delivery.endpointId,
|
|
150
281
|
eventId: delivery.eventId,
|
|
151
282
|
tenantId: delivery.tenantId,
|
|
152
283
|
attempts,
|
|
153
284
|
maxAttempts: delivery.maxAttempts,
|
|
154
|
-
|
|
155
|
-
responseStatus,
|
|
285
|
+
status,
|
|
286
|
+
responseStatus: result.statusCode ?? null,
|
|
287
|
+
lastError: result.error ?? null,
|
|
288
|
+
latencyMs: result.latencyMs ?? null,
|
|
289
|
+
...(nextAttemptAt ? { nextAttemptAt } : {}),
|
|
156
290
|
...meta,
|
|
157
|
-
}
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
async updateCircuitBreakerAfterDelivery(delivery, success) {
|
|
294
|
+
try {
|
|
295
|
+
await this.circuitBreaker.afterDelivery(delivery.endpointId, success, { tenantId: delivery.tenantId, url: delivery.url });
|
|
296
|
+
}
|
|
297
|
+
catch (cbError) {
|
|
298
|
+
this.logError(`Circuit breaker update failed for ${delivery.endpointId}`, cbError);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
fireDeliveryRetryScheduledHook(delivery, attempts, nextAttemptAt, lastError, responseStatus, meta = {}) {
|
|
302
|
+
if (!this.options.onDeliveryRetryScheduled)
|
|
303
|
+
return;
|
|
304
|
+
try {
|
|
305
|
+
void Promise.resolve(this.options.onDeliveryRetryScheduled({
|
|
306
|
+
deliveryId: delivery.id,
|
|
307
|
+
endpointId: delivery.endpointId,
|
|
308
|
+
eventId: delivery.eventId,
|
|
309
|
+
tenantId: delivery.tenantId,
|
|
310
|
+
attempts,
|
|
311
|
+
maxAttempts: delivery.maxAttempts,
|
|
312
|
+
nextAttemptAt,
|
|
313
|
+
lastError,
|
|
314
|
+
responseStatus,
|
|
315
|
+
...meta,
|
|
316
|
+
})).catch((hookError) => {
|
|
317
|
+
this.logError('onDeliveryRetryScheduled callback error', hookError);
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
catch (hookError) {
|
|
321
|
+
this.logError('onDeliveryRetryScheduled callback error', hookError);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
fireDeliveryFailedHook(delivery, attempts, lastError, responseStatus, meta = {}) {
|
|
325
|
+
if (!this.options.onDeliveryFailed)
|
|
326
|
+
return;
|
|
327
|
+
try {
|
|
328
|
+
void Promise.resolve(this.options.onDeliveryFailed({
|
|
329
|
+
deliveryId: delivery.id,
|
|
330
|
+
endpointId: delivery.endpointId,
|
|
331
|
+
eventId: delivery.eventId,
|
|
332
|
+
tenantId: delivery.tenantId,
|
|
333
|
+
attempts,
|
|
334
|
+
maxAttempts: delivery.maxAttempts,
|
|
335
|
+
lastError,
|
|
336
|
+
responseStatus,
|
|
337
|
+
...meta,
|
|
338
|
+
})).catch((hookError) => {
|
|
339
|
+
this.logError('onDeliveryFailed callback error', hookError);
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
catch (hookError) {
|
|
158
343
|
this.logError('onDeliveryFailed callback error', hookError);
|
|
159
|
-
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
classifyExceptionFailure(error, delivery) {
|
|
347
|
+
if (error instanceof webhook_url_validator_1.WebhookUrlValidationError) {
|
|
348
|
+
return {
|
|
349
|
+
failureKind: 'url_validation',
|
|
350
|
+
validationReason: error.reason,
|
|
351
|
+
validationUrl: error.url ?? delivery.url,
|
|
352
|
+
resolvedIp: error.resolvedIp,
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
return { failureKind: 'dispatch_error' };
|
|
160
356
|
}
|
|
161
357
|
classifyResultFailure(result) {
|
|
162
358
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webhook.delivery-worker.js","sourceRoot":"","sources":["../src/webhook.delivery-worker.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"webhook.delivery-worker.js","sourceRoot":"","sources":["../src/webhook.delivery-worker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhook.retry-classifier.d.ts","sourceRoot":"","sources":["../src/webhook.retry-classifier.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,yCAAyC,CAAC;AAIzE,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAczE"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isRetryableDeliveryResult = isRetryableDeliveryResult;
|
|
4
|
+
const RETRYABLE_CLIENT_ERROR_STATUSES = new Set([408, 409, 425, 429]);
|
|
5
|
+
function isRetryableDeliveryResult(result) {
|
|
6
|
+
if (result.success) {
|
|
7
|
+
return false;
|
|
8
|
+
}
|
|
9
|
+
if (result.statusCode == null) {
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
if (result.statusCode >= 400 && result.statusCode < 500) {
|
|
13
|
+
return RETRYABLE_CLIENT_ERROR_STATUSES.has(result.statusCode);
|
|
14
|
+
}
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=webhook.retry-classifier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhook.retry-classifier.js","sourceRoot":"","sources":["../src/webhook.retry-classifier.ts"],"names":[],"mappings":";;AAIA,8DAcC;AAhBD,MAAM,+BAA+B,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;AAEtE,SAAgB,yBAAyB,CAAC,MAAsB;IAC9D,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,MAAM,CAAC,UAAU,IAAI,IAAI,EAAE,CAAC;QAC9B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,MAAM,CAAC,UAAU,IAAI,GAAG,IAAI,MAAM,CAAC,UAAU,GAAG,GAAG,EAAE,CAAC;QACxD,OAAO,+BAA+B,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAChE,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nestarc/webhook",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"description": "Outbound webhook delivery for NestJS — HMAC signing, exponential retry, circuit breaker, delivery logs, fan-out, Standard Webhooks compatible",
|
|
5
5
|
"author": "nestarc",
|
|
6
6
|
"license": "MIT",
|
|
@@ -77,6 +77,12 @@ CREATE TABLE IF NOT EXISTS webhook_deliveries (
|
|
|
77
77
|
|
|
78
78
|
CREATE INDEX IF NOT EXISTS idx_webhook_deliveries_status_next
|
|
79
79
|
ON webhook_deliveries (status, next_attempt_at);
|
|
80
|
+
CREATE INDEX IF NOT EXISTS webhook_deliveries_runnable_pending_idx
|
|
81
|
+
ON webhook_deliveries (next_attempt_at, id)
|
|
82
|
+
WHERE status = 'PENDING';
|
|
83
|
+
CREATE INDEX IF NOT EXISTS webhook_deliveries_sending_claimed_idx
|
|
84
|
+
ON webhook_deliveries (claimed_at, id)
|
|
85
|
+
WHERE status = 'SENDING';
|
|
80
86
|
CREATE INDEX IF NOT EXISTS idx_webhook_deliveries_endpoint_status
|
|
81
87
|
ON webhook_deliveries (endpoint_id, status);
|
|
82
88
|
CREATE INDEX IF NOT EXISTS idx_webhook_deliveries_event
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
-- @nestarc/webhook v0.12.0 - worker capacity diagnostics indexes
|
|
2
|
+
-- Adds partial indexes for high-volume delivery worker claim and stale recovery paths.
|
|
3
|
+
|
|
4
|
+
CREATE INDEX IF NOT EXISTS webhook_deliveries_runnable_pending_idx
|
|
5
|
+
ON webhook_deliveries (next_attempt_at, id)
|
|
6
|
+
WHERE status = 'PENDING';
|
|
7
|
+
|
|
8
|
+
CREATE INDEX IF NOT EXISTS webhook_deliveries_sending_claimed_idx
|
|
9
|
+
ON webhook_deliveries (claimed_at, id)
|
|
10
|
+
WHERE status = 'SENDING';
|