@fedify/fedify 2.3.0-dev.1114 → 2.3.0-dev.1119
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/dist/{builder-YlEusQth.mjs → builder-Ond_h57y.mjs} +2 -2
- package/dist/compat/transformers.test.mjs +1 -1
- package/dist/{deno-CF3jMgip.mjs → deno-DVsHS7rA.mjs} +1 -1
- package/dist/{docloader-BENj6vQ4.mjs → docloader-WsWfKaE5.mjs} +2 -2
- package/dist/federation/builder.test.mjs +1 -1
- package/dist/federation/handler.test.mjs +2 -2
- package/dist/federation/idempotency.test.mjs +2 -2
- package/dist/federation/metrics.test.d.mts +2 -0
- package/dist/federation/metrics.test.mjs +107 -0
- package/dist/federation/middleware.test.mjs +386 -6
- package/dist/federation/mod.cjs +1 -1
- package/dist/federation/mod.js +1 -1
- package/dist/federation/send.test.mjs +3 -3
- package/dist/federation/webfinger.test.mjs +1 -1
- package/dist/{http-CpzZ9zsb.js → http-CouJSFVK.js} +73 -5
- package/dist/{http-CKCgOPkX.cjs → http-CubOB9wq.cjs} +90 -4
- package/dist/{http-BmOZYc-8.mjs → http-DUV8ysti.mjs} +3 -3
- package/dist/{key-B4I8H5Lc.mjs → key-BoWaYRHm.mjs} +1 -1
- package/dist/{kv-cache-Wc5ezcVW.js → kv-cache-DBNpsneh.js} +1 -1
- package/dist/{kv-cache-DY-XWOqM.cjs → kv-cache-Dz31ATUT.cjs} +1 -1
- package/dist/{ld-B5D5THhl.mjs → ld-B5K1mSuG.mjs} +3 -3
- package/dist/{metrics-ek3ilf6c.mjs → metrics-C4attqv0.mjs} +73 -5
- package/dist/{middleware-EI7OU6BR.mjs → middleware-BDKFRjue.mjs} +1 -1
- package/dist/{middleware-EqTYPG4F.cjs → middleware-CmsDtIHI.cjs} +33 -14
- package/dist/{middleware-CuZbBw-N.js → middleware-Dtjz-hSk.js} +33 -14
- package/dist/{middleware-DlcecZMq.mjs → middleware-t0jC8I99.mjs} +40 -21
- package/dist/mod.cjs +4 -4
- package/dist/mod.js +4 -4
- package/dist/nodeinfo/handler.test.mjs +1 -1
- package/dist/{owner-DO810N24.mjs → owner-hDxI0ufu.mjs} +2 -2
- package/dist/{proof-DIoqrKnX.cjs → proof-BUWfVr6Q.cjs} +1 -1
- package/dist/{proof-BgfyWv7b.mjs → proof-DhVuz4bc.mjs} +3 -3
- package/dist/{proof-Vd8-1EWh.js → proof-n60t8o9P.js} +1 -1
- package/dist/{send-CAYXdUTk.mjs → send-BPhyR5Oo.mjs} +3 -3
- package/dist/sig/http.test.mjs +2 -2
- package/dist/sig/key.test.mjs +1 -1
- package/dist/sig/ld.test.mjs +2 -2
- package/dist/sig/mod.cjs +2 -2
- package/dist/sig/mod.js +2 -2
- package/dist/sig/owner.test.mjs +1 -1
- package/dist/sig/proof.test.mjs +1 -1
- package/dist/utils/docloader.test.mjs +2 -2
- package/dist/utils/mod.cjs +1 -1
- package/dist/utils/mod.js +1 -1
- package/package.json +5 -5
|
@@ -5,7 +5,7 @@ import { r as createRequestContext } from "../context-BAE7AKLA.mjs";
|
|
|
5
5
|
import { t as assertEquals } from "../assert_equals-Ew3jOFa3.mjs";
|
|
6
6
|
import "../std__assert-BTEgfoJo.mjs";
|
|
7
7
|
import { t as MemoryKvStore } from "../kv-QHE0oeM3.mjs";
|
|
8
|
-
import { o as createFederation, s as handleWebFinger } from "../middleware-
|
|
8
|
+
import { o as createFederation, s as handleWebFinger } from "../middleware-t0jC8I99.mjs";
|
|
9
9
|
import { Image, Link, Person, Tombstone } from "@fedify/vocab";
|
|
10
10
|
import { test } from "@fedify/fixture";
|
|
11
11
|
//#region src/federation/webfinger.test.ts
|
|
@@ -10,7 +10,7 @@ import { ATTR_HTTP_REQUEST_HEADER, ATTR_HTTP_REQUEST_METHOD, ATTR_URL_FULL } fro
|
|
|
10
10
|
import { decodeBase64, encodeBase64 } from "byte-encodings/base64";
|
|
11
11
|
//#region deno.json
|
|
12
12
|
var name = "@fedify/fedify";
|
|
13
|
-
var version = "2.3.0-dev.
|
|
13
|
+
var version = "2.3.0-dev.1119+6cc02662";
|
|
14
14
|
//#endregion
|
|
15
15
|
//#region src/sig/accept.ts
|
|
16
16
|
/**
|
|
@@ -168,6 +168,9 @@ var FederationMetrics = class {
|
|
|
168
168
|
queueTaskFailed;
|
|
169
169
|
queueTaskDuration;
|
|
170
170
|
queueTaskInFlight;
|
|
171
|
+
fanoutRecipients;
|
|
172
|
+
inboxActivity;
|
|
173
|
+
outboxActivity;
|
|
171
174
|
constructor(meterProvider) {
|
|
172
175
|
const meter = meterProvider.getMeter(name, version);
|
|
173
176
|
this.deliverySent = meter.createCounter("activitypub.delivery.sent", {
|
|
@@ -262,6 +265,18 @@ var FederationMetrics = class {
|
|
|
262
265
|
description: "Queue tasks currently being processed in this Fedify process.",
|
|
263
266
|
unit: "{task}"
|
|
264
267
|
});
|
|
268
|
+
this.fanoutRecipients = meter.createHistogram("activitypub.fanout.recipients", {
|
|
269
|
+
description: "Number of recipient inboxes produced by an ActivityPub fanout task.",
|
|
270
|
+
unit: "{recipient}"
|
|
271
|
+
});
|
|
272
|
+
this.inboxActivity = meter.createCounter("activitypub.inbox.activity", {
|
|
273
|
+
description: "ActivityPub activities observed at the inbox lifecycle level: queued, processed, retried, rejected, or abandoned.",
|
|
274
|
+
unit: "{activity}"
|
|
275
|
+
});
|
|
276
|
+
this.outboxActivity = meter.createCounter("activitypub.outbox.activity", {
|
|
277
|
+
description: "ActivityPub activities observed at the outbox lifecycle level: queued, retried, or abandoned. Per-recipient delivery counters live on `activitypub.delivery.*`.",
|
|
278
|
+
unit: "{activity}"
|
|
279
|
+
});
|
|
265
280
|
}
|
|
266
281
|
recordDelivery(inbox, durationMs, success, activityType) {
|
|
267
282
|
const deliveryAttributes = {
|
|
@@ -334,7 +349,23 @@ var FederationMetrics = class {
|
|
|
334
349
|
else if (result === "failed") this.queueTaskFailed.add(1, attributes);
|
|
335
350
|
this.queueTaskDuration.record(durationMs, attributes);
|
|
336
351
|
}
|
|
352
|
+
recordFanoutRecipients(recipientCount, activityType) {
|
|
353
|
+
const attributes = {};
|
|
354
|
+
if (activityType != null) attributes["activitypub.activity.type"] = activityType;
|
|
355
|
+
this.fanoutRecipients.record(recipientCount, attributes);
|
|
356
|
+
}
|
|
357
|
+
recordInboxActivity(result, activityType) {
|
|
358
|
+
this.inboxActivity.add(1, buildActivityLifecycleAttributes(result, activityType));
|
|
359
|
+
}
|
|
360
|
+
recordOutboxActivity(result, activityType) {
|
|
361
|
+
this.outboxActivity.add(1, buildActivityLifecycleAttributes(result, activityType));
|
|
362
|
+
}
|
|
337
363
|
};
|
|
364
|
+
function buildActivityLifecycleAttributes(result, activityType) {
|
|
365
|
+
const attributes = { "activitypub.processing.result": result };
|
|
366
|
+
if (activityType != null) attributes["activitypub.activity.type"] = activityType;
|
|
367
|
+
return attributes;
|
|
368
|
+
}
|
|
338
369
|
function buildQueueTaskAttributes(common) {
|
|
339
370
|
const attributes = { "fedify.queue.role": common.role };
|
|
340
371
|
const backend = getQueueBackend(common.queue);
|
|
@@ -364,20 +395,57 @@ function getQueueBackend(queue) {
|
|
|
364
395
|
return name;
|
|
365
396
|
}
|
|
366
397
|
/**
|
|
367
|
-
* Records `fedify.queue.task.enqueued` for an outgoing outbox enqueue
|
|
398
|
+
* Records `fedify.queue.task.enqueued` for an outgoing outbox enqueue and,
|
|
399
|
+
* for the initial attempt, also records
|
|
400
|
+
* `activitypub.outbox.activity{queued}`.
|
|
368
401
|
*
|
|
369
402
|
* Both `Context.sendActivity()` and `OutboxContext.forwardActivity()` enqueue
|
|
370
403
|
* outbox messages with the same metric attributes (role, queue, activity
|
|
371
404
|
* type, attempt), so they share this helper rather than each defining a local
|
|
372
|
-
* closure.
|
|
405
|
+
* closure. Retry enqueues (attempt > 0) intentionally do not record a
|
|
406
|
+
* second `activitypub.outbox.activity{queued}`; retries are reported as
|
|
407
|
+
* `result=retried` from the retry-scheduling site, which has the failure
|
|
408
|
+
* context.
|
|
373
409
|
* @since 2.3.0
|
|
374
410
|
*/
|
|
375
411
|
function recordOutboxEnqueue(meterProvider, outboxQueue, message) {
|
|
376
|
-
getFederationMetrics(meterProvider)
|
|
412
|
+
const metrics = getFederationMetrics(meterProvider);
|
|
413
|
+
metrics.recordQueueTaskEnqueued({
|
|
377
414
|
role: "outbox",
|
|
378
415
|
queue: outboxQueue,
|
|
379
416
|
activityType: message.activityType
|
|
380
417
|
}, message.attempt);
|
|
418
|
+
if (message.attempt === 0) metrics.recordOutboxActivity("queued", message.activityType);
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* Records `activitypub.fanout.recipients` with the number of recipient
|
|
422
|
+
* inboxes a single fanout produced. The histogram is unitless count
|
|
423
|
+
* (one measurement per fanout enqueue). Recipient URLs are deliberately
|
|
424
|
+
* not recorded; only the activity type, when known.
|
|
425
|
+
* @since 2.3.0
|
|
426
|
+
*/
|
|
427
|
+
function recordFanoutRecipients(meterProvider, recipientCount, activityType) {
|
|
428
|
+
getFederationMetrics(meterProvider).recordFanoutRecipients(recipientCount, activityType);
|
|
429
|
+
}
|
|
430
|
+
/**
|
|
431
|
+
* Records one `activitypub.inbox.activity` measurement. The
|
|
432
|
+
* `activitypub.processing.result` attribute is always present;
|
|
433
|
+
* `activitypub.activity.type` is recorded only when Fedify already knows
|
|
434
|
+
* the activity type.
|
|
435
|
+
* @since 2.3.0
|
|
436
|
+
*/
|
|
437
|
+
function recordInboxActivity(meterProvider, result, activityType) {
|
|
438
|
+
getFederationMetrics(meterProvider).recordInboxActivity(result, activityType);
|
|
439
|
+
}
|
|
440
|
+
/**
|
|
441
|
+
* Records one `activitypub.outbox.activity` measurement. The
|
|
442
|
+
* `activitypub.processing.result` attribute is always present;
|
|
443
|
+
* `activitypub.activity.type` is recorded only when Fedify already knows
|
|
444
|
+
* the activity type (it is always known for outbox lifecycle events).
|
|
445
|
+
* @since 2.3.0
|
|
446
|
+
*/
|
|
447
|
+
function recordOutboxActivity(meterProvider, result, activityType) {
|
|
448
|
+
getFederationMetrics(meterProvider).recordOutboxActivity(result, activityType);
|
|
381
449
|
}
|
|
382
450
|
/**
|
|
383
451
|
* Times an awaited public key fetch and records exactly one
|
|
@@ -1876,4 +1944,4 @@ function timingSafeEqual(a, b) {
|
|
|
1876
1944
|
return result === 0;
|
|
1877
1945
|
}
|
|
1878
1946
|
//#endregion
|
|
1879
|
-
export {
|
|
1947
|
+
export { parseAcceptSignature as C, version as E, fulfillAcceptSignature as S, name as T, recordFanoutRecipients as _, verifyRequestDetailed as a, recordOutboxEnqueue as b, fetchKeyDetailed as c, validateCryptoKey as d, getDurationMs as f, measureSignatureKeyFetch as g, isAbortError$1 as h, verifyRequest as i, generateCryptoKeyPair as l, getRemoteHost as m, parseRfc9421SignatureInput as n, exportJwk as o, getFederationMetrics as p, signRequest as r, fetchKey as s, doubleKnock as t, importJwk as u, recordInboxActivity as v, validateAcceptSignature as w, formatAcceptSignature as x, recordOutboxActivity as y };
|
|
@@ -11,7 +11,7 @@ let _opentelemetry_semantic_conventions = require("@opentelemetry/semantic-conve
|
|
|
11
11
|
let byte_encodings_base64 = require("byte-encodings/base64");
|
|
12
12
|
//#region deno.json
|
|
13
13
|
var name = "@fedify/fedify";
|
|
14
|
-
var version = "2.3.0-dev.
|
|
14
|
+
var version = "2.3.0-dev.1119+6cc02662";
|
|
15
15
|
//#endregion
|
|
16
16
|
//#region src/sig/accept.ts
|
|
17
17
|
/**
|
|
@@ -169,6 +169,9 @@ var FederationMetrics = class {
|
|
|
169
169
|
queueTaskFailed;
|
|
170
170
|
queueTaskDuration;
|
|
171
171
|
queueTaskInFlight;
|
|
172
|
+
fanoutRecipients;
|
|
173
|
+
inboxActivity;
|
|
174
|
+
outboxActivity;
|
|
172
175
|
constructor(meterProvider) {
|
|
173
176
|
const meter = meterProvider.getMeter(name, version);
|
|
174
177
|
this.deliverySent = meter.createCounter("activitypub.delivery.sent", {
|
|
@@ -263,6 +266,18 @@ var FederationMetrics = class {
|
|
|
263
266
|
description: "Queue tasks currently being processed in this Fedify process.",
|
|
264
267
|
unit: "{task}"
|
|
265
268
|
});
|
|
269
|
+
this.fanoutRecipients = meter.createHistogram("activitypub.fanout.recipients", {
|
|
270
|
+
description: "Number of recipient inboxes produced by an ActivityPub fanout task.",
|
|
271
|
+
unit: "{recipient}"
|
|
272
|
+
});
|
|
273
|
+
this.inboxActivity = meter.createCounter("activitypub.inbox.activity", {
|
|
274
|
+
description: "ActivityPub activities observed at the inbox lifecycle level: queued, processed, retried, rejected, or abandoned.",
|
|
275
|
+
unit: "{activity}"
|
|
276
|
+
});
|
|
277
|
+
this.outboxActivity = meter.createCounter("activitypub.outbox.activity", {
|
|
278
|
+
description: "ActivityPub activities observed at the outbox lifecycle level: queued, retried, or abandoned. Per-recipient delivery counters live on `activitypub.delivery.*`.",
|
|
279
|
+
unit: "{activity}"
|
|
280
|
+
});
|
|
266
281
|
}
|
|
267
282
|
recordDelivery(inbox, durationMs, success, activityType) {
|
|
268
283
|
const deliveryAttributes = {
|
|
@@ -335,7 +350,23 @@ var FederationMetrics = class {
|
|
|
335
350
|
else if (result === "failed") this.queueTaskFailed.add(1, attributes);
|
|
336
351
|
this.queueTaskDuration.record(durationMs, attributes);
|
|
337
352
|
}
|
|
353
|
+
recordFanoutRecipients(recipientCount, activityType) {
|
|
354
|
+
const attributes = {};
|
|
355
|
+
if (activityType != null) attributes["activitypub.activity.type"] = activityType;
|
|
356
|
+
this.fanoutRecipients.record(recipientCount, attributes);
|
|
357
|
+
}
|
|
358
|
+
recordInboxActivity(result, activityType) {
|
|
359
|
+
this.inboxActivity.add(1, buildActivityLifecycleAttributes(result, activityType));
|
|
360
|
+
}
|
|
361
|
+
recordOutboxActivity(result, activityType) {
|
|
362
|
+
this.outboxActivity.add(1, buildActivityLifecycleAttributes(result, activityType));
|
|
363
|
+
}
|
|
338
364
|
};
|
|
365
|
+
function buildActivityLifecycleAttributes(result, activityType) {
|
|
366
|
+
const attributes = { "activitypub.processing.result": result };
|
|
367
|
+
if (activityType != null) attributes["activitypub.activity.type"] = activityType;
|
|
368
|
+
return attributes;
|
|
369
|
+
}
|
|
339
370
|
function buildQueueTaskAttributes(common) {
|
|
340
371
|
const attributes = { "fedify.queue.role": common.role };
|
|
341
372
|
const backend = getQueueBackend(common.queue);
|
|
@@ -365,20 +396,57 @@ function getQueueBackend(queue) {
|
|
|
365
396
|
return name;
|
|
366
397
|
}
|
|
367
398
|
/**
|
|
368
|
-
* Records `fedify.queue.task.enqueued` for an outgoing outbox enqueue
|
|
399
|
+
* Records `fedify.queue.task.enqueued` for an outgoing outbox enqueue and,
|
|
400
|
+
* for the initial attempt, also records
|
|
401
|
+
* `activitypub.outbox.activity{queued}`.
|
|
369
402
|
*
|
|
370
403
|
* Both `Context.sendActivity()` and `OutboxContext.forwardActivity()` enqueue
|
|
371
404
|
* outbox messages with the same metric attributes (role, queue, activity
|
|
372
405
|
* type, attempt), so they share this helper rather than each defining a local
|
|
373
|
-
* closure.
|
|
406
|
+
* closure. Retry enqueues (attempt > 0) intentionally do not record a
|
|
407
|
+
* second `activitypub.outbox.activity{queued}`; retries are reported as
|
|
408
|
+
* `result=retried` from the retry-scheduling site, which has the failure
|
|
409
|
+
* context.
|
|
374
410
|
* @since 2.3.0
|
|
375
411
|
*/
|
|
376
412
|
function recordOutboxEnqueue(meterProvider, outboxQueue, message) {
|
|
377
|
-
getFederationMetrics(meterProvider)
|
|
413
|
+
const metrics = getFederationMetrics(meterProvider);
|
|
414
|
+
metrics.recordQueueTaskEnqueued({
|
|
378
415
|
role: "outbox",
|
|
379
416
|
queue: outboxQueue,
|
|
380
417
|
activityType: message.activityType
|
|
381
418
|
}, message.attempt);
|
|
419
|
+
if (message.attempt === 0) metrics.recordOutboxActivity("queued", message.activityType);
|
|
420
|
+
}
|
|
421
|
+
/**
|
|
422
|
+
* Records `activitypub.fanout.recipients` with the number of recipient
|
|
423
|
+
* inboxes a single fanout produced. The histogram is unitless count
|
|
424
|
+
* (one measurement per fanout enqueue). Recipient URLs are deliberately
|
|
425
|
+
* not recorded; only the activity type, when known.
|
|
426
|
+
* @since 2.3.0
|
|
427
|
+
*/
|
|
428
|
+
function recordFanoutRecipients(meterProvider, recipientCount, activityType) {
|
|
429
|
+
getFederationMetrics(meterProvider).recordFanoutRecipients(recipientCount, activityType);
|
|
430
|
+
}
|
|
431
|
+
/**
|
|
432
|
+
* Records one `activitypub.inbox.activity` measurement. The
|
|
433
|
+
* `activitypub.processing.result` attribute is always present;
|
|
434
|
+
* `activitypub.activity.type` is recorded only when Fedify already knows
|
|
435
|
+
* the activity type.
|
|
436
|
+
* @since 2.3.0
|
|
437
|
+
*/
|
|
438
|
+
function recordInboxActivity(meterProvider, result, activityType) {
|
|
439
|
+
getFederationMetrics(meterProvider).recordInboxActivity(result, activityType);
|
|
440
|
+
}
|
|
441
|
+
/**
|
|
442
|
+
* Records one `activitypub.outbox.activity` measurement. The
|
|
443
|
+
* `activitypub.processing.result` attribute is always present;
|
|
444
|
+
* `activitypub.activity.type` is recorded only when Fedify already knows
|
|
445
|
+
* the activity type (it is always known for outbox lifecycle events).
|
|
446
|
+
* @since 2.3.0
|
|
447
|
+
*/
|
|
448
|
+
function recordOutboxActivity(meterProvider, result, activityType) {
|
|
449
|
+
getFederationMetrics(meterProvider).recordOutboxActivity(result, activityType);
|
|
382
450
|
}
|
|
383
451
|
/**
|
|
384
452
|
* Times an awaited public key fetch and records exactly one
|
|
@@ -1973,6 +2041,24 @@ Object.defineProperty(exports, "parseRfc9421SignatureInput", {
|
|
|
1973
2041
|
return parseRfc9421SignatureInput;
|
|
1974
2042
|
}
|
|
1975
2043
|
});
|
|
2044
|
+
Object.defineProperty(exports, "recordFanoutRecipients", {
|
|
2045
|
+
enumerable: true,
|
|
2046
|
+
get: function() {
|
|
2047
|
+
return recordFanoutRecipients;
|
|
2048
|
+
}
|
|
2049
|
+
});
|
|
2050
|
+
Object.defineProperty(exports, "recordInboxActivity", {
|
|
2051
|
+
enumerable: true,
|
|
2052
|
+
get: function() {
|
|
2053
|
+
return recordInboxActivity;
|
|
2054
|
+
}
|
|
2055
|
+
});
|
|
2056
|
+
Object.defineProperty(exports, "recordOutboxActivity", {
|
|
2057
|
+
enumerable: true,
|
|
2058
|
+
get: function() {
|
|
2059
|
+
return recordOutboxActivity;
|
|
2060
|
+
}
|
|
2061
|
+
});
|
|
1976
2062
|
Object.defineProperty(exports, "recordOutboxEnqueue", {
|
|
1977
2063
|
enumerable: true,
|
|
1978
2064
|
get: function() {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { Temporal } from "@js-temporal/polyfill";
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
|
-
import { n as version, t as name } from "./deno-
|
|
5
|
-
import { a as measureSignatureKeyFetch, n as getFederationMetrics, t as getDurationMs } from "./metrics-
|
|
4
|
+
import { n as version, t as name } from "./deno-DVsHS7rA.mjs";
|
|
5
|
+
import { a as measureSignatureKeyFetch, n as getFederationMetrics, t as getDurationMs } from "./metrics-C4attqv0.mjs";
|
|
6
6
|
import { i as validateAcceptSignature, n as fulfillAcceptSignature, r as parseAcceptSignature } from "./accept-CgDcxvjV.mjs";
|
|
7
|
-
import { o as validateCryptoKey, r as fetchKeyDetailed } from "./key-
|
|
7
|
+
import { o as validateCryptoKey, r as fetchKeyDetailed } from "./key-BoWaYRHm.mjs";
|
|
8
8
|
import { getLogger } from "@logtape/logtape";
|
|
9
9
|
import { CryptographicKey } from "@fedify/vocab";
|
|
10
10
|
import { SpanStatusCode, trace } from "@opentelemetry/api";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import "@js-temporal/polyfill";
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
|
-
import { n as version, t as name } from "./deno-
|
|
4
|
+
import { n as version, t as name } from "./deno-DVsHS7rA.mjs";
|
|
5
5
|
import { getLogger } from "@logtape/logtape";
|
|
6
6
|
import { CryptographicKey, Object as Object$1, isActor } from "@fedify/vocab";
|
|
7
7
|
import { SpanKind, SpanStatusCode, trace } from "@opentelemetry/api";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Temporal } from "@js-temporal/polyfill";
|
|
2
2
|
import { URLPattern } from "urlpattern-polyfill";
|
|
3
|
-
import { d as validateCryptoKey, t as doubleKnock } from "./http-
|
|
3
|
+
import { d as validateCryptoKey, t as doubleKnock } from "./http-CouJSFVK.js";
|
|
4
4
|
import { getLogger } from "@logtape/logtape";
|
|
5
5
|
import { curry } from "es-toolkit";
|
|
6
6
|
import { UrlError, createActivityPubRequest, getRemoteDocument, logRequest, preloadedContexts, validatePublicUrl } from "@fedify/vocab-runtime";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const { Temporal } = require("@js-temporal/polyfill");
|
|
2
2
|
const { URLPattern } = require("urlpattern-polyfill");
|
|
3
3
|
require("./chunk-DDcVe30Y.cjs");
|
|
4
|
-
const require_http = require("./http-
|
|
4
|
+
const require_http = require("./http-CubOB9wq.cjs");
|
|
5
5
|
let _logtape_logtape = require("@logtape/logtape");
|
|
6
6
|
let es_toolkit = require("es-toolkit");
|
|
7
7
|
let _fedify_vocab_runtime = require("@fedify/vocab-runtime");
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import "@js-temporal/polyfill";
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
|
-
import { n as version, t as name } from "./deno-
|
|
5
|
-
import { a as measureSignatureKeyFetch, n as getFederationMetrics, t as getDurationMs } from "./metrics-
|
|
6
|
-
import { n as fetchKey, o as validateCryptoKey } from "./key-
|
|
4
|
+
import { n as version, t as name } from "./deno-DVsHS7rA.mjs";
|
|
5
|
+
import { a as measureSignatureKeyFetch, n as getFederationMetrics, t as getDurationMs } from "./metrics-C4attqv0.mjs";
|
|
6
|
+
import { n as fetchKey, o as validateCryptoKey } from "./key-BoWaYRHm.mjs";
|
|
7
7
|
import { getLogger } from "@logtape/logtape";
|
|
8
8
|
import { Activity, CryptographicKey, Object as Object$1, getTypeId } from "@fedify/vocab";
|
|
9
9
|
import { SpanStatusCode, trace } from "@opentelemetry/api";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import "@js-temporal/polyfill";
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
|
-
import { n as version, t as name } from "./deno-
|
|
4
|
+
import { n as version, t as name } from "./deno-DVsHS7rA.mjs";
|
|
5
5
|
import { metrics } from "@opentelemetry/api";
|
|
6
6
|
//#region src/federation/metrics.ts
|
|
7
7
|
var FederationMetrics = class {
|
|
@@ -20,6 +20,9 @@ var FederationMetrics = class {
|
|
|
20
20
|
queueTaskFailed;
|
|
21
21
|
queueTaskDuration;
|
|
22
22
|
queueTaskInFlight;
|
|
23
|
+
fanoutRecipients;
|
|
24
|
+
inboxActivity;
|
|
25
|
+
outboxActivity;
|
|
23
26
|
constructor(meterProvider) {
|
|
24
27
|
const meter = meterProvider.getMeter(name, version);
|
|
25
28
|
this.deliverySent = meter.createCounter("activitypub.delivery.sent", {
|
|
@@ -114,6 +117,18 @@ var FederationMetrics = class {
|
|
|
114
117
|
description: "Queue tasks currently being processed in this Fedify process.",
|
|
115
118
|
unit: "{task}"
|
|
116
119
|
});
|
|
120
|
+
this.fanoutRecipients = meter.createHistogram("activitypub.fanout.recipients", {
|
|
121
|
+
description: "Number of recipient inboxes produced by an ActivityPub fanout task.",
|
|
122
|
+
unit: "{recipient}"
|
|
123
|
+
});
|
|
124
|
+
this.inboxActivity = meter.createCounter("activitypub.inbox.activity", {
|
|
125
|
+
description: "ActivityPub activities observed at the inbox lifecycle level: queued, processed, retried, rejected, or abandoned.",
|
|
126
|
+
unit: "{activity}"
|
|
127
|
+
});
|
|
128
|
+
this.outboxActivity = meter.createCounter("activitypub.outbox.activity", {
|
|
129
|
+
description: "ActivityPub activities observed at the outbox lifecycle level: queued, retried, or abandoned. Per-recipient delivery counters live on `activitypub.delivery.*`.",
|
|
130
|
+
unit: "{activity}"
|
|
131
|
+
});
|
|
117
132
|
}
|
|
118
133
|
recordDelivery(inbox, durationMs, success, activityType) {
|
|
119
134
|
const deliveryAttributes = {
|
|
@@ -186,7 +201,23 @@ var FederationMetrics = class {
|
|
|
186
201
|
else if (result === "failed") this.queueTaskFailed.add(1, attributes);
|
|
187
202
|
this.queueTaskDuration.record(durationMs, attributes);
|
|
188
203
|
}
|
|
204
|
+
recordFanoutRecipients(recipientCount, activityType) {
|
|
205
|
+
const attributes = {};
|
|
206
|
+
if (activityType != null) attributes["activitypub.activity.type"] = activityType;
|
|
207
|
+
this.fanoutRecipients.record(recipientCount, attributes);
|
|
208
|
+
}
|
|
209
|
+
recordInboxActivity(result, activityType) {
|
|
210
|
+
this.inboxActivity.add(1, buildActivityLifecycleAttributes(result, activityType));
|
|
211
|
+
}
|
|
212
|
+
recordOutboxActivity(result, activityType) {
|
|
213
|
+
this.outboxActivity.add(1, buildActivityLifecycleAttributes(result, activityType));
|
|
214
|
+
}
|
|
189
215
|
};
|
|
216
|
+
function buildActivityLifecycleAttributes(result, activityType) {
|
|
217
|
+
const attributes = { "activitypub.processing.result": result };
|
|
218
|
+
if (activityType != null) attributes["activitypub.activity.type"] = activityType;
|
|
219
|
+
return attributes;
|
|
220
|
+
}
|
|
190
221
|
function buildQueueTaskAttributes(common) {
|
|
191
222
|
const attributes = { "fedify.queue.role": common.role };
|
|
192
223
|
const backend = getQueueBackend(common.queue);
|
|
@@ -216,20 +247,57 @@ function getQueueBackend(queue) {
|
|
|
216
247
|
return name;
|
|
217
248
|
}
|
|
218
249
|
/**
|
|
219
|
-
* Records `fedify.queue.task.enqueued` for an outgoing outbox enqueue
|
|
250
|
+
* Records `fedify.queue.task.enqueued` for an outgoing outbox enqueue and,
|
|
251
|
+
* for the initial attempt, also records
|
|
252
|
+
* `activitypub.outbox.activity{queued}`.
|
|
220
253
|
*
|
|
221
254
|
* Both `Context.sendActivity()` and `OutboxContext.forwardActivity()` enqueue
|
|
222
255
|
* outbox messages with the same metric attributes (role, queue, activity
|
|
223
256
|
* type, attempt), so they share this helper rather than each defining a local
|
|
224
|
-
* closure.
|
|
257
|
+
* closure. Retry enqueues (attempt > 0) intentionally do not record a
|
|
258
|
+
* second `activitypub.outbox.activity{queued}`; retries are reported as
|
|
259
|
+
* `result=retried` from the retry-scheduling site, which has the failure
|
|
260
|
+
* context.
|
|
225
261
|
* @since 2.3.0
|
|
226
262
|
*/
|
|
227
263
|
function recordOutboxEnqueue(meterProvider, outboxQueue, message) {
|
|
228
|
-
getFederationMetrics(meterProvider)
|
|
264
|
+
const metrics = getFederationMetrics(meterProvider);
|
|
265
|
+
metrics.recordQueueTaskEnqueued({
|
|
229
266
|
role: "outbox",
|
|
230
267
|
queue: outboxQueue,
|
|
231
268
|
activityType: message.activityType
|
|
232
269
|
}, message.attempt);
|
|
270
|
+
if (message.attempt === 0) metrics.recordOutboxActivity("queued", message.activityType);
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Records `activitypub.fanout.recipients` with the number of recipient
|
|
274
|
+
* inboxes a single fanout produced. The histogram is unitless count
|
|
275
|
+
* (one measurement per fanout enqueue). Recipient URLs are deliberately
|
|
276
|
+
* not recorded; only the activity type, when known.
|
|
277
|
+
* @since 2.3.0
|
|
278
|
+
*/
|
|
279
|
+
function recordFanoutRecipients(meterProvider, recipientCount, activityType) {
|
|
280
|
+
getFederationMetrics(meterProvider).recordFanoutRecipients(recipientCount, activityType);
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Records one `activitypub.inbox.activity` measurement. The
|
|
284
|
+
* `activitypub.processing.result` attribute is always present;
|
|
285
|
+
* `activitypub.activity.type` is recorded only when Fedify already knows
|
|
286
|
+
* the activity type.
|
|
287
|
+
* @since 2.3.0
|
|
288
|
+
*/
|
|
289
|
+
function recordInboxActivity(meterProvider, result, activityType) {
|
|
290
|
+
getFederationMetrics(meterProvider).recordInboxActivity(result, activityType);
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Records one `activitypub.outbox.activity` measurement. The
|
|
294
|
+
* `activitypub.processing.result` attribute is always present;
|
|
295
|
+
* `activitypub.activity.type` is recorded only when Fedify already knows
|
|
296
|
+
* the activity type (it is always known for outbox lifecycle events).
|
|
297
|
+
* @since 2.3.0
|
|
298
|
+
*/
|
|
299
|
+
function recordOutboxActivity(meterProvider, result, activityType) {
|
|
300
|
+
getFederationMetrics(meterProvider).recordOutboxActivity(result, activityType);
|
|
233
301
|
}
|
|
234
302
|
/**
|
|
235
303
|
* Times an awaited public key fetch and records exactly one
|
|
@@ -311,4 +379,4 @@ function getDurationMs(start) {
|
|
|
311
379
|
return Math.max(0, performance.now() - start);
|
|
312
380
|
}
|
|
313
381
|
//#endregion
|
|
314
|
-
export { measureSignatureKeyFetch as a, isAbortError as i, getFederationMetrics as n,
|
|
382
|
+
export { measureSignatureKeyFetch as a, recordOutboxActivity as c, isAbortError as i, recordOutboxEnqueue as l, getFederationMetrics as n, recordFanoutRecipients as o, getRemoteHost as r, recordInboxActivity as s, getDurationMs as t };
|
|
@@ -2,10 +2,10 @@ const { Temporal } = require("@js-temporal/polyfill");
|
|
|
2
2
|
const { URLPattern } = require("urlpattern-polyfill");
|
|
3
3
|
const require_chunk = require("./chunk-DDcVe30Y.cjs");
|
|
4
4
|
const require_transformers = require("./transformers-NeAONrAq.cjs");
|
|
5
|
-
const require_http = require("./http-
|
|
6
|
-
const require_proof = require("./proof-
|
|
5
|
+
const require_http = require("./http-CubOB9wq.cjs");
|
|
6
|
+
const require_proof = require("./proof-BUWfVr6Q.cjs");
|
|
7
7
|
const require_types = require("./types-KC4QAoxe.cjs");
|
|
8
|
-
const require_kv_cache = require("./kv-cache-
|
|
8
|
+
const require_kv_cache = require("./kv-cache-Dz31ATUT.cjs");
|
|
9
9
|
let _logtape_logtape = require("@logtape/logtape");
|
|
10
10
|
let _fedify_vocab = require("@fedify/vocab");
|
|
11
11
|
let _opentelemetry_api = require("@opentelemetry/api");
|
|
@@ -817,6 +817,7 @@ async function routeActivity({ context: ctx, json, activity, recipient, inboxLis
|
|
|
817
817
|
code: _opentelemetry_api.SpanStatusCode.UNSET,
|
|
818
818
|
message: `Activity ${activity.id?.href} has already been processed.`
|
|
819
819
|
});
|
|
820
|
+
require_http.recordInboxActivity(meterProvider, "rejected", (0, _fedify_vocab.getTypeId)(activity).href);
|
|
820
821
|
return "alreadyProcessed";
|
|
821
822
|
}
|
|
822
823
|
}
|
|
@@ -826,6 +827,7 @@ async function routeActivity({ context: ctx, json, activity, recipient, inboxLis
|
|
|
826
827
|
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
827
828
|
message: "Missing actor."
|
|
828
829
|
});
|
|
830
|
+
require_http.recordInboxActivity(meterProvider, "rejected", (0, _fedify_vocab.getTypeId)(activity).href);
|
|
829
831
|
return "missingActor";
|
|
830
832
|
}
|
|
831
833
|
span.setAttribute("activitypub.actor.id", activity.actorId.href);
|
|
@@ -861,6 +863,7 @@ async function routeActivity({ context: ctx, json, activity, recipient, inboxLis
|
|
|
861
863
|
queue,
|
|
862
864
|
activityType: (0, _fedify_vocab.getTypeId)(activity).href
|
|
863
865
|
}, 0);
|
|
866
|
+
require_http.recordInboxActivity(meterProvider, "queued", (0, _fedify_vocab.getTypeId)(activity).href);
|
|
864
867
|
logger.info("Activity {activityId} is enqueued.", {
|
|
865
868
|
activityId: activity.id?.href,
|
|
866
869
|
activity: json,
|
|
@@ -880,6 +883,7 @@ async function routeActivity({ context: ctx, json, activity, recipient, inboxLis
|
|
|
880
883
|
code: _opentelemetry_api.SpanStatusCode.UNSET,
|
|
881
884
|
message: `Unsupported activity type: ${(0, _fedify_vocab.getTypeId)(activity).href}`
|
|
882
885
|
});
|
|
886
|
+
require_http.recordInboxActivity(meterProvider, "rejected", (0, _fedify_vocab.getTypeId)(activity).href);
|
|
883
887
|
span.end();
|
|
884
888
|
return "unsupportedActivity";
|
|
885
889
|
}
|
|
@@ -889,7 +893,7 @@ async function routeActivity({ context: ctx, json, activity, recipient, inboxLis
|
|
|
889
893
|
const activityType = (0, _fedify_vocab.getTypeId)(activity).href;
|
|
890
894
|
const started = performance.now();
|
|
891
895
|
try {
|
|
892
|
-
await listener(inboxContextFactory(recipient, json, activity
|
|
896
|
+
await listener(inboxContextFactory(recipient, json, activity.id?.href, activityType), activity);
|
|
893
897
|
} finally {
|
|
894
898
|
require_http.getFederationMetrics(meterProvider).recordInboxProcessingDuration(activityType, require_http.getDurationMs(started));
|
|
895
899
|
}
|
|
@@ -914,9 +918,11 @@ async function routeActivity({ context: ctx, json, activity, recipient, inboxLis
|
|
|
914
918
|
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
915
919
|
message: String(error)
|
|
916
920
|
});
|
|
921
|
+
require_http.recordInboxActivity(meterProvider, "rejected", (0, _fedify_vocab.getTypeId)(activity).href);
|
|
917
922
|
span.end();
|
|
918
923
|
return "error";
|
|
919
924
|
}
|
|
925
|
+
require_http.recordInboxActivity(meterProvider, "processed", (0, _fedify_vocab.getTypeId)(activity).href);
|
|
920
926
|
if (cacheKey != null) await kv.set(cacheKey, true, { ttl: Temporal.Duration.from({ days: 1 }) });
|
|
921
927
|
logger.info("Activity {activityId} has been processed.", {
|
|
922
928
|
activityId: activity.id?.href,
|
|
@@ -3233,6 +3239,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3233
3239
|
});
|
|
3234
3240
|
}
|
|
3235
3241
|
}
|
|
3242
|
+
require_http.recordOutboxActivity(this.meterProvider, "abandoned", message.activityType);
|
|
3236
3243
|
return;
|
|
3237
3244
|
}
|
|
3238
3245
|
if (this.outboxQueue?.nativeRetrial) {
|
|
@@ -3263,11 +3270,15 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3263
3270
|
queue: outboxQueue,
|
|
3264
3271
|
activityType: retryMessage.activityType
|
|
3265
3272
|
}, retryMessage.attempt);
|
|
3273
|
+
require_http.recordOutboxActivity(this.meterProvider, "retried", retryMessage.activityType);
|
|
3266
3274
|
}
|
|
3267
|
-
} else
|
|
3268
|
-
|
|
3269
|
-
|
|
3270
|
-
|
|
3275
|
+
} else {
|
|
3276
|
+
logger.error("Failed to send activity {activityId} to {inbox} after {attempt} attempts; giving up:\n{error}", {
|
|
3277
|
+
...logData,
|
|
3278
|
+
error
|
|
3279
|
+
});
|
|
3280
|
+
require_http.recordOutboxActivity(this.meterProvider, "abandoned", message.activityType);
|
|
3281
|
+
}
|
|
3271
3282
|
return;
|
|
3272
3283
|
}
|
|
3273
3284
|
logger.info("Successfully sent activity {activityId} to {inbox}.", { ...logData });
|
|
@@ -3302,6 +3313,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3302
3313
|
activity: message.activity,
|
|
3303
3314
|
recipient: message.identifier
|
|
3304
3315
|
});
|
|
3316
|
+
require_http.recordInboxActivity(this.meterProvider, "rejected", activityType);
|
|
3305
3317
|
return;
|
|
3306
3318
|
}
|
|
3307
3319
|
}
|
|
@@ -3318,6 +3330,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3318
3330
|
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
3319
3331
|
message: `Unsupported activity type: ${activityType}`
|
|
3320
3332
|
});
|
|
3333
|
+
require_http.recordInboxActivity(this.meterProvider, "rejected", activityType);
|
|
3321
3334
|
span.end();
|
|
3322
3335
|
return;
|
|
3323
3336
|
}
|
|
@@ -3330,6 +3343,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3330
3343
|
} finally {
|
|
3331
3344
|
require_http.getFederationMetrics(this.meterProvider).recordInboxProcessingDuration(activityType, require_http.getDurationMs(started));
|
|
3332
3345
|
}
|
|
3346
|
+
require_http.recordInboxActivity(this.meterProvider, "processed", activityType);
|
|
3333
3347
|
} catch (error) {
|
|
3334
3348
|
try {
|
|
3335
3349
|
await this.inboxErrorHandler?.(context, error);
|
|
@@ -3380,13 +3394,17 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3380
3394
|
queue: inboxQueue,
|
|
3381
3395
|
activityType
|
|
3382
3396
|
}, retryMessage.attempt);
|
|
3397
|
+
require_http.recordInboxActivity(this.meterProvider, "retried", activityType);
|
|
3383
3398
|
}
|
|
3384
|
-
} else
|
|
3385
|
-
error,
|
|
3386
|
-
|
|
3387
|
-
|
|
3388
|
-
|
|
3389
|
-
|
|
3399
|
+
} else {
|
|
3400
|
+
logger.error("Failed to process the incoming activity {activityId} after {trial} attempts; giving up:\n{error}", {
|
|
3401
|
+
error,
|
|
3402
|
+
activityId: activity.id?.href,
|
|
3403
|
+
activity: message.activity,
|
|
3404
|
+
recipient: message.identifier
|
|
3405
|
+
});
|
|
3406
|
+
require_http.recordInboxActivity(this.meterProvider, "abandoned", activityType);
|
|
3407
|
+
}
|
|
3390
3408
|
span.setStatus({
|
|
3391
3409
|
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
3392
3410
|
message: String(error)
|
|
@@ -4413,6 +4431,7 @@ var ContextImpl = class ContextImpl {
|
|
|
4413
4431
|
queue: this.federation.fanoutQueue,
|
|
4414
4432
|
activityType: message.activityType
|
|
4415
4433
|
}, 0);
|
|
4434
|
+
require_http.recordFanoutRecipients(this.federation.meterProvider, globalThis.Object.keys(message.inboxes).length, message.activityType);
|
|
4416
4435
|
return true;
|
|
4417
4436
|
}
|
|
4418
4437
|
async *getFollowers(identifier) {
|