@camstack/system 1.2.219 → 1.2.221
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/addon-runner.js +2 -2
- package/dist/addon-runner.mjs +2 -2
- package/dist/addon-utils.js +1 -1
- package/dist/addon-utils.mjs +1 -1
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
- package/dist/builtins/alerts/alerts.addon.js +1 -1
- package/dist/builtins/alerts/alerts.addon.mjs +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +1 -1
- package/dist/builtins/console-logging/index.js +1 -1
- package/dist/builtins/console-logging/index.mjs +1 -1
- package/dist/builtins/core-blocks/core-blocks.addon.js +1 -1
- package/dist/builtins/core-blocks/core-blocks.addon.mjs +1 -1
- package/dist/builtins/device-manager/device-manager.addon.js +2 -2
- package/dist/builtins/device-manager/device-manager.addon.mjs +2 -2
- package/dist/builtins/doorbell/virtual-doorbell.addon.js +1 -1
- package/dist/builtins/doorbell/virtual-doorbell.addon.mjs +1 -1
- package/dist/builtins/hub-forwarder/index.js +1 -1
- package/dist/builtins/hub-forwarder/index.mjs +1 -1
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
- package/dist/builtins/local-auth/local-auth.addon.js +1 -1
- package/dist/builtins/local-auth/local-auth.addon.mjs +1 -1
- package/dist/builtins/local-network/local-network.addon.js +1 -1
- package/dist/builtins/local-network/local-network.addon.mjs +1 -1
- package/dist/builtins/loki-logging/index.js +1 -1
- package/dist/builtins/loki-logging/index.mjs +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
- package/dist/builtins/platform-probe/index.js +1 -1
- package/dist/builtins/platform-probe/index.mjs +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
- package/dist/builtins/snapshot/index.js +1 -1
- package/dist/builtins/snapshot/index.mjs +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +0 -0
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +0 -0
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +1 -1
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +1 -1
- package/dist/builtins/system-config/system-config.addon.js +1 -1
- package/dist/builtins/system-config/system-config.addon.mjs +1 -1
- package/dist/builtins/winston-logging/index.js +1 -1
- package/dist/builtins/winston-logging/index.mjs +1 -1
- package/dist/{custom-action-registry-DKWhaWL1.js → custom-action-registry-DvVMHLfJ.js} +1 -1
- package/dist/{custom-action-registry-B6gOtUWA.mjs → custom-action-registry-DvtOs-tp.mjs} +1 -1
- package/dist/{dist-B17W9ngu.js → dist-0sWJNwme.js} +261 -4
- package/dist/{dist-Cyz5_i7z.mjs → dist-T9GvfhgV.mjs} +261 -4
- package/dist/index.js +71 -32
- package/dist/index.mjs +65 -33
- package/dist/kernel/gc-census.d.ts +144 -0
- package/dist/kernel/heap-watch.d.ts +8 -0
- package/dist/kernel/socket-plane-report.d.ts +37 -0
- package/dist/kernel/transport/cap-action-census.d.ts +218 -0
- package/dist/kernel/transport/cap-child-index.d.ts +49 -0
- package/dist/kernel/transport/index.d.ts +2 -0
- package/dist/kernel/transport/local-child-registry.d.ts +63 -4
- package/dist/kernel/transport/local-transport.d.ts +9 -0
- package/dist/kernel/transport/socket-channel.d.ts +21 -0
- package/dist/{manifest-system-deps-g_nK0xsF.js → manifest-system-deps-DfpwaXkh.js} +550 -27
- package/dist/{manifest-system-deps-C7dihwWT.mjs → manifest-system-deps-iadzxSBr.mjs} +509 -28
- package/dist/{retired-settings-keys-CjvB7Etx.js → retired-settings-keys-Dh-XMfFx.js} +1 -1
- package/dist/{retired-settings-keys-BCYUrdsA.mjs → retired-settings-keys-DmVZAH9M.mjs} +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { a as __toCommonJS, i as __require, n as __esmMin, o as __toESM$1, r as __exportAll, t as __commonJSMin$1 } from "./chunk-CNf5ZN-e.mjs";
|
|
2
|
-
import { A as addonSettingsCapability, Dt as procedureAuthKey, Ft as scopesAllowDeviceCap, Jt as errMsg$1, Mt as resolveMethodAuth, Pt as scopesAllowAddon, Qt as DEVICE_STATUS_METHOD, Xt as DATAPLANE_SECRET_HEADER$1, Zt as DEVICE_SETTINGS_CONTRIBUTION_METHODS, _ as RUNTIME_DEFAULTS, _n as readinessKey, _t as logLevelAtMost, an as asJsonObject$1, at as isArrayOutputSchema, cn as createEvent, ct as isObjectInput, dn as expandCapMethods, dt as isVoidInput, ft as kebabToCamel, gn as parseJsonUnknown, h as METHOD_ACCESS_MAP, hn as parseJsonObject, ln as emitDownForOwnedCaps, mt as lifecycleJobSchema, nn as ReadinessRegistry, on as asNumber, ot as isCollectionArrayMethod, p as LOG_LEVEL_RANK, rn as ReadinessTimeoutError, sn as asString$1, t as ALL_CAPABILITY_DEFINITIONS, tt as extractNestedAddonId, vn as resolveCapMount, vt as looseSchema, wt as objectInputDeclaresAddonId, xn as EventCategory$1, yn as scopeKey } from "./dist-
|
|
2
|
+
import { A as addonSettingsCapability, Dt as procedureAuthKey, Ft as scopesAllowDeviceCap, Jt as errMsg$1, Mt as resolveMethodAuth, Pt as scopesAllowAddon, Qt as DEVICE_STATUS_METHOD, Xt as DATAPLANE_SECRET_HEADER$1, Zt as DEVICE_SETTINGS_CONTRIBUTION_METHODS, _ as RUNTIME_DEFAULTS, _n as readinessKey, _t as logLevelAtMost, an as asJsonObject$1, at as isArrayOutputSchema, cn as createEvent, ct as isObjectInput, dn as expandCapMethods, dt as isVoidInput, ft as kebabToCamel, gn as parseJsonUnknown, h as METHOD_ACCESS_MAP, hn as parseJsonObject, ln as emitDownForOwnedCaps, mt as lifecycleJobSchema, nn as ReadinessRegistry, on as asNumber, ot as isCollectionArrayMethod, p as LOG_LEVEL_RANK, rn as ReadinessTimeoutError, sn as asString$1, t as ALL_CAPABILITY_DEFINITIONS, tt as extractNestedAddonId, vn as resolveCapMount, vt as looseSchema, wt as objectInputDeclaresAddonId, xn as EventCategory$1, yn as scopeKey } from "./dist-T9GvfhgV.mjs";
|
|
3
3
|
import { AlertCenterAddon } from "./builtins/alerts/alerts.addon.mjs";
|
|
4
4
|
import "./builtins/alerts/index.mjs";
|
|
5
5
|
import { t as formatLogLine } from "./formatter-B7qW8bPJ.mjs";
|
|
@@ -26,9 +26,9 @@ import "./builtins/system-config/index.mjs";
|
|
|
26
26
|
import { WinstonDestination, WinstonLoggingAddon } from "./builtins/winston-logging/index.mjs";
|
|
27
27
|
import { _ as fetchJson, a as createFileDataPlaneHandler, c as parseRangeHeader, d as ModelDownloadService, f as collectModelFiles, g as ensureModel, h as downloadModel, i as startEventLoopStallMonitor, l as parseTokenizedUrl, m as downloadFile, n as STALL_TICK_MS, o as contentTypeFor, p as deleteModelFromDisk, r as attributeStall, s as createAuthenticatedFileServer, t as STALL_REPORT_MS, u as resolveFilePath, v as getModelFilePath, y as isModelDownloaded } from "./event-loop-stall-monitor-GPrVvx14.mjs";
|
|
28
28
|
import { C as registerLanHttpHandler, S as readLanHttpState, _ as DEFAULT_LAN_HTTP_PORT, a as writeTlsMode, b as bindPendingLanHttp, c as loadTlsCert, d as collectCertIdentity, f as CA_VALIDITY_DAYS, g as evaluateExistingCert, h as SERVER_AUTH_OID, i as writeExtraSans, l as reissueTlsLeaf, m as MAX_LEAF_VALIDITY_DAYS, n as readTlsAccessStatus, o as validateUploadedTls, p as LEAF_RENEWAL_WINDOW_DAYS, r as readTlsMode, s as ensureTlsCert, t as readExtraSans, u as CA_COMMON_NAME, v as allFamiliesListenHost, x as closeLanHttp, y as applyLanHttp } from "./tls-2xbgg78V.mjs";
|
|
29
|
-
import { $ as buildUdsNativeCapProxy, $t as ARRAY_BUFFER_RELEASE_MIN_DROP_RATIO, A as createUdsLoggerWithControl, An as sampleSocketDirection, At as HUB_MAIN_RSS_BUDGET_MB, B as readMoleculerFanoutMode, Bt as createV8Reclaimer, C as ipcParentLink, Cn as createSocketPlaneReader, Ct as createAddonDataPlaneFacility, D as createUdsEventBus, Dn as EMPTY_SOCKET_DIRECTION, Dt as HEAP_WATCH_INTERVAL_MS, E as createUdsEventBridge, En as readSocketQueues, Et as HEAP_RECLAIM_TRIGGER_MB, F as CapRouteError, Fn as
|
|
29
|
+
import { $ as buildUdsNativeCapProxy, $t as ARRAY_BUFFER_RELEASE_MIN_DROP_RATIO, A as createUdsLoggerWithControl, An as sampleSocketDirection, At as HUB_MAIN_RSS_BUDGET_MB, B as readMoleculerFanoutMode, Bn as EVENT_PLANE_TOP_N, Bt as createV8Reclaimer, C as ipcParentLink, Cn as createSocketPlaneReader, Ct as createAddonDataPlaneFacility, D as createUdsEventBus, Dn as EMPTY_SOCKET_DIRECTION, Dt as HEAP_WATCH_INTERVAL_MS, E as createUdsEventBridge, En as readSocketQueues, Et as HEAP_RECLAIM_TRIGGER_MB, F as CapRouteError, Fn as EMPTY_CAP_ACTION_READING, Ft as RUNNER_RSS_BUDGET_ENV, G as createLocalTransport, Gt as reclaimIntervalMs, H as PARENT_ROUTED_PROVIDER_ADDON_ID, Hn as createEventPlaneReader, Ht as hubMainRssBudget, I as classifyCapRoute, In as MAX_CAP_ACTIONS_PER_PEER, It as ZERO_LOOP_DELAY, J as SocketChannel, Jt as startRunnerHeapWatch, K as UdsLocalTransportClient, Kt as shouldReclaim, L as LocalChildClient, Ln as capActionLabel, Lt as buildHeapSample, M as AGENT_CAP_FWD_SERVICE, Mn as socketDirectionMessages, Mt as RSS_BUDGET_REANNOUNCE_MIN_MS, N as CapRouteResolver, Nn as CAP_ACTION_OVERFLOW_LABEL, Nt as RSS_BUDGET_RELEASE_RATIO, O as udsChildLogToWorkerEntry, On as createSocketDirectionCounters, Ot as HEAP_WATCH_WARN_RATIO, P as callWithServiceDiscovery, Pn as CAP_ACTION_UNLABELLED, Pt as RUNNER_HEAP_WATCH_INTERVAL_MS, Q as buildNativeCapProxy, Qt as ARRAY_BUFFER_CENSUS_THRESHOLD_MB, R as LocalChildRegistry, Rn as createCapActionCensus, Rt as createDeferredHeapWatchSink, S as buildLinkChain, Sn as createSocketPlaneMeter, St as runNpm, T as createParentUnownedCallHandler, Tn as formatSocketPlane, Tt as HEAP_RECLAIM_STEADY_STATE_INTERVAL_MS, U as __resetCapUsageRegistryForTests, Un as diffEventPlane, Ut as nextRssBudgetState, V as CapUsageRegistry, Vn as createEventPlaneMeter, Vt as describeRss, W as getCapUsageRegistry, Wn as formatEventPlane, Wt as parseRssBudgetMb, X as FrameDecoder, Xt as ARRAY_BUFFER_CENSUS_COOLDOWN_MS, Y as localEndpointPath, Yt as strandedMb, Z as encodeFrame, Zt as ARRAY_BUFFER_CENSUS_SUSTAIN_MS, _ as AddonDepsManager, _n as createMeshQueueReader, _t as CapabilityUnavailableError, a as createUdsAddonContext, an as HEAP_SPACE_REPORT_MIN_MB, at as createAddonService, b as brokerCallForCap, bn as SOCKET_PLANE_TOP_N, bt as resolveAddonClass, c as getOrInitReadinessRegistryForClient, cn as heapSpaceField, ct as capActionName, d as clusterEventTopic, dn as OUTBOUND_QUEUE_COOLDOWN_MS, dt as capServiceName, en as createArrayBufferCensusGate, et as createBrokerDeviceManagerApi, f as getBrokerEventBus, fn as OUTBOUND_QUEUE_SUSTAIN_MS, ft as parseCapAction, g as subscribePassthrough, gn as MESH_QUEUE_TOP_N, gt as CapabilityHandle, h as setNodeEventInterest, hn as formatOutboundQueueVerdict, ht as DeviceRegistry, i as createAddonContext, in as DECISIVE_HEAP_SPACES, j as AGENT_CAP_FWD_ACTION, jn as socketDirectionBytes, jt as HUB_RSS_BUDGET_ENV, k as createUdsLogger, kn as recordSocketFrame, kt as HUB_MAIN_HEAP_WATCH_LABEL, l as setHubConnected, ln as readHeapSpaces, lt as capActionSuffix, m as registerEventBusService, mn as createOutboundQueueGate, mt as serializeTypedArrays, n as installManifestPythonDeps, nn as formatArrayBufferCensus, o as getWorkerDeviceRegistry, on as emitHeapDiagnosticReport, ot as validateProviderRegistrations, p as getMoleculerEventStats, pn as OUTBOUND_QUEUE_THRESHOLD_BYTES, pt as deserializeTypedArrays, q as UdsLocalTransportServer, qt as startHeapWatch, r as adaptBrokerToCluster, rn as isArrayBufferCensusReport, rt as mountNativeCapService, s as getOrInitReadinessRegistry, sn as formatHeapSpaces, st as NATIVE_PROVIDER_SERVICE_INFIX, t as installManifestSystemDeps, tn as createInspectorArrayBufferCensus, u as EVENT_TOPIC_PREFIX, un as selectReportedSpaces, ut as capBareAction, v as createKernelHwAccel, vn as formatMeshQueue, vt as copyBundledNativeModules, w as localProviderLink, wn as diffSocketPlane, wt as HEAP_RECLAIM_MIN_INTERVAL_MS, x as brokerTransportLink, xn as SOCKET_QUEUE_TOP_N, xt as resolveNpmInvocation, y as resolveHwAccel, yn as EMPTY_SOCKET_PLANE_BASELINE, yt as installManifestNativeDeps, z as UDS_NO_ROUTE_PREFIX, zn as diffCapActionCensus, zt as createLoopDelayMeter } from "./manifest-system-deps-iadzxSBr.mjs";
|
|
30
30
|
import { n as getSinglePidStats, t as getPidStats } from "./resource-monitor-Vp0bPV3U.mjs";
|
|
31
|
-
import { t as CustomActionRegistry } from "./custom-action-registry-
|
|
31
|
+
import { t as CustomActionRegistry } from "./custom-action-registry-DvtOs-tp.mjs";
|
|
32
32
|
import { z } from "zod";
|
|
33
33
|
import { createHash, randomUUID, timingSafeEqual } from "node:crypto";
|
|
34
34
|
import { PYTHON_VERSION, buildBinaryPath, downloadBinary, ensureBinary, ensureFfmpeg, ensurePython, findInPath, getFfmpegDownloadUrl, getPlatformInfo, getPythonDownloadUrl, installPythonPackages, installPythonRequirements } from "@camstack/types/node";
|
|
@@ -78878,16 +78878,36 @@ var require_udp_broadcaster = /* @__PURE__ */ __commonJSMin$1(((exports, module)
|
|
|
78878
78878
|
var require_parser = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
78879
78879
|
var Writable = __require("stream").Writable;
|
|
78880
78880
|
var { resolvePacketType } = require_constants();
|
|
78881
|
-
/**
|
|
78882
|
-
|
|
78883
|
-
*
|
|
78884
|
-
* @typedef {import("./parser")} ParserClass
|
|
78885
|
-
*/
|
|
78881
|
+
/** Moleculer TCP framing: CRC byte, 4-byte BE total length, type byte, payload. */
|
|
78882
|
+
var HEADER_BYTES = 6;
|
|
78886
78883
|
/**
|
|
78887
78884
|
* TCP packet parser
|
|
78888
78885
|
* @class Parser
|
|
78889
78886
|
* @extends {Writable}
|
|
78890
78887
|
* @implements {ParserClass}
|
|
78888
|
+
*
|
|
78889
|
+
* ── CamStack patch (D457) — the accumulator is no longer quadratic ─────────
|
|
78890
|
+
*
|
|
78891
|
+
* The shipped `_write` did, ONCE PER SOCKET CHUNK that left a partial packet:
|
|
78892
|
+
*
|
|
78893
|
+
* packet = Buffer.concat([this.buf, chunk]); // copies the whole pending
|
|
78894
|
+
* this.buf = Buffer.from(packet); // copies it AGAIN
|
|
78895
|
+
*
|
|
78896
|
+
* so a message of M bytes arriving in chunks of c copied ~2·M²/2c bytes on the
|
|
78897
|
+
* receiving event loop — quadratic in the chunk COUNT. On CamStack's hub the
|
|
78898
|
+
* mesh carries base64 JPEG cross-node (`pipelineRunner.getNativeCrop`
|
|
78899
|
+
* with `encodeJpeg`, `pipelineRunner.runStatelessStep{frameJpeg}`) at
|
|
78900
|
+
* `maxPacketSize: 10 MiB`, and a 50 s V8 profile of hub-main put **20.8 % of
|
|
78901
|
+
* its busy main thread inside this one function**.
|
|
78902
|
+
*
|
|
78903
|
+
* The fix is the same one CamStack applied to its own UDS `FrameDecoder`:
|
|
78904
|
+
* hold the pending chunks in a LIST, concatenate ONCE when a whole packet is
|
|
78905
|
+
* available, and never at all while one is still incomplete. Everything else —
|
|
78906
|
+
* the framing, the CRC check and its position, the `maxPacketSize` rule
|
|
78907
|
+
* (accumulated bytes, not the declared length, exactly as before), the `data`
|
|
78908
|
+
* event shape, the error text — is byte-for-byte the original behaviour, and
|
|
78909
|
+
* `packages/system/src/kernel/__tests__/moleculer/mesh-tcp-parser.spec.ts`
|
|
78910
|
+
* asserts each of those cases alongside the copy accounting.
|
|
78891
78911
|
*/
|
|
78892
78912
|
var Parser = class extends Writable {
|
|
78893
78913
|
/**
|
|
@@ -78898,32 +78918,44 @@ var require_parser = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
|
78898
78918
|
constructor(options, maxPacketSize) {
|
|
78899
78919
|
super(options);
|
|
78900
78920
|
this.maxPacketSize = maxPacketSize;
|
|
78901
|
-
|
|
78921
|
+
/** Pending chunks, newest last. Never concatenated until a packet completes. */
|
|
78922
|
+
this.bufs = [];
|
|
78923
|
+
/** Total bytes across `bufs` — the old `this.buf.length`. */
|
|
78924
|
+
this.bufLen = 0;
|
|
78925
|
+
}
|
|
78926
|
+
/** The first `HEADER_BYTES` pending bytes, without flattening the rest. */
|
|
78927
|
+
_header() {
|
|
78928
|
+
const first = this.bufs[0];
|
|
78929
|
+
if (first.length >= HEADER_BYTES) return first;
|
|
78930
|
+
const head = Buffer.allocUnsafe(HEADER_BYTES);
|
|
78931
|
+
let written = 0;
|
|
78932
|
+
for (let i = 0; i < this.bufs.length && written < HEADER_BYTES; i++) {
|
|
78933
|
+
const b = this.bufs[i];
|
|
78934
|
+
const take = Math.min(HEADER_BYTES - written, b.length);
|
|
78935
|
+
b.copy(head, written, 0, take);
|
|
78936
|
+
written += take;
|
|
78937
|
+
}
|
|
78938
|
+
return head;
|
|
78902
78939
|
}
|
|
78903
78940
|
_write(chunk, encoding, cb) {
|
|
78904
|
-
|
|
78905
|
-
|
|
78906
|
-
|
|
78907
|
-
|
|
78908
|
-
|
|
78909
|
-
|
|
78910
|
-
|
|
78911
|
-
|
|
78912
|
-
|
|
78913
|
-
|
|
78914
|
-
if (this.
|
|
78915
|
-
const
|
|
78916
|
-
|
|
78917
|
-
const
|
|
78918
|
-
|
|
78919
|
-
|
|
78920
|
-
|
|
78921
|
-
|
|
78922
|
-
packet = packet.slice(length);
|
|
78923
|
-
} else {
|
|
78924
|
-
this.buf = Buffer.from(packet);
|
|
78925
|
-
return cb();
|
|
78926
|
-
}
|
|
78941
|
+
if (this.bufLen > 0) this.bufs.push(chunk);
|
|
78942
|
+
else this.bufs = [chunk];
|
|
78943
|
+
this.bufLen += chunk.length;
|
|
78944
|
+
while (this.bufLen > 0) {
|
|
78945
|
+
if (this.bufLen < HEADER_BYTES) return cb();
|
|
78946
|
+
if (this.maxPacketSize && this.bufLen > this.maxPacketSize) return cb(/* @__PURE__ */ new Error(`Incoming packet is larger than the 'maxPacketSize' limit (${this.bufLen} > ${this.maxPacketSize})!`));
|
|
78947
|
+
const header = this._header();
|
|
78948
|
+
const crc = header[1] ^ header[2] ^ header[3] ^ header[4] ^ header[5];
|
|
78949
|
+
if (crc !== header[0]) return cb(/* @__PURE__ */ new Error("Invalid packet CRC! " + crc));
|
|
78950
|
+
const length = header.readInt32BE(1);
|
|
78951
|
+
if (this.bufLen < length) return cb();
|
|
78952
|
+
const packet = this.bufs.length === 1 ? this.bufs[0] : Buffer.concat(this.bufs, this.bufLen);
|
|
78953
|
+
const msg = packet.slice(HEADER_BYTES, length);
|
|
78954
|
+
const type = resolvePacketType(packet[5]);
|
|
78955
|
+
this.emit("data", type, msg);
|
|
78956
|
+
const rest = packet.slice(length);
|
|
78957
|
+
this.bufs = rest.length > 0 ? [rest] : [];
|
|
78958
|
+
this.bufLen = rest.length;
|
|
78927
78959
|
}
|
|
78928
78960
|
cb();
|
|
78929
78961
|
}
|
|
@@ -95751,4 +95783,4 @@ var LifecycleJobEngine = class {
|
|
|
95751
95783
|
}
|
|
95752
95784
|
};
|
|
95753
95785
|
//#endregion
|
|
95754
|
-
export { AGENT_CAP_FWD_ACTION, AGENT_CAP_FWD_SERVICE, AGENT_READINESS_SERVICE_NAME, ALL_CAPABILITY_DEFINITIONS, ARRAY_BUFFER_CENSUS_COOLDOWN_MS, ARRAY_BUFFER_CENSUS_SUSTAIN_MS, ARRAY_BUFFER_CENSUS_THRESHOLD_MB, ARRAY_BUFFER_RELEASE_MIN_DROP_RATIO, AddonApiFactory, AddonDepsManager, AddonEngineManager, AddonHealthMonitor, AddonInstaller, AddonLoader, AddonManifest, AddonRouteRegistry, AlertCenterAddon, ApiKeyManager, AuthManager, CA_COMMON_NAME, CA_VALIDITY_DAYS, CLUSTER_SECRET_MISMATCH_TYPE, CLUSTER_SECRET_REJECTED_EXIT_CODE, CORE_CAP_SERVICE_NAME, CapRouteError, CapRouteResolver, CapUsageRegistry, CapabilityHandle, CapabilityRegistry, CapabilityUnavailableError, ConfigManager, ConfigStore, ConsoleDestination, ConsoleLoggingAddon, CoreBlocksAddon, CustomActionRegistry, DECISIVE_HEAP_SPACES, DEFAULT_DATA_PATH, DEFAULT_LAN_HTTP_PORT, DEFAULT_LOG_LEVEL, DEVICE_SETTINGS_CONTRIBUTION_METHODS, DEVICE_STATUS_METHOD, DataPlaneRegistry, DeviceManagerAddon, DeviceRegistry, DeviceStore, EMPTY_SOCKET_DIRECTION, EMPTY_SOCKET_PLANE_BASELINE, EVENT_PLANE_TOP_N, EVENT_TOPIC_PREFIX, EngineManagerResolver, EventBus, FeatureManager, FilesystemStorageAddon, FilesystemStorageProvider, FrameDecoder, FsStorageBackend, HEALTH_MONITOR_GRACE_PERIOD_MS, HEALTH_MONITOR_RETRY_INTERVALS_MS, HEALTH_MONITOR_TICK_MS, HEAP_RECLAIM_MIN_INTERVAL_MS, HEAP_RECLAIM_STEADY_STATE_INTERVAL_MS, HEAP_RECLAIM_TRIGGER_MB, HEAP_SPACE_REPORT_MIN_MB, HEAP_WATCH_INTERVAL_MS, HEAP_WATCH_WARN_RATIO, HUB_CAP_FWD_ACTION, HUB_CAP_FWD_SERVICE, HUB_MAIN_HEAP_WATCH_LABEL, HUB_MAIN_RSS_BUDGET_MB, HUB_RSS_BUDGET_ENV, HubForwarderAddon, HubForwarderDestination, HubLogForwarder, HubNodeRegistry, INFRA_CAPABILITIES, IntegrationRegistry, JobJournal, LEAF_RENEWAL_WINDOW_DAYS, LifecycleJobEngine, LifecycleStateMachine, LivenessMonitorAddon, LocalAuthAddon, LocalChildClient, LocalChildRegistry, LogManager, LogRingBuffer, LoggingGate, LokiDestination, LokiLoggingAddon, MAX_LEAF_VALIDITY_DAYS, MESH_QUEUE_TOP_N, METHOD_ACCESS_MAP, ModelDownloadService, NATIVE_PROVIDER_SERVICE_INFIX, NATIVE_SCAN_DEPTH, NativeMetricsAddon, NativeMetricsProvider, NetworkQualityTracker, NotificationService, OUTBOUND_QUEUE_COOLDOWN_MS, OUTBOUND_QUEUE_SUSTAIN_MS, OUTBOUND_QUEUE_THRESHOLD_BYTES, PARENT_ROUTED_PROVIDER_ADDON_ID, PYTHON_VERSION, PipelineRunner, PipelineValidator, PythonEnvManager, QUARANTINE_DIRNAME, RESTART_MARKER_FILE, RSS_BUDGET_REANNOUNCE_MIN_MS, RSS_BUDGET_RELEASE_RATIO, RUNNER_HEAP_WATCH_INTERVAL_MS, RUNNER_RSS_BUDGET_ENV, RUNTIME_DEFAULTS, ReadinessRegistry, ReadinessTimeoutError, ReplEngine, RingBuffer, SERVER_AUTH_OID, SOCKET_PLANE_TOP_N, SOCKET_QUEUE_TOP_N, STALL_REPORT_MS, STALL_TICK_MS, ScopedLogger, ScopedTokenManager, SocketChannel, SqliteSettingsAddon, SqliteSettingsBackend, StagingArea, StorageLocationManager, StorageManager, StorageOrchestratorAddon, StorageOrchestratorService, SystemConfigAddon, SystemEventBus, TRADITIONAL_NATIVE_PACKAGES, ToastService, UDS_NO_ROUTE_PREFIX, UdsLocalTransportClient, UdsLocalTransportServer, UserManager, WinstonDestination, WinstonLoggingAddon, ZERO_LOOP_DELAY, __resetCapUsageRegistryForTests, __resetLoggingGateForTests, adaptBrokerToCluster, addonSettingsCapability, allFamiliesListenHost, applyLanHttp, attributeStall, bindPendingLanHttp, bootstrapSchema, brokerCallForCap, brokerTransportLink, buildBinaryPath, buildCapRouters, buildHeapSample, buildLinkChain, buildNativeCapProxy, buildNodeManifest, buildStorageLocationRegistry, buildUdsNativeCapProxy, builderMountedCapNames, callRegisterNodeWithRetry, callWithServiceDiscovery, canServeDataPlane, capActionName, capActionSuffix, capBareAction, capServiceName, classifyAddonDir, classifyCapRoute, clearPendingRestart, closeLanHttp, clusterEventTopic, clusterSecretMatches, collectCertIdentity, collectModelFiles, contentTypeFor, copyDirRecursive, copyExtraFileDirs, createAddonContext, createAddonDataPlaneFacility, createAddonService, createArrayBufferCensusGate, createAuthenticatedFileServer, createBroker, createBrokerDeviceManagerApi, createCoreCapService, createDeferredHeapWatchSink, createDoorSettingsView, createEventPlaneMeter, createEventPlaneReader, createFileDataPlaneHandler, createHubCapForwardService, createHubService, createInspectorArrayBufferCensus, createKernelHwAccel, createLocalTransport, createLoopDelayMeter, createMeshQueueReader, createOutboundQueueGate, createParentUnownedCallHandler, createProcessService, createReadinessService, createReadinessServiceForRegistry, createScopedProcessManager, createSocketDirectionCounters, createSocketPlaneMeter, createSocketPlaneReader, createStreamProbeBrokerService, createUdsAddonContext, createUdsEventBridge, createUdsEventBus, createUdsLogger, createUdsLoggerWithControl, createV8Reclaimer, deleteModelFromDisk, deriveAgentListenPort, describeProviderKindDrift, describeRss, detectWorkspacePackagesDir, diffEventPlane, diffSocketPlane, downloadBinary, downloadFile, downloadModel, emitDownForOwnedCaps, emitHeapDiagnosticReport, encodeFrame, ensureAddonNativePrebuilds, ensureBinary, ensureDir, ensureFfmpeg, ensureLibraryBuilt, ensureModel, ensureNativePrebuilds, ensurePython, ensureTlsCert, evaluateExistingCert, expandCapMethods, fetchJson, findInPath, formatArrayBufferCensus, formatEventPlane, formatHeapSpaces, formatLogLine, formatMeshQueue, formatOutboundQueueVerdict, formatSocketPlane, getBrokerEventBus, getCapUsageRegistry, getFfmpegDownloadUrl, getLoggingGate, getModelFilePath, getMoleculerEventStats, getOrInitReadinessRegistry, getOrInitReadinessRegistryForClient, getPidStats, getPlatformInfo, getPythonDownloadUrl, getRestartMarkerPath, getSinglePidStats, getWorkerDeviceRegistry, hasDotNode, hashClusterSecret, heapSpaceField, hubMainRssBudget, installManifestNativeDeps, installManifestPythonDeps, installManifestSystemDeps, installPackageFromNpm, installPythonPackages, installPythonRequirements, ipcParentLink, isAddonDeploySource, isArrayBufferCensusReport, isArrayOutputSchema, isClusterSecretMismatchError, isCollectionArrayMethod, isInfraCapability, isModelDownloaded, isSourceNewer, isolatedBuiltinPhase, loadTlsCert, localEndpointPath, localProviderLink, mountNativeCapService, nextRssBudgetState, parseCapAction, parseRangeHeader, parseRssBudgetMb, parseTokenizedUrl, partitionIsolatedBuiltinIds, proxyToUpstream, quarantineAddonResidue, readExtraSans, readHeapSpaces, readLanHttpState, readMoleculerFanoutMode, readPendingRestart, readSocketQueues, readTlsAccessStatus, readTlsMode, readinessKey, reclaimIntervalMs, recordSocketFrame, registerEventBusService, registerLanHttpHandler, reissueTlsLeaf, resolveFilePath, resolveHwAccel, resolveNpmInvocation, runHubAddonBoot, runNpm, sampleSocketDirection, scheduleSelfRestart, scopeKey, scopesAllowAddon, scopesAllowDeviceCap, selectAddonResidue, selectReportedSpaces, serializeTypedArrays, setHubConnected, setNodeEventInterest, shouldReclaim, socketDirectionBytes, socketDirectionMessages, startEventLoopStallMonitor, startHeapWatch, startRunnerHeapWatch, strandedMb, stripCamstackDeps, subscribePassthrough, udsChildLogToWorkerEntry, validateProviderRegistrations, validateUploadedTls, waitUntilReady, writeExtraSans, writePendingRestart, writeTlsMode };
|
|
95786
|
+
export { AGENT_CAP_FWD_ACTION, AGENT_CAP_FWD_SERVICE, AGENT_READINESS_SERVICE_NAME, ALL_CAPABILITY_DEFINITIONS, ARRAY_BUFFER_CENSUS_COOLDOWN_MS, ARRAY_BUFFER_CENSUS_SUSTAIN_MS, ARRAY_BUFFER_CENSUS_THRESHOLD_MB, ARRAY_BUFFER_RELEASE_MIN_DROP_RATIO, AddonApiFactory, AddonDepsManager, AddonEngineManager, AddonHealthMonitor, AddonInstaller, AddonLoader, AddonManifest, AddonRouteRegistry, AlertCenterAddon, ApiKeyManager, AuthManager, CAP_ACTION_OVERFLOW_LABEL, CAP_ACTION_UNLABELLED, CA_COMMON_NAME, CA_VALIDITY_DAYS, CLUSTER_SECRET_MISMATCH_TYPE, CLUSTER_SECRET_REJECTED_EXIT_CODE, CORE_CAP_SERVICE_NAME, CapRouteError, CapRouteResolver, CapUsageRegistry, CapabilityHandle, CapabilityRegistry, CapabilityUnavailableError, ConfigManager, ConfigStore, ConsoleDestination, ConsoleLoggingAddon, CoreBlocksAddon, CustomActionRegistry, DECISIVE_HEAP_SPACES, DEFAULT_DATA_PATH, DEFAULT_LAN_HTTP_PORT, DEFAULT_LOG_LEVEL, DEVICE_SETTINGS_CONTRIBUTION_METHODS, DEVICE_STATUS_METHOD, DataPlaneRegistry, DeviceManagerAddon, DeviceRegistry, DeviceStore, EMPTY_CAP_ACTION_READING, EMPTY_SOCKET_DIRECTION, EMPTY_SOCKET_PLANE_BASELINE, EVENT_PLANE_TOP_N, EVENT_TOPIC_PREFIX, EngineManagerResolver, EventBus, FeatureManager, FilesystemStorageAddon, FilesystemStorageProvider, FrameDecoder, FsStorageBackend, HEALTH_MONITOR_GRACE_PERIOD_MS, HEALTH_MONITOR_RETRY_INTERVALS_MS, HEALTH_MONITOR_TICK_MS, HEAP_RECLAIM_MIN_INTERVAL_MS, HEAP_RECLAIM_STEADY_STATE_INTERVAL_MS, HEAP_RECLAIM_TRIGGER_MB, HEAP_SPACE_REPORT_MIN_MB, HEAP_WATCH_INTERVAL_MS, HEAP_WATCH_WARN_RATIO, HUB_CAP_FWD_ACTION, HUB_CAP_FWD_SERVICE, HUB_MAIN_HEAP_WATCH_LABEL, HUB_MAIN_RSS_BUDGET_MB, HUB_RSS_BUDGET_ENV, HubForwarderAddon, HubForwarderDestination, HubLogForwarder, HubNodeRegistry, INFRA_CAPABILITIES, IntegrationRegistry, JobJournal, LEAF_RENEWAL_WINDOW_DAYS, LifecycleJobEngine, LifecycleStateMachine, LivenessMonitorAddon, LocalAuthAddon, LocalChildClient, LocalChildRegistry, LogManager, LogRingBuffer, LoggingGate, LokiDestination, LokiLoggingAddon, MAX_CAP_ACTIONS_PER_PEER, MAX_LEAF_VALIDITY_DAYS, MESH_QUEUE_TOP_N, METHOD_ACCESS_MAP, ModelDownloadService, NATIVE_PROVIDER_SERVICE_INFIX, NATIVE_SCAN_DEPTH, NativeMetricsAddon, NativeMetricsProvider, NetworkQualityTracker, NotificationService, OUTBOUND_QUEUE_COOLDOWN_MS, OUTBOUND_QUEUE_SUSTAIN_MS, OUTBOUND_QUEUE_THRESHOLD_BYTES, PARENT_ROUTED_PROVIDER_ADDON_ID, PYTHON_VERSION, PipelineRunner, PipelineValidator, PythonEnvManager, QUARANTINE_DIRNAME, RESTART_MARKER_FILE, RSS_BUDGET_REANNOUNCE_MIN_MS, RSS_BUDGET_RELEASE_RATIO, RUNNER_HEAP_WATCH_INTERVAL_MS, RUNNER_RSS_BUDGET_ENV, RUNTIME_DEFAULTS, ReadinessRegistry, ReadinessTimeoutError, ReplEngine, RingBuffer, SERVER_AUTH_OID, SOCKET_PLANE_TOP_N, SOCKET_QUEUE_TOP_N, STALL_REPORT_MS, STALL_TICK_MS, ScopedLogger, ScopedTokenManager, SocketChannel, SqliteSettingsAddon, SqliteSettingsBackend, StagingArea, StorageLocationManager, StorageManager, StorageOrchestratorAddon, StorageOrchestratorService, SystemConfigAddon, SystemEventBus, TRADITIONAL_NATIVE_PACKAGES, ToastService, UDS_NO_ROUTE_PREFIX, UdsLocalTransportClient, UdsLocalTransportServer, UserManager, WinstonDestination, WinstonLoggingAddon, ZERO_LOOP_DELAY, __resetCapUsageRegistryForTests, __resetLoggingGateForTests, adaptBrokerToCluster, addonSettingsCapability, allFamiliesListenHost, applyLanHttp, attributeStall, bindPendingLanHttp, bootstrapSchema, brokerCallForCap, brokerTransportLink, buildBinaryPath, buildCapRouters, buildHeapSample, buildLinkChain, buildNativeCapProxy, buildNodeManifest, buildStorageLocationRegistry, buildUdsNativeCapProxy, builderMountedCapNames, callRegisterNodeWithRetry, callWithServiceDiscovery, canServeDataPlane, capActionLabel, capActionName, capActionSuffix, capBareAction, capServiceName, classifyAddonDir, classifyCapRoute, clearPendingRestart, closeLanHttp, clusterEventTopic, clusterSecretMatches, collectCertIdentity, collectModelFiles, contentTypeFor, copyDirRecursive, copyExtraFileDirs, createAddonContext, createAddonDataPlaneFacility, createAddonService, createArrayBufferCensusGate, createAuthenticatedFileServer, createBroker, createBrokerDeviceManagerApi, createCapActionCensus, createCoreCapService, createDeferredHeapWatchSink, createDoorSettingsView, createEventPlaneMeter, createEventPlaneReader, createFileDataPlaneHandler, createHubCapForwardService, createHubService, createInspectorArrayBufferCensus, createKernelHwAccel, createLocalTransport, createLoopDelayMeter, createMeshQueueReader, createOutboundQueueGate, createParentUnownedCallHandler, createProcessService, createReadinessService, createReadinessServiceForRegistry, createScopedProcessManager, createSocketDirectionCounters, createSocketPlaneMeter, createSocketPlaneReader, createStreamProbeBrokerService, createUdsAddonContext, createUdsEventBridge, createUdsEventBus, createUdsLogger, createUdsLoggerWithControl, createV8Reclaimer, deleteModelFromDisk, deriveAgentListenPort, describeProviderKindDrift, describeRss, detectWorkspacePackagesDir, diffCapActionCensus, diffEventPlane, diffSocketPlane, downloadBinary, downloadFile, downloadModel, emitDownForOwnedCaps, emitHeapDiagnosticReport, encodeFrame, ensureAddonNativePrebuilds, ensureBinary, ensureDir, ensureFfmpeg, ensureLibraryBuilt, ensureModel, ensureNativePrebuilds, ensurePython, ensureTlsCert, evaluateExistingCert, expandCapMethods, fetchJson, findInPath, formatArrayBufferCensus, formatEventPlane, formatHeapSpaces, formatLogLine, formatMeshQueue, formatOutboundQueueVerdict, formatSocketPlane, getBrokerEventBus, getCapUsageRegistry, getFfmpegDownloadUrl, getLoggingGate, getModelFilePath, getMoleculerEventStats, getOrInitReadinessRegistry, getOrInitReadinessRegistryForClient, getPidStats, getPlatformInfo, getPythonDownloadUrl, getRestartMarkerPath, getSinglePidStats, getWorkerDeviceRegistry, hasDotNode, hashClusterSecret, heapSpaceField, hubMainRssBudget, installManifestNativeDeps, installManifestPythonDeps, installManifestSystemDeps, installPackageFromNpm, installPythonPackages, installPythonRequirements, ipcParentLink, isAddonDeploySource, isArrayBufferCensusReport, isArrayOutputSchema, isClusterSecretMismatchError, isCollectionArrayMethod, isInfraCapability, isModelDownloaded, isSourceNewer, isolatedBuiltinPhase, loadTlsCert, localEndpointPath, localProviderLink, mountNativeCapService, nextRssBudgetState, parseCapAction, parseRangeHeader, parseRssBudgetMb, parseTokenizedUrl, partitionIsolatedBuiltinIds, proxyToUpstream, quarantineAddonResidue, readExtraSans, readHeapSpaces, readLanHttpState, readMoleculerFanoutMode, readPendingRestart, readSocketQueues, readTlsAccessStatus, readTlsMode, readinessKey, reclaimIntervalMs, recordSocketFrame, registerEventBusService, registerLanHttpHandler, reissueTlsLeaf, resolveFilePath, resolveHwAccel, resolveNpmInvocation, runHubAddonBoot, runNpm, sampleSocketDirection, scheduleSelfRestart, scopeKey, scopesAllowAddon, scopesAllowDeviceCap, selectAddonResidue, selectReportedSpaces, serializeTypedArrays, setHubConnected, setNodeEventInterest, shouldReclaim, socketDirectionBytes, socketDirectionMessages, startEventLoopStallMonitor, startHeapWatch, startRunnerHeapWatch, strandedMb, stripCamstackDeps, subscribePassthrough, udsChildLogToWorkerEntry, validateProviderRegistrations, validateUploadedTls, waitUntilReady, writeExtraSans, writePendingRestart, writeTlsMode };
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* gc-census — HOW OFTEN V8 collects, on the ordinary heartbeat.
|
|
3
|
+
*
|
|
4
|
+
* ## The question this exists to answer, and why four records could not
|
|
5
|
+
*
|
|
6
|
+
* A garbage collector's cost is a product of two independent things: the LIVE
|
|
7
|
+
* SET (how much there is to mark) and the RATE at which a cycle is triggered.
|
|
8
|
+
* The `[mem]` line has carried the live set since 2026-08-29 — `heapUsed`,
|
|
9
|
+
* `oldSpace`, `largeObjectSpace`, `external`, `arrayBuffers` — and has never
|
|
10
|
+
* carried the rate. So D443, D444, D446 and D456 each read a level, saw it flat
|
|
11
|
+
* or falling, and could not say whether the GC share they were looking at came
|
|
12
|
+
* from the size of the heap or from the frequency of the collection. D444 cut
|
|
13
|
+
* hub-main's live set from 2 491 MB to 714 MB — a factor of 3.5 — and the GC
|
|
14
|
+
* share did not move. That result was unreadable until the rate was measured.
|
|
15
|
+
*
|
|
16
|
+
* Measured on hub-main 2026-09-11 with the observer below, the answer was on
|
|
17
|
+
* sight: **1.39 major mark-compacts per second against a 602 MB live set whose
|
|
18
|
+
* old space grew 22 MB/s.** A major GC every 0.7 s cannot be explained by 22
|
|
19
|
+
* MB/s of heap growth under a 3 264 MB ceiling — V8 was being driven by
|
|
20
|
+
* EXTERNAL memory pressure (537 MB/s of ArrayBuffer allocation, D458), and each
|
|
21
|
+
* of those cycles then had to mark the 602 MB live set on four platform
|
|
22
|
+
* workers. That is 70 % of the process.
|
|
23
|
+
*
|
|
24
|
+
* ## Why counts and not a rate of bytes
|
|
25
|
+
*
|
|
26
|
+
* An allocation rate sampled from `process.memoryUsage()` on this heartbeat
|
|
27
|
+
* would be a lie with a number on it. The probe runs every 2 s; external memory
|
|
28
|
+
* on hub-main cycles many times inside 2 s, so a sum of positive deltas
|
|
29
|
+
* under-reports it by more than an order of magnitude (a 100 ms sampler already
|
|
30
|
+
* reported 234 MB/s where a 5 ms one would have said 537). The GC COUNT is
|
|
31
|
+
* exact at any cadence — V8 reports every cycle — and it is the half of the
|
|
32
|
+
* product the line was missing. Read against the `oldSpace=` field already on
|
|
33
|
+
* the line, the two together say which economy is paying:
|
|
34
|
+
*
|
|
35
|
+
* - many majors, little old-space growth between them ⇒ EXTERNAL pressure.
|
|
36
|
+
* The fix is an allocation site, and shrinking the live set buys nothing.
|
|
37
|
+
* - majors that track old-space growth ⇒ the heap is genuinely filling.
|
|
38
|
+
* The fix is retention.
|
|
39
|
+
*
|
|
40
|
+
* ## Cost
|
|
41
|
+
*
|
|
42
|
+
* One prologue/epilogue callback per GC, into a counter. On hub-main at its
|
|
43
|
+
* worst that is ~4 entries/s. The observer was run against the live hub three
|
|
44
|
+
* times for 90 s while this was written, with no measurable effect on the
|
|
45
|
+
* process; `Profiler.start`, by comparison, stalls it 867 ms (D456).
|
|
46
|
+
*
|
|
47
|
+
* Absence is never zero (D393): a runtime that will not give an observer
|
|
48
|
+
* reports NOTHING on the line, not a census of zero collections.
|
|
49
|
+
*/
|
|
50
|
+
/** One window of collections, as V8 counted them. */
|
|
51
|
+
export interface GcCensusWindow {
|
|
52
|
+
/** Full mark-compacts. The expensive kind: every one marks the live set. */
|
|
53
|
+
readonly majors: number;
|
|
54
|
+
/** Scavenges of the young generation. */
|
|
55
|
+
readonly minors: number;
|
|
56
|
+
/** Incremental marking steps on the main thread. */
|
|
57
|
+
readonly incrementals: number;
|
|
58
|
+
/** Total MAIN-THREAD pause across the window. Never the concurrent work. */
|
|
59
|
+
readonly pauseMs: number;
|
|
60
|
+
/** How long the window was, so a rate can be computed from the line. */
|
|
61
|
+
readonly windowMs: number;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* A census that accumulates until it is read, then starts a new window.
|
|
65
|
+
*
|
|
66
|
+
* Window semantics, not cumulative, for the reason D456 gives: a line printing
|
|
67
|
+
* a lifetime total says nothing about the minute it describes, and the reader
|
|
68
|
+
* has to diff two lines by hand to learn anything.
|
|
69
|
+
*/
|
|
70
|
+
export interface GcCensus {
|
|
71
|
+
/** The window since the previous read. `null` until the first full window. */
|
|
72
|
+
readonly read: (at: number) => GcCensusWindow | null;
|
|
73
|
+
readonly stop: () => void;
|
|
74
|
+
}
|
|
75
|
+
/** What the census counts. Node's `PerformanceEntry.detail.kind` values. */
|
|
76
|
+
export interface GcObservation {
|
|
77
|
+
readonly kind: number;
|
|
78
|
+
readonly durationMs: number;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* How the census is fed. Injectable so a spec can pose a sequence of
|
|
82
|
+
* collections without provoking real ones, which is not something a test can
|
|
83
|
+
* do deterministically.
|
|
84
|
+
*/
|
|
85
|
+
export type GcObserverInstall = (observe: (entry: GcObservation) => void) => (() => void) | undefined;
|
|
86
|
+
/**
|
|
87
|
+
* V8's kinds, as Node reports them on `detail.kind`.
|
|
88
|
+
*
|
|
89
|
+
* Read from `perf_hooks.constants` rather than written as literals: the values
|
|
90
|
+
* are a Node ABI, and a literal `4` in this file would keep compiling and stop
|
|
91
|
+
* meaning "major" the release it changed.
|
|
92
|
+
*/
|
|
93
|
+
export interface GcKinds {
|
|
94
|
+
readonly major: number;
|
|
95
|
+
readonly minor: number;
|
|
96
|
+
readonly incremental: number;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* The shortest window a rate may be quoted over.
|
|
100
|
+
*
|
|
101
|
+
* One second, and the number comes from the line this field lives on: the boot
|
|
102
|
+
* line is printed microseconds after the watch starts, and `maj0@0s` there
|
|
103
|
+
* would be a rate computed over no time at all — indistinguishable on sight
|
|
104
|
+
* from a process that is genuinely not collecting. Below the floor the census
|
|
105
|
+
* says NOTHING, which is the same discipline as an unobservable runtime
|
|
106
|
+
* (D393): a window too short to answer is not an answer of zero.
|
|
107
|
+
*/
|
|
108
|
+
export declare const GC_CENSUS_MIN_WINDOW_MS = 1000;
|
|
109
|
+
/**
|
|
110
|
+
* Build a census over an injected observer.
|
|
111
|
+
*
|
|
112
|
+
* Returns `undefined` when the observer cannot be installed — the caller then
|
|
113
|
+
* prints nothing, which is the honest reading. It must never degrade into a
|
|
114
|
+
* census that reports zero collections: a process whose GC is not being
|
|
115
|
+
* observed and a process that is not collecting look identical on the line, and
|
|
116
|
+
* they are the two answers furthest apart.
|
|
117
|
+
*/
|
|
118
|
+
export declare function createGcCensus(install: GcObserverInstall, kinds: GcKinds, startedAt: number): GcCensus | undefined;
|
|
119
|
+
/** The real Node observer and the real kind constants, wrapped so they can be replaced in a spec. */
|
|
120
|
+
export interface NodeGcObserver {
|
|
121
|
+
readonly install: GcObserverInstall;
|
|
122
|
+
readonly kinds: GcKinds;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* The observer this process actually gets.
|
|
126
|
+
*
|
|
127
|
+
* Everything that can fail is inside the try: a runtime without
|
|
128
|
+
* `perf_hooks`, without the `gc` entry type, or without the kind constants
|
|
129
|
+
* yields `undefined` from `install`, and {@link createGcCensus} then declines
|
|
130
|
+
* to exist rather than reporting zeros.
|
|
131
|
+
*/
|
|
132
|
+
export declare function nodeGcObserver(): NodeGcObserver;
|
|
133
|
+
/**
|
|
134
|
+
* The two fields, APPENDED LAST on the `[mem]` line.
|
|
135
|
+
*
|
|
136
|
+
* D446's rule: no existing field moves, so every Loki prefix written since
|
|
137
|
+
* 2026-08-29 still matches. `gc=` prints even when nothing was collected — a
|
|
138
|
+
* window with no collections is a reading, and it is the reading that says a
|
|
139
|
+
* process is idle rather than unobserved. `gcPauseMs=` is the MAIN-THREAD
|
|
140
|
+
* pause only; the concurrent marking that cost hub-main 70 % of its CPU is on
|
|
141
|
+
* the platform workers and no in-process counter sees it, which is why the
|
|
142
|
+
* field is named for the thread it describes (D456, part 4).
|
|
143
|
+
*/
|
|
144
|
+
export declare function formatGcCensus(window: GcCensusWindow | null | undefined): string;
|
|
@@ -3,6 +3,7 @@ import { SocketPlaneCounters, SocketPlaneReader } from './socket-plane-report.js
|
|
|
3
3
|
import { MeshPeerQueue, MeshQueueReader } from './moleculer/mesh-queue-report.js';
|
|
4
4
|
import { OutboundQueueGateOptions, OutboundQueueReading } from './outbound-queue-watch.js';
|
|
5
5
|
import { HeapSpaceReader } from './heap-spaces.js';
|
|
6
|
+
import { NodeGcObserver } from './gc-census.js';
|
|
6
7
|
import { ArrayBufferCensus, ArrayBufferCensusGateOptions } from './array-buffer-census.js';
|
|
7
8
|
/**
|
|
8
9
|
* What hub-main calls itself in a `[mem]` line.
|
|
@@ -633,6 +634,13 @@ export interface HeapWatchProbes {
|
|
|
633
634
|
* `array-buffer-census.ts` for the gate, the cost and what it is NOT.
|
|
634
635
|
*/
|
|
635
636
|
readonly arrayBufferCensus?: ArrayBufferCensusProbe;
|
|
637
|
+
/**
|
|
638
|
+
* How the GC census observes collections. Defaults to the real Node
|
|
639
|
+
* observer, for EVERY process — the rate is half of what a GC costs and the
|
|
640
|
+
* line has never carried it (see `gc-census.ts`). A spec passes its own so a
|
|
641
|
+
* sequence of collections can be posed; nothing in production passes one.
|
|
642
|
+
*/
|
|
643
|
+
readonly gcObserver?: NodeGcObserver;
|
|
636
644
|
}
|
|
637
645
|
/** How the census is wired: the census itself plus the gate's thresholds. */
|
|
638
646
|
export interface ArrayBufferCensusProbe extends ArrayBufferCensusGateOptions {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { CapActionReading, CapActionWindow } from './transport/cap-action-census.js';
|
|
1
2
|
import { SocketDirectionSample, SocketTrafficSample } from './transport/socket-traffic.js';
|
|
2
3
|
/** One peer's cumulative traffic, as the channel keeps it, plus its outbound
|
|
3
4
|
* queue depth at the instant of the read. */
|
|
@@ -39,6 +40,15 @@ export interface SocketPlaneRegistry {
|
|
|
39
40
|
* the field rather than print a zero that reads as "nothing was forwarded".
|
|
40
41
|
*/
|
|
41
42
|
readonly readForwardCensus?: () => SocketForwardCensus;
|
|
43
|
+
/**
|
|
44
|
+
* The per-ACTION byte census, when the registry keeps one (D456).
|
|
45
|
+
*
|
|
46
|
+
* OPTIONAL on the same terms as {@link readForwardCensus}: a registry whose
|
|
47
|
+
* channels carry no byte counters has nothing to attribute, and the line
|
|
48
|
+
* must omit the fields rather than print a `0/0` that reads as "the plane
|
|
49
|
+
* moved nothing" instead of "nobody measured".
|
|
50
|
+
*/
|
|
51
|
+
readonly readActionCensus?: () => CapActionReading;
|
|
42
52
|
}
|
|
43
53
|
/** One cumulative reading of every measured peer. */
|
|
44
54
|
export interface SocketPlaneCounters {
|
|
@@ -47,6 +57,8 @@ export interface SocketPlaneCounters {
|
|
|
47
57
|
readonly peersConnected: number;
|
|
48
58
|
/** Cumulative forward census, absent when the registry keeps none. */
|
|
49
59
|
readonly forward?: SocketForwardCensus;
|
|
60
|
+
/** Cumulative per-action census, absent when the registry keeps none. */
|
|
61
|
+
readonly actions?: CapActionReading;
|
|
50
62
|
}
|
|
51
63
|
/** `undefined` = this process has no local socket plane to report (every forked
|
|
52
64
|
* runner, and hub-main before the registry exists). */
|
|
@@ -127,16 +139,41 @@ export interface SocketPlaneWindow {
|
|
|
127
139
|
readonly queued: SocketQueueReading;
|
|
128
140
|
/** Forwards in this window, absent when the registry keeps no census. */
|
|
129
141
|
readonly forward?: SocketForwardCensus;
|
|
142
|
+
/**
|
|
143
|
+
* The per-action census over this window, absent when none is kept.
|
|
144
|
+
*
|
|
145
|
+
* This is the field that survives raw-forward. Once 85.7 % of sibling calls
|
|
146
|
+
* cross hub-main without being read (D448, measured on 1.2.270), the bytes
|
|
147
|
+
* a peer moves stop being the proxy for what hub-main PAYS — a forwarded
|
|
148
|
+
* body costs a memcpy, a decoded one costs msgpack plus the garbage. So the
|
|
149
|
+
* entry carries the raw/decoded split BESIDE the bytes, per method, and the
|
|
150
|
+
* two questions are read off one row.
|
|
151
|
+
*/
|
|
152
|
+
readonly actions?: CapActionWindow;
|
|
130
153
|
}
|
|
131
154
|
/** How many queue-holding peers get named. Three: a queue is an exception,
|
|
132
155
|
* and the line already carries five names for traffic. */
|
|
133
156
|
export declare const SOCKET_QUEUE_TOP_N = 3;
|
|
157
|
+
/**
|
|
158
|
+
* How many (peer, action) pairs get named.
|
|
159
|
+
*
|
|
160
|
+
* Five, matching {@link SOCKET_PLANE_TOP_N}, and for the same measured reason:
|
|
161
|
+
* the distribution is not flat. Queried on this hub 2026-09-11, the heaviest
|
|
162
|
+
* peer's top THREE caps were 2 077 of its 2 141 calls/min — five names the
|
|
163
|
+
* dominant action, its challenger, and enough of the tail to see the shape
|
|
164
|
+
* change. The map behind it keeps every action (see `cap-action-census.ts` on
|
|
165
|
+
* why the bound that matters is the line's width, not the map's size); this
|
|
166
|
+
* constant governs only what is printed.
|
|
167
|
+
*/
|
|
168
|
+
export declare const SOCKET_ACTION_TOP_N = 5;
|
|
134
169
|
/** The queue reading over the current counters — a level, so no baseline. */
|
|
135
170
|
export declare function readSocketQueues(current: SocketPlaneCounters): SocketQueueReading;
|
|
136
171
|
/** Previous cumulative reading, kept between lines. */
|
|
137
172
|
export interface SocketPlaneBaseline {
|
|
138
173
|
readonly peers: ReadonlyMap<string, SocketPeerSample>;
|
|
139
174
|
readonly forward?: SocketForwardCensus;
|
|
175
|
+
/** Previous per-action reading; absent = nothing has been read yet. */
|
|
176
|
+
readonly actions?: CapActionReading;
|
|
140
177
|
}
|
|
141
178
|
/** A process that has never read the plane. */
|
|
142
179
|
export declare const EMPTY_SOCKET_PLANE_BASELINE: SocketPlaneBaseline;
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* cap-action-census — which cap METHOD moves the bytes, and how much of each
|
|
3
|
+
* one this parent forwarded without ever reading it.
|
|
4
|
+
*
|
|
5
|
+
* ## Why `socket-traffic.ts` keeps no method, and why this is a separate file
|
|
6
|
+
*
|
|
7
|
+
* Read `socket-traffic.ts` before changing anything here. It does not omit the
|
|
8
|
+
* method by oversight; three separate properties of that file forbid it, and
|
|
9
|
+
* this module exists because each can be answered somewhere else rather than
|
|
10
|
+
* relaxed:
|
|
11
|
+
*
|
|
12
|
+
* 1. **The channel does not know one.** `SocketChannel` sees a {@link
|
|
13
|
+
* import('./local-transport.js').Frame} — `{ k, id, body }` — and `body` is
|
|
14
|
+
* `unknown` by contract. The cap envelope lives one layer up, in
|
|
15
|
+
* `child-cap-protocol.ts`. A counter inside the channel that reached into
|
|
16
|
+
* `body.capName` would make the transport depend on the protocol it
|
|
17
|
+
* carries. So the LABEL is supplied from above ({@link capActionLabel}) and
|
|
18
|
+
* only the BYTES come from the wire.
|
|
19
|
+
*
|
|
20
|
+
* 2. **A `res` frame carries no method at all** — only its correlation `id`.
|
|
21
|
+
* And the responses are the whole question: measured 2026-09-11, hub-main
|
|
22
|
+
* wrote 144–262 MB/min to `hub/pipeline-analytics` on 1 966–2 411 responses
|
|
23
|
+
* (a 73–108 kB mean) against 2 kB of requests. Charging those bytes to a
|
|
24
|
+
* method is therefore not a counter at all, it is a CORRELATION: the label
|
|
25
|
+
* is taken off the `req`, held against its id, and settled when the `res`
|
|
26
|
+
* for that id is written. `socket-traffic.ts` is a two-addition hot path
|
|
27
|
+
* with no state per message; this is state per in-flight request, and the
|
|
28
|
+
* two do not belong in one file.
|
|
29
|
+
*
|
|
30
|
+
* 3. **Cardinality.** `recordSocketFrame` costs 2.37–2.41 ns and allocates
|
|
31
|
+
* nothing, on a path that runs ~44 000 times a second. Its docblock's rule
|
|
32
|
+
* — "an instrument that changes what it measures is not an instrument" — is
|
|
33
|
+
* the binding constraint, and a naive per-method map breaks it twice: a Map
|
|
34
|
+
* lookup and a counter object per method NAME, where the names arrive off
|
|
35
|
+
* the wire and are therefore unbounded in principle.
|
|
36
|
+
*
|
|
37
|
+
* ## What was chosen for the cardinality, and why not a sample
|
|
38
|
+
*
|
|
39
|
+
* **Full per-method counters in memory, bounded per peer; top-N only at REPORT
|
|
40
|
+
* time.** The constraint that is real is the LINE's width (D446: Loki reads
|
|
41
|
+
* these prefixes), not the map's size — and those are different limits:
|
|
42
|
+
*
|
|
43
|
+
* - *Measured shape.* The cap-usage graph already keeps `(caller, provider,
|
|
44
|
+
* cap, method)` and, queried on this hub on 2026-09-11, holds **53 rows for
|
|
45
|
+
* the whole cluster** — 14 of them for `pipeline-analytics`, whose top three
|
|
46
|
+
* caps are 2 077 of its 2 141 calls/min. A peer uses a handful of methods,
|
|
47
|
+
* not hundreds. ~39 peers × a few dozen labels is a few hundred counter
|
|
48
|
+
* objects, each allocated ONCE and then only incremented. That is not an
|
|
49
|
+
* explosion; it is smaller than the `childEventStats` map next to it.
|
|
50
|
+
* - *The unbounded case is still refused*, because "measured today" is not a
|
|
51
|
+
* guarantee: {@link MAX_CAP_ACTIONS_PER_PEER} caps the distinct labels per
|
|
52
|
+
* peer and everything past it is charged to ONE
|
|
53
|
+
* {@link CAP_ACTION_OVERFLOW_LABEL} bucket. The bytes are never dropped —
|
|
54
|
+
* they stop being *named*, which is a different and visible failure.
|
|
55
|
+
* - *A sampled window was rejected.* The flow this exists to name is few,
|
|
56
|
+
* enormous responses: 1 966 responses carrying 144 MB. A 1-in-N sample of a
|
|
57
|
+
* distribution whose top item fires ~30 times a minute answers "probably"
|
|
58
|
+
* to a question that has an exact answer for the price of an integer add.
|
|
59
|
+
* And a sample that misses a method would report it as zero bytes, which is
|
|
60
|
+
* exactly the `null`-vs-`0` confusion D393 exists to forbid.
|
|
61
|
+
* - *A byte THRESHOLD was rejected for the same reason in reverse*: a
|
|
62
|
+
* threshold decides what to keep before it knows the window's shape, so the
|
|
63
|
+
* method that only matters during an episode is the one it discards. Rank
|
|
64
|
+
* at report time, when the totals are known.
|
|
65
|
+
*
|
|
66
|
+
* ## What a reader may conclude, and what it may not
|
|
67
|
+
*
|
|
68
|
+
* {@link CapActionWindow.labelledBytes} against `totalBytes` is the census's
|
|
69
|
+
* own coverage, and it is on the line. Bytes this parent moved that carry no
|
|
70
|
+
* cap envelope (`register`, `addon-call`, log and event frames) are charged to
|
|
71
|
+
* {@link CAP_ACTION_UNLABELLED} rather than omitted: an instrument that
|
|
72
|
+
* silently drops what it cannot classify reports a clean attribution of a
|
|
73
|
+
* fraction it never names. A window whose `labelledBytes` is a small part of
|
|
74
|
+
* `totalBytes` has NOT attributed the plane, and says so.
|
|
75
|
+
*
|
|
76
|
+
* ## Mutation, as in `socket-traffic.ts`
|
|
77
|
+
*
|
|
78
|
+
* Same deliberate exception, for the same measured reason: the counters are
|
|
79
|
+
* plain mutable numbers written only by {@link CapActionCensus.record} and
|
|
80
|
+
* friends, and read only through {@link CapActionCensus.read}, which COPIES.
|
|
81
|
+
* The copy is not a nicety — the reporting layer subtracts the previous
|
|
82
|
+
* reading, and a `read()` that handed back the live maps would advance the
|
|
83
|
+
* baseline together with the counters and report every window as empty.
|
|
84
|
+
*/
|
|
85
|
+
/**
|
|
86
|
+
* The channel's half of the census — see `socket-channel.ts` for the seam.
|
|
87
|
+
*
|
|
88
|
+
* The channel owns the BYTES and the request↔response correlation and NOTHING
|
|
89
|
+
* else: it sees `{ k, id, body }` with `body: unknown`, and a `res` frame
|
|
90
|
+
* carries no method at all. So the layer that understands the protocol supplies
|
|
91
|
+
* {@link CapActionChannelObserver.label}, and the channel calls it once per
|
|
92
|
+
* `req` frame, holds the answer against the frame's id, and settles it with
|
|
93
|
+
* {@link CapActionChannelObserver.record} when the matching `res` is written or
|
|
94
|
+
* read. A `null` label is still recorded — those bytes crossed, and a census
|
|
95
|
+
* that drops what it cannot name reports a clean attribution of a fraction it
|
|
96
|
+
* never mentions.
|
|
97
|
+
*
|
|
98
|
+
* Declared HERE rather than in the channel so `local-transport.ts` can name it
|
|
99
|
+
* on {@link import('./local-transport.js').LocalChannel} without importing the
|
|
100
|
+
* implementation that satisfies it.
|
|
101
|
+
*/
|
|
102
|
+
export interface CapActionChannelObserver {
|
|
103
|
+
/** `<cap>.<method>`, or `null` for a frame that carries no cap envelope. */
|
|
104
|
+
label(body: unknown): string | null;
|
|
105
|
+
/** One completed request/response pair, its on-the-wire bytes both ways. */
|
|
106
|
+
record(label: string | null, reqBytes: number, resBytes: number): void;
|
|
107
|
+
}
|
|
108
|
+
/** One action's cumulative cost on one peer's channel. Mutable by design. */
|
|
109
|
+
export interface CapActionCounters {
|
|
110
|
+
/** Completed request/response pairs. */
|
|
111
|
+
calls: number;
|
|
112
|
+
/** On-the-wire bytes of the requests, prefix and payload included. */
|
|
113
|
+
reqBytes: number;
|
|
114
|
+
/** On-the-wire bytes of the answers. */
|
|
115
|
+
resBytes: number;
|
|
116
|
+
/** Of `calls`, how many this parent forwarded without reading (D448). */
|
|
117
|
+
raw: number;
|
|
118
|
+
/** Of `calls`, how many it materialised the args of. */
|
|
119
|
+
decoded: number;
|
|
120
|
+
}
|
|
121
|
+
/** An immutable reading of one action. */
|
|
122
|
+
export interface CapActionSample {
|
|
123
|
+
readonly calls: number;
|
|
124
|
+
readonly reqBytes: number;
|
|
125
|
+
readonly resBytes: number;
|
|
126
|
+
readonly raw: number;
|
|
127
|
+
readonly decoded: number;
|
|
128
|
+
}
|
|
129
|
+
/** One complete reading: peer → action → counters. */
|
|
130
|
+
export type CapActionReading = ReadonlyMap<string, ReadonlyMap<string, CapActionSample>>;
|
|
131
|
+
/** A process that has never read the census. */
|
|
132
|
+
export declare const EMPTY_CAP_ACTION_READING: CapActionReading;
|
|
133
|
+
/**
|
|
134
|
+
* Bytes that crossed on a frame carrying no cap envelope.
|
|
135
|
+
*
|
|
136
|
+
* Named rather than omitted so the census's coverage is readable off its own
|
|
137
|
+
* output: `register`, `addon-call`, log frames and the event fan-out all land
|
|
138
|
+
* here. A census that reported only what it could name would look like a
|
|
139
|
+
* complete attribution of whatever share it happened to cover.
|
|
140
|
+
*/
|
|
141
|
+
export declare const CAP_ACTION_UNLABELLED = "(unlabelled)";
|
|
142
|
+
/** Bytes of actions past {@link MAX_CAP_ACTIONS_PER_PEER} on one peer. */
|
|
143
|
+
export declare const CAP_ACTION_OVERFLOW_LABEL = "(overflow)";
|
|
144
|
+
/**
|
|
145
|
+
* Distinct named actions kept per peer before the overflow bucket takes over.
|
|
146
|
+
*
|
|
147
|
+
* Sixty-four against a measured worst case of 14 (`pipeline-analytics`, the
|
|
148
|
+
* heaviest peer on this hub, 2026-09-11) — four times the observed shape, so a
|
|
149
|
+
* peer has to change character before it overflows, and a bound that is never
|
|
150
|
+
* reached in practice still forbids the unbounded growth a wire-supplied key
|
|
151
|
+
* makes possible in principle.
|
|
152
|
+
*/
|
|
153
|
+
export declare const MAX_CAP_ACTIONS_PER_PEER = 64;
|
|
154
|
+
/**
|
|
155
|
+
* `<cap>.<method>` for a cap envelope, `null` for anything else.
|
|
156
|
+
*
|
|
157
|
+
* Both directions are labelled by the same function: a child's `cap-call-out`
|
|
158
|
+
* and the parent's `cap-call` carry `capName` + `method` in the same two keys,
|
|
159
|
+
* so one predicate covers the whole plane. Anything else — a `register`, an
|
|
160
|
+
* `addon-call`, a log or an event — is deliberately unlabelled; see
|
|
161
|
+
* {@link CAP_ACTION_UNLABELLED} for where its bytes go.
|
|
162
|
+
*
|
|
163
|
+
* Cost: two property reads, two `typeof`s and one concatenation of two short
|
|
164
|
+
* strings, called once per `req` frame (not per frame). Against the
|
|
165
|
+
* `encodeFrame` it sits beside — 1 948–1 975 ns on a 0.33 kB body — it is
|
|
166
|
+
* noise, and unlike `recordSocketFrame` it is not on the `evt` path at all.
|
|
167
|
+
*/
|
|
168
|
+
export declare function capActionLabel(body: unknown): string | null;
|
|
169
|
+
/** Which half of D448's census one call fell on. */
|
|
170
|
+
export type CapActionForwardKind = 'raw' | 'decoded';
|
|
171
|
+
/** The census as its writers see it. */
|
|
172
|
+
export interface CapActionCensus {
|
|
173
|
+
/** One completed request/response pair on `peerId`, charged to `action`. */
|
|
174
|
+
record(peerId: string, action: string, reqBytes: number, resBytes: number): void;
|
|
175
|
+
/** How `action`'s most recent call was routed — see {@link CapActionForwardKind}. */
|
|
176
|
+
recordForward(peerId: string, action: string, kind: CapActionForwardKind): void;
|
|
177
|
+
/** Bytes on a frame that carried no cap envelope. */
|
|
178
|
+
recordUnlabelled(peerId: string, bytes: number): void;
|
|
179
|
+
/** Drop a peer's counters when its channel closes for good. */
|
|
180
|
+
forget(peerId: string): void;
|
|
181
|
+
/** A COPY of the counters — see the module docblock on why it must be one. */
|
|
182
|
+
read(): CapActionReading;
|
|
183
|
+
}
|
|
184
|
+
export declare function createCapActionCensus(): CapActionCensus;
|
|
185
|
+
/** One (peer, action) pair over the window since the previous reading. */
|
|
186
|
+
export interface CapActionDelta {
|
|
187
|
+
readonly peerId: string;
|
|
188
|
+
readonly action: string;
|
|
189
|
+
readonly calls: number;
|
|
190
|
+
readonly reqBytes: number;
|
|
191
|
+
readonly resBytes: number;
|
|
192
|
+
readonly raw: number;
|
|
193
|
+
readonly decoded: number;
|
|
194
|
+
}
|
|
195
|
+
/** The census over one heartbeat window. */
|
|
196
|
+
export interface CapActionWindow {
|
|
197
|
+
/**
|
|
198
|
+
* Heaviest first by `reqBytes + resBytes`, at most the requested N.
|
|
199
|
+
*
|
|
200
|
+
* By BYTES and never by calls, for the reason D454 records: the flow this
|
|
201
|
+
* exists to name is few, enormous responses, and a ranking by count cannot
|
|
202
|
+
* see it by construction.
|
|
203
|
+
*/
|
|
204
|
+
readonly top: readonly CapActionDelta[];
|
|
205
|
+
/** Bytes the census could put a cap method on, this window. */
|
|
206
|
+
readonly labelledBytes: number;
|
|
207
|
+
/** Every byte it saw, named or not. `labelled/total` is its own coverage. */
|
|
208
|
+
readonly totalBytes: number;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Subtract the previous reading from the current one.
|
|
212
|
+
*
|
|
213
|
+
* A peer whose runner RESPAWNED reconnects under the same id with counters
|
|
214
|
+
* that went backwards. Clamped at 0, exactly as `diffSocketPlane` clamps for
|
|
215
|
+
* the same reason: its traffic in that window is genuinely unknown, and a
|
|
216
|
+
* negative number on a rate reads as a broken meter.
|
|
217
|
+
*/
|
|
218
|
+
export declare function diffCapActionCensus(before: CapActionReading, current: CapActionReading, topN: number): CapActionWindow;
|