@fedify/fedify 2.4.0-dev.1567 → 2.4.0-dev.1570
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 +4 -0
- package/dist/{assert-OguE97r2.mjs → assert-DvVHoIZ0.mjs} +1 -1
- package/dist/{assert_instance_of-DBC5X09g.mjs → assert_instance_of-CxoC8bVq.mjs} +1 -1
- package/dist/{assert_not_equals-DkVK8oqV.mjs → assert_not_equals-C8vcTTA3.mjs} +1 -1
- package/dist/{assert_rejects-DN60FHPX.mjs → assert_rejects-DAdaaIWM.mjs} +2 -2
- package/dist/{assert_strict_equals-XEgZAlrj.mjs → assert_strict_equals-BzqyKuYL.mjs} +1 -1
- package/dist/{assert_throws-BOkhLGYc.mjs → assert_throws-zN79lgIC.mjs} +1 -1
- package/dist/{builder-DGWCUaNQ.mjs → builder-CJnWbgbj.mjs} +23 -3
- package/dist/codec-nfBU4Up4.mjs +124 -0
- package/dist/compat/mod.d.cts +1 -1
- package/dist/compat/mod.d.ts +1 -1
- package/dist/compat/outgoing-jsonld.test.mjs +3 -3
- package/dist/compat/public-audience.test.mjs +3 -3
- package/dist/compat/transformers.test.mjs +5 -5
- package/dist/{context-DVoTs_wM.mjs → context-BBRTgkrs.mjs} +8 -2
- package/dist/{context-BBVLF7lx.d.cts → context-BLe0NPtZ.d.cts} +530 -259
- package/dist/{context-BU6jSQdo.d.ts → context-GfQA-CqB.d.ts} +529 -259
- package/dist/{deno-Dho0TW0X.mjs → deno-klNxGW7W.mjs} +1 -1
- package/dist/{docloader-DCQSgDOg.mjs → docloader-CuFH35j1.mjs} +3 -3
- package/dist/federation/builder.test.mjs +5 -5
- package/dist/federation/circuit-breaker.test.mjs +5 -5
- package/dist/federation/collection.test.mjs +3 -3
- package/dist/federation/handler.test.mjs +13 -23
- package/dist/federation/idempotency.test.mjs +6 -6
- package/dist/federation/inbox.test.mjs +3 -3
- package/dist/federation/keycache.test.mjs +5 -5
- package/dist/federation/kv.test.mjs +3 -3
- package/dist/federation/metrics.test.mjs +4 -4
- package/dist/federation/middleware.test.mjs +204 -19
- package/dist/federation/mod.cjs +3 -259
- package/dist/federation/mod.d.cts +4 -4
- package/dist/federation/mod.d.ts +4 -4
- package/dist/federation/mod.js +1 -257
- package/dist/federation/mq.test.mjs +103 -261
- package/dist/federation/negotiation.test.mjs +4 -4
- package/dist/federation/retry.test.mjs +3 -3
- package/dist/federation/router.test.mjs +5 -5
- package/dist/federation/send.test.mjs +10 -10
- package/dist/federation/tasks/codec.test.d.mts +2 -0
- package/dist/federation/tasks/codec.test.mjs +302 -0
- package/dist/federation/tasks/enqueue.test.d.mts +2 -0
- package/dist/federation/tasks/enqueue.test.mjs +1057 -0
- package/dist/federation/tasks/tasks.test.d.mts +2 -0
- package/dist/federation/tasks/tasks.test.mjs +1228 -0
- package/dist/federation/temporal.test.mjs +4 -4
- package/dist/federation/webfinger.test.mjs +6 -6
- package/dist/{http-sngIMb9S.js → http-D0jH0kco.js} +16 -80
- package/dist/{http-C7Lot0it.cjs → http-DeuPW1Oh.cjs} +14 -78
- package/dist/{http-Bf8YhWOi.mjs → http-JdRPUYku.mjs} +4 -4
- package/dist/{key-3rYgSl9f.mjs → key-o0_ipvUR.mjs} +10 -76
- package/dist/{kv-cache-CO2IaDJu.cjs → kv-cache-C3rqzQvu.cjs} +1 -1
- package/dist/{kv-cache-P3scUO6t.mjs → kv-cache-CM7w20U5.mjs} +1 -1
- package/dist/{kv-cache-B0siRaoZ.js → kv-cache-DSWq2JHU.js} +1 -1
- package/dist/{ld-CCOPy-Co.mjs → ld-C__CEgQH.mjs} +3 -3
- package/dist/{metrics-CR4UD_gF.mjs → metrics-CLSPm4dZ.mjs} +8 -6
- package/dist/{mq-D-nlpY04.d.ts → metrics-CoUJLQhZ.d.cts} +69 -1
- package/dist/{mq-D8uSFzxe.d.cts → metrics-Dc4jR-IC.d.ts} +69 -1
- package/dist/{middleware-DUelXs9h.cjs → middleware-B502nwxx.cjs} +874 -134
- package/dist/{middleware-CIteB8IS.mjs → middleware-CdMiavoh.mjs} +1 -1
- package/dist/{middleware-DfBPuuvp.mjs → middleware-CjHqy-1i.mjs} +469 -150
- package/dist/{middleware-BoNiH9CQ.js → middleware-zuLSkPIk.js} +863 -135
- package/dist/{mod-C0F6kvgS.d.cts → mod-B8Efb9qp.d.cts} +1 -1
- package/dist/{mod-yvIXFAEi.d.cts → mod-BtEaIEcD.d.cts} +1 -31
- package/dist/{mod-vPYVoa5n.d.ts → mod-Cmr39iWq.d.ts} +1 -1
- package/dist/{mod-DFvNJcNb.d.ts → mod-UMmveiO0.d.ts} +1 -31
- package/dist/mod.cjs +6 -6
- package/dist/mod.d.cts +6 -6
- package/dist/mod.d.ts +6 -6
- package/dist/mod.js +5 -5
- package/dist/mq-03vS-C9P.mjs +276 -0
- package/dist/nodeinfo/client.test.mjs +3 -3
- package/dist/nodeinfo/handler.test.mjs +5 -5
- package/dist/nodeinfo/types.test.mjs +4 -4
- package/dist/otel/exporter.test.mjs +3 -3
- package/dist/{outgoing-jsonld-L_DbOaFe.mjs → outgoing-jsonld-BNL8AC14.mjs} +1 -1
- package/dist/{owner-TUz_H-M9.mjs → owner-gz4TUfKG.mjs} +2 -2
- package/dist/{proof-DzKUmE7R.cjs → proof-CiDzRtr0.cjs} +1 -1
- package/dist/{proof-CrI3UpuA.mjs → proof-CuQpZ_AT.mjs} +5 -5
- package/dist/{proof-C5i7MhbD.js → proof-DQWTf6oB.js} +1 -1
- package/dist/{send-BBs_erdP.mjs → send-B60teucv.mjs} +3 -3
- package/dist/sig/accept.test.mjs +1 -1
- package/dist/sig/http.test.mjs +8 -8
- package/dist/sig/key.test.mjs +7 -191
- package/dist/sig/ld.test.mjs +7 -7
- package/dist/sig/mod.cjs +2 -2
- package/dist/sig/mod.js +2 -2
- package/dist/sig/owner.test.mjs +6 -6
- package/dist/sig/proof.test.mjs +9 -69
- package/dist/{std__assert-BBjXFNOb.mjs → std__assert-Dh6uLf_q.mjs} +4 -4
- package/dist/{temporal-bBIy2G-F.mjs → temporal-CvVMrvJJ.mjs} +1 -1
- package/dist/testing/mod.d.mts +1037 -8
- package/dist/testing/mod.mjs +3 -2
- package/dist/testing-Dy-WhqpN.mjs +77 -0
- package/dist/utils/docloader.test.mjs +6 -6
- package/dist/utils/kv-cache.test.mjs +1 -1
- package/dist/utils/mod.cjs +1 -1
- package/dist/utils/mod.d.cts +1 -1
- package/dist/utils/mod.d.ts +1 -1
- package/dist/utils/mod.js +1 -1
- package/package.json +8 -6
- /package/dist/{accept-CPkZzmGN.mjs → accept-CgDcxvjV.mjs} +0 -0
- /package/dist/{activity-listener-tztVvlNb.mjs → activity-listener-BeTGV3wc.mjs} +0 -0
- /package/dist/{assert_equals-C-ZRDbaf.mjs → assert_equals-PBVKNMJd.mjs} +0 -0
- /package/dist/{circuit-breaker-CSWsyoef.mjs → circuit-breaker-hJBB6jwA.mjs} +0 -0
- /package/dist/{client-ByXmQhYD.mjs → client-B_A6mfn3.mjs} +0 -0
- /package/dist/{collection-Cc3DVAhE.mjs → collection-Dp5ky45w.mjs} +0 -0
- /package/dist/{keycache-BeU0LCII.mjs → keycache-CaOR6NYg.mjs} +0 -0
- /package/dist/{keys-DGu1NFwu.mjs → keys-CSYsOMFG.mjs} +0 -0
- /package/dist/{kv-rV3vodCc.mjs → kv-CIvR3Non.mjs} +0 -0
- /package/dist/{negotiation-DDstyBvc.mjs → negotiation-m_L2nyS3.mjs} +0 -0
- /package/dist/{public-audience-Cvbr2Gzt.mjs → public-audience-c9zmYKgA.mjs} +0 -0
- /package/dist/{retry-CXg_MBI-.mjs → retry-DI4O-zYl.mjs} +0 -0
- /package/dist/{types-J53Kw7so.mjs → types-BFowWFTT.mjs} +0 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import "@js-temporal/polyfill";
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
|
-
import "../std__assert-
|
|
5
|
-
import { r as assertFalse } from "../assert_rejects-
|
|
6
|
-
import { t as assert } from "../assert-
|
|
7
|
-
import { t as hasMalformedKnownTemporalLiteral } from "../temporal-
|
|
4
|
+
import "../std__assert-Dh6uLf_q.mjs";
|
|
5
|
+
import { r as assertFalse } from "../assert_rejects-DAdaaIWM.mjs";
|
|
6
|
+
import { t as assert } from "../assert-DvVHoIZ0.mjs";
|
|
7
|
+
import { t as hasMalformedKnownTemporalLiteral } from "../temporal-CvVMrvJJ.mjs";
|
|
8
8
|
import { test } from "@fedify/fixture";
|
|
9
9
|
//#region src/federation/temporal.test.ts
|
|
10
10
|
test("hasMalformedKnownTemporalLiteral() detects expanded proof timestamps", async () => {
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { Temporal } from "@js-temporal/polyfill";
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
|
-
import { r as createRequestContext } from "../context-
|
|
5
|
-
import { t as
|
|
6
|
-
import "../
|
|
7
|
-
import
|
|
8
|
-
import { t as
|
|
9
|
-
import { o as createFederation, s as handleWebFinger } from "../middleware-
|
|
4
|
+
import { r as createRequestContext } from "../context-BBRTgkrs.mjs";
|
|
5
|
+
import { t as MemoryKvStore } from "../kv-CIvR3Non.mjs";
|
|
6
|
+
import { t as assertEquals } from "../assert_equals-PBVKNMJd.mjs";
|
|
7
|
+
import "../std__assert-Dh6uLf_q.mjs";
|
|
8
|
+
import { t as assertNotEquals } from "../assert_not_equals-C8vcTTA3.mjs";
|
|
9
|
+
import { o as createFederation, s as handleWebFinger } from "../middleware-CjHqy-1i.mjs";
|
|
10
10
|
import { Image, Link, Person, Tombstone } from "@fedify/vocab";
|
|
11
11
|
import { createTestMeterProvider, test } from "@fedify/fixture";
|
|
12
12
|
//#region src/federation/webfinger.test.ts
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { Temporal } from "@js-temporal/polyfill";
|
|
2
2
|
import { URLPattern } from "urlpattern-polyfill";
|
|
3
3
|
import { getLogger } from "@logtape/logtape";
|
|
4
|
-
import { CryptographicKey,
|
|
4
|
+
import { CryptographicKey, Object as Object$1, isActor } from "@fedify/vocab";
|
|
5
5
|
import { SpanKind, SpanStatusCode, metrics, trace } from "@opentelemetry/api";
|
|
6
6
|
import { encodeHex } from "byte-encodings/hex";
|
|
7
7
|
import { Item, decodeDict, encodeDict, encodeItem } from "structured-field-values";
|
|
8
|
-
import { FetchError, getDocumentLoader
|
|
8
|
+
import { FetchError, getDocumentLoader } from "@fedify/vocab-runtime";
|
|
9
9
|
import { ATTR_HTTP_REQUEST_HEADER, ATTR_HTTP_REQUEST_METHOD, ATTR_URL_FULL } from "@opentelemetry/semantic-conventions";
|
|
10
10
|
import { decodeBase64, encodeBase64 } from "byte-encodings/base64";
|
|
11
11
|
//#region deno.json
|
|
12
12
|
var name = "@fedify/fedify";
|
|
13
|
-
var version = "2.4.0-dev.
|
|
13
|
+
var version = "2.4.0-dev.1570+f1b6aaa3";
|
|
14
14
|
//#endregion
|
|
15
15
|
//#region src/sig/accept.ts
|
|
16
16
|
/**
|
|
@@ -314,11 +314,11 @@ var FederationMetrics = class {
|
|
|
314
314
|
unit: "{change}"
|
|
315
315
|
});
|
|
316
316
|
this.keyLookup = meter.createCounter("activitypub.key.lookup", {
|
|
317
|
-
description: "Public-key lookup attempts performed by Fedify, including cache hits
|
|
317
|
+
description: "Public-key lookup attempts performed by Fedify, including both cache hits and remote fetches.",
|
|
318
318
|
unit: "{lookup}"
|
|
319
319
|
});
|
|
320
320
|
this.keyLookupDuration = meter.createHistogram("activitypub.key.lookup.duration", {
|
|
321
|
-
description: "Duration of public-key lookups performed by Fedify, including
|
|
321
|
+
description: "Duration of public-key lookups performed by Fedify, including any remote fetch.",
|
|
322
322
|
unit: "ms",
|
|
323
323
|
advice: { explicitBucketBoundaries: [
|
|
324
324
|
5,
|
|
@@ -472,10 +472,10 @@ var FederationMetrics = class {
|
|
|
472
472
|
this.httpServerRequestCount.add(1, attributes);
|
|
473
473
|
this.httpServerRequestDuration.record(durationMs, attributes);
|
|
474
474
|
}
|
|
475
|
-
recordQueueTaskEnqueued(common, attempt) {
|
|
475
|
+
recordQueueTaskEnqueued(common, attempt, count = 1) {
|
|
476
476
|
const attributes = buildQueueTaskAttributes(common);
|
|
477
477
|
attributes["fedify.queue.task.attempt"] = attempt;
|
|
478
|
-
this.queueTaskEnqueued.add(
|
|
478
|
+
this.queueTaskEnqueued.add(count, attributes);
|
|
479
479
|
}
|
|
480
480
|
recordQueueTaskStarted(common) {
|
|
481
481
|
this.queueTaskStarted.add(1, buildQueueTaskAttributes(common));
|
|
@@ -486,9 +486,10 @@ var FederationMetrics = class {
|
|
|
486
486
|
decrementQueueTaskInFlight(common) {
|
|
487
487
|
this.queueTaskInFlight.add(-1, buildQueueTaskInFlightAttributes(common));
|
|
488
488
|
}
|
|
489
|
-
recordQueueTaskOutcome(common, result, durationMs) {
|
|
489
|
+
recordQueueTaskOutcome(common, result, durationMs, failureReason) {
|
|
490
490
|
const attributes = buildQueueTaskAttributes(common);
|
|
491
491
|
attributes["fedify.queue.task.result"] = result;
|
|
492
|
+
if (failureReason != null && result === "failed") attributes["fedify.task.failure_reason"] = failureReason;
|
|
492
493
|
if (result === "completed") this.queueTaskCompleted.add(1, attributes);
|
|
493
494
|
else if (result === "failed") this.queueTaskFailed.add(1, attributes);
|
|
494
495
|
this.queueTaskDuration.record(durationMs, attributes);
|
|
@@ -582,6 +583,7 @@ function buildQueueTaskAttributes(common) {
|
|
|
582
583
|
const nativeRetrial = common.queue?.nativeRetrial;
|
|
583
584
|
if (typeof nativeRetrial === "boolean") attributes["fedify.queue.native_retrial"] = nativeRetrial;
|
|
584
585
|
if (common.activityType != null) attributes["activitypub.activity.type"] = common.activityType;
|
|
586
|
+
if (common.taskName != null) attributes["fedify.task.name"] = common.taskName;
|
|
585
587
|
return attributes;
|
|
586
588
|
}
|
|
587
589
|
function buildQueueTaskInFlightAttributes(common) {
|
|
@@ -1147,85 +1149,24 @@ async function fetchKeyDetailed(keyId, cls, options = {}) {
|
|
|
1147
1149
|
async function getCachedFetchKey(cacheKey, keyId, cls, keyCache, logger) {
|
|
1148
1150
|
if (keyCache == null) return null;
|
|
1149
1151
|
const cachedKey = await keyCache.get(cacheKey);
|
|
1150
|
-
const hit = checkCachedKeyHit(cachedKey, keyId, cls, logger);
|
|
1151
|
-
if (hit != null) return hit;
|
|
1152
|
-
if (cachedKey === null) {
|
|
1153
|
-
logger.debug("Entry {keyId} found in cache, but it is unavailable.", { keyId });
|
|
1154
|
-
return {
|
|
1155
|
-
key: null,
|
|
1156
|
-
cached: true
|
|
1157
|
-
};
|
|
1158
|
-
}
|
|
1159
|
-
return null;
|
|
1160
|
-
}
|
|
1161
|
-
function checkCachedKeyHit(cachedKey, keyId, cls, logger) {
|
|
1162
1152
|
if (cachedKey instanceof cls && cachedKey.publicKey != null) {
|
|
1163
1153
|
logger.debug("Key {keyId} found in cache.", { keyId });
|
|
1164
1154
|
return {
|
|
1165
1155
|
key: cachedKey,
|
|
1166
1156
|
cached: true
|
|
1167
1157
|
};
|
|
1158
|
+
} else if (cachedKey === null) {
|
|
1159
|
+
logger.debug("Entry {keyId} found in cache, but it is unavailable.", { keyId });
|
|
1160
|
+
return {
|
|
1161
|
+
key: null,
|
|
1162
|
+
cached: true
|
|
1163
|
+
};
|
|
1168
1164
|
}
|
|
1169
1165
|
return null;
|
|
1170
1166
|
}
|
|
1171
1167
|
async function clearFetchErrorMetadata(keyId, keyCache) {
|
|
1172
1168
|
await keyCache?.setFetchError?.(keyId, null);
|
|
1173
1169
|
}
|
|
1174
|
-
function isDidKeyUrl(keyId) {
|
|
1175
|
-
return keyId.protocol === "did:" && keyId.pathname.startsWith("key:");
|
|
1176
|
-
}
|
|
1177
|
-
async function doRawKeysMatch(left, right) {
|
|
1178
|
-
const [leftRaw, rightRaw] = await Promise.all([crypto.subtle.exportKey("raw", left), crypto.subtle.exportKey("raw", right)]);
|
|
1179
|
-
if (leftRaw.byteLength !== rightRaw.byteLength) return false;
|
|
1180
|
-
const leftBytes = new Uint8Array(leftRaw);
|
|
1181
|
-
const rightBytes = new Uint8Array(rightRaw);
|
|
1182
|
-
return leftBytes.every((byte, index) => byte === rightBytes[index]);
|
|
1183
|
-
}
|
|
1184
|
-
async function isCachedDidKeyValid(key, verificationMethod) {
|
|
1185
|
-
try {
|
|
1186
|
-
return key.id?.href === verificationMethod.id.href && key.controllerId?.href === verificationMethod.controller.href && await doRawKeysMatch(key.publicKey, verificationMethod.publicKey);
|
|
1187
|
-
} catch {
|
|
1188
|
-
return false;
|
|
1189
|
-
}
|
|
1190
|
-
}
|
|
1191
|
-
async function resolveDidKey(cacheKey, cls, keyCache, logger) {
|
|
1192
|
-
if (!isDidKeyUrl(cacheKey)) return null;
|
|
1193
|
-
const keyId = cacheKey.href;
|
|
1194
|
-
if (!(cls === Multikey)) {
|
|
1195
|
-
logger.debug("Failed to resolve did:key {keyId}; did:key verification methods are only supported as Multikey values.", { keyId });
|
|
1196
|
-
return {
|
|
1197
|
-
key: null,
|
|
1198
|
-
cached: false
|
|
1199
|
-
};
|
|
1200
|
-
}
|
|
1201
|
-
let verificationMethod;
|
|
1202
|
-
try {
|
|
1203
|
-
verificationMethod = await parseDidKeyVerificationMethod(cacheKey);
|
|
1204
|
-
} catch (error) {
|
|
1205
|
-
logger.debug("Failed to resolve did:key verification method {keyId}: {error}", {
|
|
1206
|
-
keyId,
|
|
1207
|
-
error
|
|
1208
|
-
});
|
|
1209
|
-
return {
|
|
1210
|
-
key: null,
|
|
1211
|
-
cached: false
|
|
1212
|
-
};
|
|
1213
|
-
}
|
|
1214
|
-
const hit = checkCachedKeyHit(await keyCache?.get(cacheKey), keyId, cls, logger);
|
|
1215
|
-
if (hit?.key instanceof Multikey && await isCachedDidKeyValid(hit.key, verificationMethod)) return hit;
|
|
1216
|
-
const key = new Multikey({
|
|
1217
|
-
id: verificationMethod.id,
|
|
1218
|
-
controller: verificationMethod.controller,
|
|
1219
|
-
publicKey: verificationMethod.publicKey
|
|
1220
|
-
});
|
|
1221
|
-
await keyCache?.set(cacheKey, key);
|
|
1222
|
-
await clearFetchErrorMetadata(cacheKey, keyCache);
|
|
1223
|
-
logger.debug("Resolved did:key verification method {keyId}.", { keyId });
|
|
1224
|
-
return {
|
|
1225
|
-
key,
|
|
1226
|
-
cached: false
|
|
1227
|
-
};
|
|
1228
|
-
}
|
|
1229
1170
|
async function resolveFetchedKey(document, cacheKey, keyId, cls, { documentLoader, contextLoader, keyCache, tracerProvider }, logger) {
|
|
1230
1171
|
let object;
|
|
1231
1172
|
try {
|
|
@@ -1340,11 +1281,6 @@ async function fetchKeyWithResult(cacheKey, cls, options, onCachedUnavailable, o
|
|
|
1340
1281
|
]);
|
|
1341
1282
|
const keyId = cacheKey.href;
|
|
1342
1283
|
const keyCache = options.keyCache;
|
|
1343
|
-
const didKey = await resolveDidKey(cacheKey, cls, keyCache, logger);
|
|
1344
|
-
if (didKey != null) {
|
|
1345
|
-
outcome = { result: didKey.key == null ? "invalid" : didKey.cached ? "hit" : "fetched" };
|
|
1346
|
-
return didKey;
|
|
1347
|
-
}
|
|
1348
1284
|
const cached = await getCachedFetchKey(cacheKey, keyId, cls, keyCache, logger);
|
|
1349
1285
|
if (cached?.key === null && cached.cached) {
|
|
1350
1286
|
const cachedUnavailable = await onCachedUnavailable(cacheKey, keyId, keyCache, logger);
|
|
@@ -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.4.0-dev.
|
|
14
|
+
var version = "2.4.0-dev.1570+f1b6aaa3";
|
|
15
15
|
//#endregion
|
|
16
16
|
//#region src/sig/accept.ts
|
|
17
17
|
/**
|
|
@@ -315,11 +315,11 @@ var FederationMetrics = class {
|
|
|
315
315
|
unit: "{change}"
|
|
316
316
|
});
|
|
317
317
|
this.keyLookup = meter.createCounter("activitypub.key.lookup", {
|
|
318
|
-
description: "Public-key lookup attempts performed by Fedify, including cache hits
|
|
318
|
+
description: "Public-key lookup attempts performed by Fedify, including both cache hits and remote fetches.",
|
|
319
319
|
unit: "{lookup}"
|
|
320
320
|
});
|
|
321
321
|
this.keyLookupDuration = meter.createHistogram("activitypub.key.lookup.duration", {
|
|
322
|
-
description: "Duration of public-key lookups performed by Fedify, including
|
|
322
|
+
description: "Duration of public-key lookups performed by Fedify, including any remote fetch.",
|
|
323
323
|
unit: "ms",
|
|
324
324
|
advice: { explicitBucketBoundaries: [
|
|
325
325
|
5,
|
|
@@ -473,10 +473,10 @@ var FederationMetrics = class {
|
|
|
473
473
|
this.httpServerRequestCount.add(1, attributes);
|
|
474
474
|
this.httpServerRequestDuration.record(durationMs, attributes);
|
|
475
475
|
}
|
|
476
|
-
recordQueueTaskEnqueued(common, attempt) {
|
|
476
|
+
recordQueueTaskEnqueued(common, attempt, count = 1) {
|
|
477
477
|
const attributes = buildQueueTaskAttributes(common);
|
|
478
478
|
attributes["fedify.queue.task.attempt"] = attempt;
|
|
479
|
-
this.queueTaskEnqueued.add(
|
|
479
|
+
this.queueTaskEnqueued.add(count, attributes);
|
|
480
480
|
}
|
|
481
481
|
recordQueueTaskStarted(common) {
|
|
482
482
|
this.queueTaskStarted.add(1, buildQueueTaskAttributes(common));
|
|
@@ -487,9 +487,10 @@ var FederationMetrics = class {
|
|
|
487
487
|
decrementQueueTaskInFlight(common) {
|
|
488
488
|
this.queueTaskInFlight.add(-1, buildQueueTaskInFlightAttributes(common));
|
|
489
489
|
}
|
|
490
|
-
recordQueueTaskOutcome(common, result, durationMs) {
|
|
490
|
+
recordQueueTaskOutcome(common, result, durationMs, failureReason) {
|
|
491
491
|
const attributes = buildQueueTaskAttributes(common);
|
|
492
492
|
attributes["fedify.queue.task.result"] = result;
|
|
493
|
+
if (failureReason != null && result === "failed") attributes["fedify.task.failure_reason"] = failureReason;
|
|
493
494
|
if (result === "completed") this.queueTaskCompleted.add(1, attributes);
|
|
494
495
|
else if (result === "failed") this.queueTaskFailed.add(1, attributes);
|
|
495
496
|
this.queueTaskDuration.record(durationMs, attributes);
|
|
@@ -583,6 +584,7 @@ function buildQueueTaskAttributes(common) {
|
|
|
583
584
|
const nativeRetrial = common.queue?.nativeRetrial;
|
|
584
585
|
if (typeof nativeRetrial === "boolean") attributes["fedify.queue.native_retrial"] = nativeRetrial;
|
|
585
586
|
if (common.activityType != null) attributes["activitypub.activity.type"] = common.activityType;
|
|
587
|
+
if (common.taskName != null) attributes["fedify.task.name"] = common.taskName;
|
|
586
588
|
return attributes;
|
|
587
589
|
}
|
|
588
590
|
function buildQueueTaskInFlightAttributes(common) {
|
|
@@ -1148,85 +1150,24 @@ async function fetchKeyDetailed(keyId, cls, options = {}) {
|
|
|
1148
1150
|
async function getCachedFetchKey(cacheKey, keyId, cls, keyCache, logger) {
|
|
1149
1151
|
if (keyCache == null) return null;
|
|
1150
1152
|
const cachedKey = await keyCache.get(cacheKey);
|
|
1151
|
-
const hit = checkCachedKeyHit(cachedKey, keyId, cls, logger);
|
|
1152
|
-
if (hit != null) return hit;
|
|
1153
|
-
if (cachedKey === null) {
|
|
1154
|
-
logger.debug("Entry {keyId} found in cache, but it is unavailable.", { keyId });
|
|
1155
|
-
return {
|
|
1156
|
-
key: null,
|
|
1157
|
-
cached: true
|
|
1158
|
-
};
|
|
1159
|
-
}
|
|
1160
|
-
return null;
|
|
1161
|
-
}
|
|
1162
|
-
function checkCachedKeyHit(cachedKey, keyId, cls, logger) {
|
|
1163
1153
|
if (cachedKey instanceof cls && cachedKey.publicKey != null) {
|
|
1164
1154
|
logger.debug("Key {keyId} found in cache.", { keyId });
|
|
1165
1155
|
return {
|
|
1166
1156
|
key: cachedKey,
|
|
1167
1157
|
cached: true
|
|
1168
1158
|
};
|
|
1159
|
+
} else if (cachedKey === null) {
|
|
1160
|
+
logger.debug("Entry {keyId} found in cache, but it is unavailable.", { keyId });
|
|
1161
|
+
return {
|
|
1162
|
+
key: null,
|
|
1163
|
+
cached: true
|
|
1164
|
+
};
|
|
1169
1165
|
}
|
|
1170
1166
|
return null;
|
|
1171
1167
|
}
|
|
1172
1168
|
async function clearFetchErrorMetadata(keyId, keyCache) {
|
|
1173
1169
|
await keyCache?.setFetchError?.(keyId, null);
|
|
1174
1170
|
}
|
|
1175
|
-
function isDidKeyUrl(keyId) {
|
|
1176
|
-
return keyId.protocol === "did:" && keyId.pathname.startsWith("key:");
|
|
1177
|
-
}
|
|
1178
|
-
async function doRawKeysMatch(left, right) {
|
|
1179
|
-
const [leftRaw, rightRaw] = await Promise.all([crypto.subtle.exportKey("raw", left), crypto.subtle.exportKey("raw", right)]);
|
|
1180
|
-
if (leftRaw.byteLength !== rightRaw.byteLength) return false;
|
|
1181
|
-
const leftBytes = new Uint8Array(leftRaw);
|
|
1182
|
-
const rightBytes = new Uint8Array(rightRaw);
|
|
1183
|
-
return leftBytes.every((byte, index) => byte === rightBytes[index]);
|
|
1184
|
-
}
|
|
1185
|
-
async function isCachedDidKeyValid(key, verificationMethod) {
|
|
1186
|
-
try {
|
|
1187
|
-
return key.id?.href === verificationMethod.id.href && key.controllerId?.href === verificationMethod.controller.href && await doRawKeysMatch(key.publicKey, verificationMethod.publicKey);
|
|
1188
|
-
} catch {
|
|
1189
|
-
return false;
|
|
1190
|
-
}
|
|
1191
|
-
}
|
|
1192
|
-
async function resolveDidKey(cacheKey, cls, keyCache, logger) {
|
|
1193
|
-
if (!isDidKeyUrl(cacheKey)) return null;
|
|
1194
|
-
const keyId = cacheKey.href;
|
|
1195
|
-
if (!(cls === _fedify_vocab.Multikey)) {
|
|
1196
|
-
logger.debug("Failed to resolve did:key {keyId}; did:key verification methods are only supported as Multikey values.", { keyId });
|
|
1197
|
-
return {
|
|
1198
|
-
key: null,
|
|
1199
|
-
cached: false
|
|
1200
|
-
};
|
|
1201
|
-
}
|
|
1202
|
-
let verificationMethod;
|
|
1203
|
-
try {
|
|
1204
|
-
verificationMethod = await (0, _fedify_vocab_runtime.parseDidKeyVerificationMethod)(cacheKey);
|
|
1205
|
-
} catch (error) {
|
|
1206
|
-
logger.debug("Failed to resolve did:key verification method {keyId}: {error}", {
|
|
1207
|
-
keyId,
|
|
1208
|
-
error
|
|
1209
|
-
});
|
|
1210
|
-
return {
|
|
1211
|
-
key: null,
|
|
1212
|
-
cached: false
|
|
1213
|
-
};
|
|
1214
|
-
}
|
|
1215
|
-
const hit = checkCachedKeyHit(await keyCache?.get(cacheKey), keyId, cls, logger);
|
|
1216
|
-
if (hit?.key instanceof _fedify_vocab.Multikey && await isCachedDidKeyValid(hit.key, verificationMethod)) return hit;
|
|
1217
|
-
const key = new _fedify_vocab.Multikey({
|
|
1218
|
-
id: verificationMethod.id,
|
|
1219
|
-
controller: verificationMethod.controller,
|
|
1220
|
-
publicKey: verificationMethod.publicKey
|
|
1221
|
-
});
|
|
1222
|
-
await keyCache?.set(cacheKey, key);
|
|
1223
|
-
await clearFetchErrorMetadata(cacheKey, keyCache);
|
|
1224
|
-
logger.debug("Resolved did:key verification method {keyId}.", { keyId });
|
|
1225
|
-
return {
|
|
1226
|
-
key,
|
|
1227
|
-
cached: false
|
|
1228
|
-
};
|
|
1229
|
-
}
|
|
1230
1171
|
async function resolveFetchedKey(document, cacheKey, keyId, cls, { documentLoader, contextLoader, keyCache, tracerProvider }, logger) {
|
|
1231
1172
|
let object;
|
|
1232
1173
|
try {
|
|
@@ -1341,11 +1282,6 @@ async function fetchKeyWithResult(cacheKey, cls, options, onCachedUnavailable, o
|
|
|
1341
1282
|
]);
|
|
1342
1283
|
const keyId = cacheKey.href;
|
|
1343
1284
|
const keyCache = options.keyCache;
|
|
1344
|
-
const didKey = await resolveDidKey(cacheKey, cls, keyCache, logger);
|
|
1345
|
-
if (didKey != null) {
|
|
1346
|
-
outcome = { result: didKey.key == null ? "invalid" : didKey.cached ? "hit" : "fetched" };
|
|
1347
|
-
return didKey;
|
|
1348
|
-
}
|
|
1349
1285
|
const cached = await getCachedFetchKey(cacheKey, keyId, cls, keyCache, logger);
|
|
1350
1286
|
if (cached?.key === null && cached.cached) {
|
|
1351
1287
|
const cachedUnavailable = await onCachedUnavailable(cacheKey, keyId, keyCache, logger);
|
|
@@ -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 { n as getDurationMs, r as getFederationMetrics, s as measureSignatureKeyFetch } from "./metrics-
|
|
6
|
-
import { i as validateAcceptSignature, n as fulfillAcceptSignature, r as parseAcceptSignature } from "./accept-
|
|
7
|
-
import { o as validateCryptoKey, r as fetchKeyDetailed } from "./key-
|
|
4
|
+
import { n as version, t as name } from "./deno-klNxGW7W.mjs";
|
|
5
|
+
import { n as getDurationMs, r as getFederationMetrics, s as measureSignatureKeyFetch } from "./metrics-CLSPm4dZ.mjs";
|
|
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-o0_ipvUR.mjs";
|
|
8
8
|
import { getLogger } from "@logtape/logtape";
|
|
9
9
|
import { CryptographicKey } from "@fedify/vocab";
|
|
10
10
|
import { SpanStatusCode, trace } from "@opentelemetry/api";
|
|
@@ -1,12 +1,12 @@
|
|
|
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 { _ as recordKeyLookup, n as getDurationMs, t as classifyFetchError } from "./metrics-
|
|
4
|
+
import { n as version, t as name } from "./deno-klNxGW7W.mjs";
|
|
5
|
+
import { _ as recordKeyLookup, n as getDurationMs, t as classifyFetchError } from "./metrics-CLSPm4dZ.mjs";
|
|
6
6
|
import { getLogger } from "@logtape/logtape";
|
|
7
|
-
import { CryptographicKey,
|
|
7
|
+
import { CryptographicKey, Object as Object$1, isActor } from "@fedify/vocab";
|
|
8
8
|
import { SpanKind, SpanStatusCode, trace } from "@opentelemetry/api";
|
|
9
|
-
import { FetchError, getDocumentLoader
|
|
9
|
+
import { FetchError, getDocumentLoader } from "@fedify/vocab-runtime";
|
|
10
10
|
//#region src/sig/key.ts
|
|
11
11
|
/**
|
|
12
12
|
* Checks if the given key is valid and supported. No-op if the key is valid,
|
|
@@ -195,85 +195,24 @@ async function fetchKeyDetailed(keyId, cls, options = {}) {
|
|
|
195
195
|
async function getCachedFetchKey(cacheKey, keyId, cls, keyCache, logger) {
|
|
196
196
|
if (keyCache == null) return null;
|
|
197
197
|
const cachedKey = await keyCache.get(cacheKey);
|
|
198
|
-
const hit = checkCachedKeyHit(cachedKey, keyId, cls, logger);
|
|
199
|
-
if (hit != null) return hit;
|
|
200
|
-
if (cachedKey === null) {
|
|
201
|
-
logger.debug("Entry {keyId} found in cache, but it is unavailable.", { keyId });
|
|
202
|
-
return {
|
|
203
|
-
key: null,
|
|
204
|
-
cached: true
|
|
205
|
-
};
|
|
206
|
-
}
|
|
207
|
-
return null;
|
|
208
|
-
}
|
|
209
|
-
function checkCachedKeyHit(cachedKey, keyId, cls, logger) {
|
|
210
198
|
if (cachedKey instanceof cls && cachedKey.publicKey != null) {
|
|
211
199
|
logger.debug("Key {keyId} found in cache.", { keyId });
|
|
212
200
|
return {
|
|
213
201
|
key: cachedKey,
|
|
214
202
|
cached: true
|
|
215
203
|
};
|
|
204
|
+
} else if (cachedKey === null) {
|
|
205
|
+
logger.debug("Entry {keyId} found in cache, but it is unavailable.", { keyId });
|
|
206
|
+
return {
|
|
207
|
+
key: null,
|
|
208
|
+
cached: true
|
|
209
|
+
};
|
|
216
210
|
}
|
|
217
211
|
return null;
|
|
218
212
|
}
|
|
219
213
|
async function clearFetchErrorMetadata(keyId, keyCache) {
|
|
220
214
|
await keyCache?.setFetchError?.(keyId, null);
|
|
221
215
|
}
|
|
222
|
-
function isDidKeyUrl(keyId) {
|
|
223
|
-
return keyId.protocol === "did:" && keyId.pathname.startsWith("key:");
|
|
224
|
-
}
|
|
225
|
-
async function doRawKeysMatch(left, right) {
|
|
226
|
-
const [leftRaw, rightRaw] = await Promise.all([crypto.subtle.exportKey("raw", left), crypto.subtle.exportKey("raw", right)]);
|
|
227
|
-
if (leftRaw.byteLength !== rightRaw.byteLength) return false;
|
|
228
|
-
const leftBytes = new Uint8Array(leftRaw);
|
|
229
|
-
const rightBytes = new Uint8Array(rightRaw);
|
|
230
|
-
return leftBytes.every((byte, index) => byte === rightBytes[index]);
|
|
231
|
-
}
|
|
232
|
-
async function isCachedDidKeyValid(key, verificationMethod) {
|
|
233
|
-
try {
|
|
234
|
-
return key.id?.href === verificationMethod.id.href && key.controllerId?.href === verificationMethod.controller.href && await doRawKeysMatch(key.publicKey, verificationMethod.publicKey);
|
|
235
|
-
} catch {
|
|
236
|
-
return false;
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
async function resolveDidKey(cacheKey, cls, keyCache, logger) {
|
|
240
|
-
if (!isDidKeyUrl(cacheKey)) return null;
|
|
241
|
-
const keyId = cacheKey.href;
|
|
242
|
-
if (!(cls === Multikey)) {
|
|
243
|
-
logger.debug("Failed to resolve did:key {keyId}; did:key verification methods are only supported as Multikey values.", { keyId });
|
|
244
|
-
return {
|
|
245
|
-
key: null,
|
|
246
|
-
cached: false
|
|
247
|
-
};
|
|
248
|
-
}
|
|
249
|
-
let verificationMethod;
|
|
250
|
-
try {
|
|
251
|
-
verificationMethod = await parseDidKeyVerificationMethod(cacheKey);
|
|
252
|
-
} catch (error) {
|
|
253
|
-
logger.debug("Failed to resolve did:key verification method {keyId}: {error}", {
|
|
254
|
-
keyId,
|
|
255
|
-
error
|
|
256
|
-
});
|
|
257
|
-
return {
|
|
258
|
-
key: null,
|
|
259
|
-
cached: false
|
|
260
|
-
};
|
|
261
|
-
}
|
|
262
|
-
const hit = checkCachedKeyHit(await keyCache?.get(cacheKey), keyId, cls, logger);
|
|
263
|
-
if (hit?.key instanceof Multikey && await isCachedDidKeyValid(hit.key, verificationMethod)) return hit;
|
|
264
|
-
const key = new Multikey({
|
|
265
|
-
id: verificationMethod.id,
|
|
266
|
-
controller: verificationMethod.controller,
|
|
267
|
-
publicKey: verificationMethod.publicKey
|
|
268
|
-
});
|
|
269
|
-
await keyCache?.set(cacheKey, key);
|
|
270
|
-
await clearFetchErrorMetadata(cacheKey, keyCache);
|
|
271
|
-
logger.debug("Resolved did:key verification method {keyId}.", { keyId });
|
|
272
|
-
return {
|
|
273
|
-
key,
|
|
274
|
-
cached: false
|
|
275
|
-
};
|
|
276
|
-
}
|
|
277
216
|
async function resolveFetchedKey(document, cacheKey, keyId, cls, { documentLoader, contextLoader, keyCache, tracerProvider }, logger) {
|
|
278
217
|
let object;
|
|
279
218
|
try {
|
|
@@ -388,11 +327,6 @@ async function fetchKeyWithResult(cacheKey, cls, options, onCachedUnavailable, o
|
|
|
388
327
|
]);
|
|
389
328
|
const keyId = cacheKey.href;
|
|
390
329
|
const keyCache = options.keyCache;
|
|
391
|
-
const didKey = await resolveDidKey(cacheKey, cls, keyCache, logger);
|
|
392
|
-
if (didKey != null) {
|
|
393
|
-
outcome = { result: didKey.key == null ? "invalid" : didKey.cached ? "hit" : "fetched" };
|
|
394
|
-
return didKey;
|
|
395
|
-
}
|
|
396
330
|
const cached = await getCachedFetchKey(cacheKey, keyId, cls, keyCache, logger);
|
|
397
331
|
if (cached?.key === null && cached.cached) {
|
|
398
332
|
const cachedUnavailable = await onCachedUnavailable(cacheKey, keyId, keyCache, logger);
|
|
@@ -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-DeuPW1Oh.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,7 +1,7 @@
|
|
|
1
1
|
import { Temporal } from "@js-temporal/polyfill";
|
|
2
2
|
import { URLPattern } from "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
|
-
import { p as recordDocumentCache } from "./metrics-
|
|
4
|
+
import { p as recordDocumentCache } from "./metrics-CLSPm4dZ.mjs";
|
|
5
5
|
import { getLogger } from "@logtape/logtape";
|
|
6
6
|
import { preloadedContexts } from "@fedify/vocab-runtime";
|
|
7
7
|
//#region src/utils/kv-cache.ts
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Temporal } from "@js-temporal/polyfill";
|
|
2
2
|
import { URLPattern } from "urlpattern-polyfill";
|
|
3
|
-
import { C as recordDocumentCache, d as validateCryptoKey, t as doubleKnock } from "./http-
|
|
3
|
+
import { C as recordDocumentCache, d as validateCryptoKey, t as doubleKnock } from "./http-D0jH0kco.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,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 { n as getDurationMs, r as getFederationMetrics, s as measureSignatureKeyFetch } from "./metrics-
|
|
6
|
-
import { n as fetchKey, o as validateCryptoKey } from "./key-
|
|
4
|
+
import { n as version, t as name } from "./deno-klNxGW7W.mjs";
|
|
5
|
+
import { n as getDurationMs, r as getFederationMetrics, s as measureSignatureKeyFetch } from "./metrics-CLSPm4dZ.mjs";
|
|
6
|
+
import { n as fetchKey, o as validateCryptoKey } from "./key-o0_ipvUR.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-klNxGW7W.mjs";
|
|
5
5
|
import { metrics } from "@opentelemetry/api";
|
|
6
6
|
import { FetchError } from "@fedify/vocab-runtime";
|
|
7
7
|
//#region src/federation/metrics.ts
|
|
@@ -167,11 +167,11 @@ var FederationMetrics = class {
|
|
|
167
167
|
unit: "{change}"
|
|
168
168
|
});
|
|
169
169
|
this.keyLookup = meter.createCounter("activitypub.key.lookup", {
|
|
170
|
-
description: "Public-key lookup attempts performed by Fedify, including cache hits
|
|
170
|
+
description: "Public-key lookup attempts performed by Fedify, including both cache hits and remote fetches.",
|
|
171
171
|
unit: "{lookup}"
|
|
172
172
|
});
|
|
173
173
|
this.keyLookupDuration = meter.createHistogram("activitypub.key.lookup.duration", {
|
|
174
|
-
description: "Duration of public-key lookups performed by Fedify, including
|
|
174
|
+
description: "Duration of public-key lookups performed by Fedify, including any remote fetch.",
|
|
175
175
|
unit: "ms",
|
|
176
176
|
advice: { explicitBucketBoundaries: [
|
|
177
177
|
5,
|
|
@@ -325,10 +325,10 @@ var FederationMetrics = class {
|
|
|
325
325
|
this.httpServerRequestCount.add(1, attributes);
|
|
326
326
|
this.httpServerRequestDuration.record(durationMs, attributes);
|
|
327
327
|
}
|
|
328
|
-
recordQueueTaskEnqueued(common, attempt) {
|
|
328
|
+
recordQueueTaskEnqueued(common, attempt, count = 1) {
|
|
329
329
|
const attributes = buildQueueTaskAttributes(common);
|
|
330
330
|
attributes["fedify.queue.task.attempt"] = attempt;
|
|
331
|
-
this.queueTaskEnqueued.add(
|
|
331
|
+
this.queueTaskEnqueued.add(count, attributes);
|
|
332
332
|
}
|
|
333
333
|
recordQueueTaskStarted(common) {
|
|
334
334
|
this.queueTaskStarted.add(1, buildQueueTaskAttributes(common));
|
|
@@ -339,9 +339,10 @@ var FederationMetrics = class {
|
|
|
339
339
|
decrementQueueTaskInFlight(common) {
|
|
340
340
|
this.queueTaskInFlight.add(-1, buildQueueTaskInFlightAttributes(common));
|
|
341
341
|
}
|
|
342
|
-
recordQueueTaskOutcome(common, result, durationMs) {
|
|
342
|
+
recordQueueTaskOutcome(common, result, durationMs, failureReason) {
|
|
343
343
|
const attributes = buildQueueTaskAttributes(common);
|
|
344
344
|
attributes["fedify.queue.task.result"] = result;
|
|
345
|
+
if (failureReason != null && result === "failed") attributes["fedify.task.failure_reason"] = failureReason;
|
|
345
346
|
if (result === "completed") this.queueTaskCompleted.add(1, attributes);
|
|
346
347
|
else if (result === "failed") this.queueTaskFailed.add(1, attributes);
|
|
347
348
|
this.queueTaskDuration.record(durationMs, attributes);
|
|
@@ -435,6 +436,7 @@ function buildQueueTaskAttributes(common) {
|
|
|
435
436
|
const nativeRetrial = common.queue?.nativeRetrial;
|
|
436
437
|
if (typeof nativeRetrial === "boolean") attributes["fedify.queue.native_retrial"] = nativeRetrial;
|
|
437
438
|
if (common.activityType != null) attributes["activitypub.activity.type"] = common.activityType;
|
|
439
|
+
if (common.taskName != null) attributes["fedify.task.name"] = common.taskName;
|
|
438
440
|
return attributes;
|
|
439
441
|
}
|
|
440
442
|
function buildQueueTaskInFlightAttributes(common) {
|