@naylence/agent-sdk 0.3.12 → 0.3.13
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 +30 -0
- package/dist/browser/index.js +1167 -439
- package/dist/browser/index.js.map +1 -1
- package/dist/cjs/naylence/agent/agent-proxy.js.map +1 -1
- package/dist/cjs/naylence/agent/agent.js.map +1 -1
- package/dist/cjs/naylence/agent/background-task-agent.js.map +1 -1
- package/dist/cjs/naylence/agent/base-agent.js.map +1 -1
- package/dist/cjs/public-api.d.ts +7 -0
- package/dist/cjs/public-api.js +26 -0
- package/dist/cjs/public-api.js.map +1 -0
- package/dist/cjs/version.d.ts +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/esm/naylence/agent/agent-proxy.d.ts +148 -0
- package/dist/esm/naylence/agent/agent-proxy.js +130 -0
- package/dist/esm/naylence/agent/agent-proxy.js.map +1 -1
- package/dist/esm/naylence/agent/agent.d.ts +194 -2
- package/dist/esm/naylence/agent/agent.js +123 -0
- package/dist/esm/naylence/agent/agent.js.map +1 -1
- package/dist/esm/naylence/agent/background-task-agent.d.ts +164 -0
- package/dist/esm/naylence/agent/background-task-agent.js +150 -0
- package/dist/esm/naylence/agent/background-task-agent.js.map +1 -1
- package/dist/esm/naylence/agent/base-agent.d.ts +171 -0
- package/dist/esm/naylence/agent/base-agent.js +170 -1
- package/dist/esm/naylence/agent/base-agent.js.map +1 -1
- package/dist/esm/public-api.d.ts +15 -0
- package/dist/esm/public-api.js +16 -0
- package/dist/esm/public-api.js.map +1 -0
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +2 -2
- package/dist/types/naylence/agent/agent-proxy.d.ts +148 -0
- package/dist/types/naylence/agent/agent-proxy.d.ts.map +1 -1
- package/dist/types/naylence/agent/agent.d.ts +194 -2
- package/dist/types/naylence/agent/agent.d.ts.map +1 -1
- package/dist/types/naylence/agent/background-task-agent.d.ts +164 -0
- package/dist/types/naylence/agent/background-task-agent.d.ts.map +1 -1
- package/dist/types/naylence/agent/base-agent.d.ts +171 -0
- package/dist/types/naylence/agent/base-agent.d.ts.map +1 -1
- package/dist/types/public-api.d.ts +16 -0
- package/dist/types/public-api.d.ts.map +1 -0
- package/dist/types/version.d.ts +1 -1
- package/package.json +7 -2
package/dist/browser/index.js
CHANGED
|
@@ -15277,6 +15277,7 @@
|
|
|
15277
15277
|
"./node/admission/direct-admission-client-factory.js",
|
|
15278
15278
|
"./node/admission/noop-admission-client-factory.js",
|
|
15279
15279
|
"./node/admission/welcome-service-client-factory.js",
|
|
15280
|
+
"./node/default-connection-retry-policy-factory.js",
|
|
15280
15281
|
"./node/default-node-identity-policy-factory.js",
|
|
15281
15282
|
"./node/node-factory.js",
|
|
15282
15283
|
"./node/node-identity-policy-profile-factory.js",
|
|
@@ -15355,6 +15356,7 @@
|
|
|
15355
15356
|
"./node/admission/direct-admission-client-factory.js": () => Promise.resolve().then(function () { return directAdmissionClientFactory; }),
|
|
15356
15357
|
"./node/admission/noop-admission-client-factory.js": () => Promise.resolve().then(function () { return noopAdmissionClientFactory; }),
|
|
15357
15358
|
"./node/admission/welcome-service-client-factory.js": () => Promise.resolve().then(function () { return welcomeServiceClientFactory; }),
|
|
15359
|
+
"./node/default-connection-retry-policy-factory.js": () => Promise.resolve().then(function () { return defaultConnectionRetryPolicyFactory; }),
|
|
15358
15360
|
"./node/default-node-identity-policy-factory.js": () => Promise.resolve().then(function () { return defaultNodeIdentityPolicyFactory; }),
|
|
15359
15361
|
"./node/node-factory.js": () => Promise.resolve().then(function () { return nodeFactory; }),
|
|
15360
15362
|
"./node/node-identity-policy-profile-factory.js": () => Promise.resolve().then(function () { return nodeIdentityPolicyProfileFactory; }),
|
|
@@ -15665,12 +15667,12 @@
|
|
|
15665
15667
|
}
|
|
15666
15668
|
|
|
15667
15669
|
// This file is auto-generated during build - do not edit manually
|
|
15668
|
-
// Generated from package.json version: 0.3.
|
|
15670
|
+
// Generated from package.json version: 0.3.16
|
|
15669
15671
|
/**
|
|
15670
15672
|
* The package version, injected at build time.
|
|
15671
15673
|
* @internal
|
|
15672
15674
|
*/
|
|
15673
|
-
const VERSION$2 = '0.3.
|
|
15675
|
+
const VERSION$2 = '0.3.16';
|
|
15674
15676
|
|
|
15675
15677
|
let initialized$1 = false;
|
|
15676
15678
|
const runtimePlugin = {
|
|
@@ -16401,7 +16403,7 @@
|
|
|
16401
16403
|
* Provides functionality similar to Python's asyncio TaskSpawner with proper
|
|
16402
16404
|
* error handling, cancellation, and graceful shutdown capabilities.
|
|
16403
16405
|
*/
|
|
16404
|
-
const logger$
|
|
16406
|
+
const logger$1h = getLogger('naylence.fame.util.task_spawner');
|
|
16405
16407
|
function firstDefined(source, keys) {
|
|
16406
16408
|
for (const key of keys) {
|
|
16407
16409
|
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
@@ -16562,7 +16564,7 @@
|
|
|
16562
16564
|
const taskId = `task-${++this._taskCounter}`;
|
|
16563
16565
|
const taskName = normalizedOptions.name || `unnamed-${taskId}`;
|
|
16564
16566
|
const timeout = normalizedOptions.timeout ?? this._config.defaultTimeout;
|
|
16565
|
-
logger$
|
|
16567
|
+
logger$1h.debug('starting_background_task', {
|
|
16566
16568
|
task_name: taskName,
|
|
16567
16569
|
task_id: taskId,
|
|
16568
16570
|
});
|
|
@@ -16579,7 +16581,7 @@
|
|
|
16579
16581
|
task.promise
|
|
16580
16582
|
.then(() => {
|
|
16581
16583
|
if (!this._suppressCompletionLogging) {
|
|
16582
|
-
logger$
|
|
16584
|
+
logger$1h.debug('task_completed_successfully', {
|
|
16583
16585
|
task_name: taskName,
|
|
16584
16586
|
task_id: taskId,
|
|
16585
16587
|
duration_ms: Date.now() - task.startTime,
|
|
@@ -16633,7 +16635,7 @@
|
|
|
16633
16635
|
error.name === 'AbortError' ||
|
|
16634
16636
|
error.message === 'Task cancelled' ||
|
|
16635
16637
|
error.message === 'Aborted') {
|
|
16636
|
-
logger$
|
|
16638
|
+
logger$1h.debug('task_cancelled', {
|
|
16637
16639
|
task_name: taskName,
|
|
16638
16640
|
note: 'Task cancelled as requested',
|
|
16639
16641
|
});
|
|
@@ -16641,7 +16643,7 @@
|
|
|
16641
16643
|
}
|
|
16642
16644
|
// Handle timeout
|
|
16643
16645
|
if (error instanceof TaskTimeoutError) {
|
|
16644
|
-
logger$
|
|
16646
|
+
logger$1h.warning('task_timed_out', {
|
|
16645
16647
|
task_name: taskName,
|
|
16646
16648
|
error: error.message,
|
|
16647
16649
|
});
|
|
@@ -16653,7 +16655,7 @@
|
|
|
16653
16655
|
// Handle known WebSocket shutdown race condition (similar to Python version)
|
|
16654
16656
|
if (error.message.includes("await wasn't used with future") ||
|
|
16655
16657
|
error.message.includes('WebSocket closed during receive')) {
|
|
16656
|
-
logger$
|
|
16658
|
+
logger$1h.debug('task_shutdown_race_condition_handled', {
|
|
16657
16659
|
task_name: taskName,
|
|
16658
16660
|
note: 'Normal WebSocket close timing during shutdown - not an error',
|
|
16659
16661
|
});
|
|
@@ -16663,7 +16665,7 @@
|
|
|
16663
16665
|
if (error.name === 'FameTransportClose' ||
|
|
16664
16666
|
error.message.includes('normal closure') ||
|
|
16665
16667
|
error.message.includes('Connection closed')) {
|
|
16666
|
-
logger$
|
|
16668
|
+
logger$1h.debug('task_shutdown_completed_normally', {
|
|
16667
16669
|
task_name: taskName,
|
|
16668
16670
|
note: 'Task closed normally during shutdown',
|
|
16669
16671
|
});
|
|
@@ -16671,7 +16673,7 @@
|
|
|
16671
16673
|
}
|
|
16672
16674
|
// Handle PKCE redirect "errors" as info
|
|
16673
16675
|
if (error.name === 'OAuth2PkceRedirectInitiatedError') {
|
|
16674
|
-
logger$
|
|
16676
|
+
logger$1h.debug('background_task_redirecting', {
|
|
16675
16677
|
task_name: taskName,
|
|
16676
16678
|
note: 'Task interrupted for PKCE redirect',
|
|
16677
16679
|
});
|
|
@@ -16684,14 +16686,14 @@
|
|
|
16684
16686
|
// Log retriable errors as warnings (they'll be retried by upstream logic)
|
|
16685
16687
|
// Log non-retriable errors as errors (fatal failures)
|
|
16686
16688
|
if (isRetriableError) {
|
|
16687
|
-
logger$
|
|
16689
|
+
logger$1h.warning('background_task_failed', {
|
|
16688
16690
|
task_name: taskName,
|
|
16689
16691
|
error: error.message,
|
|
16690
16692
|
retriable: true,
|
|
16691
16693
|
});
|
|
16692
16694
|
}
|
|
16693
16695
|
else {
|
|
16694
|
-
logger$
|
|
16696
|
+
logger$1h.error('background_task_failed', {
|
|
16695
16697
|
task_name: taskName,
|
|
16696
16698
|
error: error.message,
|
|
16697
16699
|
stack: error.stack,
|
|
@@ -16710,11 +16712,11 @@
|
|
|
16710
16712
|
async shutdownTasks(options = {}) {
|
|
16711
16713
|
const { gracePeriod, cancelHanging, joinTimeout } = normalizeShutdownOptions(options);
|
|
16712
16714
|
if (this._tasks.size === 0) {
|
|
16713
|
-
logger$
|
|
16715
|
+
logger$1h.debug('shutdown_tasks_no_tasks_to_shutdown');
|
|
16714
16716
|
return;
|
|
16715
16717
|
}
|
|
16716
16718
|
this._suppressCompletionLogging = true;
|
|
16717
|
-
logger$
|
|
16719
|
+
logger$1h.debug('shutting_down_tasks', {
|
|
16718
16720
|
task_count: this._tasks.size,
|
|
16719
16721
|
task_names: Array.from(this._tasks.values()).map((t) => t.name),
|
|
16720
16722
|
grace_period_ms: gracePeriod,
|
|
@@ -16729,7 +16731,7 @@
|
|
|
16729
16731
|
if (cancelHanging) {
|
|
16730
16732
|
const stillRunning = tasks.filter((task) => task.getState() === TaskState.RUNNING && !completed.has(task));
|
|
16731
16733
|
if (stillRunning.length > 0) {
|
|
16732
|
-
logger$
|
|
16734
|
+
logger$1h.debug('tasks_did_not_complete_within_grace_period', {
|
|
16733
16735
|
hanging_count: stillRunning.length,
|
|
16734
16736
|
});
|
|
16735
16737
|
// Wait for them to finish with individual timeouts
|
|
@@ -16739,7 +16741,7 @@
|
|
|
16739
16741
|
}
|
|
16740
16742
|
catch (error) {
|
|
16741
16743
|
if (error instanceof TaskTimeoutError) {
|
|
16742
|
-
logger$
|
|
16744
|
+
logger$1h.warning('task_did_not_shutdown', {
|
|
16743
16745
|
task_name: task.name || task.id,
|
|
16744
16746
|
join_timeout_ms: joinTimeout,
|
|
16745
16747
|
});
|
|
@@ -16750,7 +16752,7 @@
|
|
|
16750
16752
|
}
|
|
16751
16753
|
else if (!(error instanceof TaskCancelledError)) {
|
|
16752
16754
|
/* istanbul ignore next - unreachable defensive branch */
|
|
16753
|
-
logger$
|
|
16755
|
+
logger$1h.error('task_raised_during_cancellation', {
|
|
16754
16756
|
task_name: task.name || task.id,
|
|
16755
16757
|
error: error instanceof Error ? error.message : String(error),
|
|
16756
16758
|
});
|
|
@@ -17368,7 +17370,7 @@
|
|
|
17368
17370
|
* condition/promise and ensure at most one notifier coroutine exists for a
|
|
17369
17371
|
* flow at any time.
|
|
17370
17372
|
*/
|
|
17371
|
-
const logger$
|
|
17373
|
+
const logger$1g = getLogger('naylence.fame.flow.flow_controller');
|
|
17372
17374
|
/**
|
|
17373
17375
|
* Simple condition variable implementation for TypeScript/Node.js
|
|
17374
17376
|
* Similar to Python's asyncio.Condition
|
|
@@ -17502,7 +17504,7 @@
|
|
|
17502
17504
|
const newBalance = Math.max(0, Math.min(this.initialWindow, prev + delta));
|
|
17503
17505
|
this.credits.set(flowId, newBalance);
|
|
17504
17506
|
const crossedZero = prev <= 0 && newBalance > 0;
|
|
17505
|
-
logger$
|
|
17507
|
+
logger$1g.debug('flow_controller_add_credits', {
|
|
17506
17508
|
flow_id: flowId,
|
|
17507
17509
|
delta,
|
|
17508
17510
|
prev_balance: prev,
|
|
@@ -17522,12 +17524,12 @@
|
|
|
17522
17524
|
async acquire(flowId) {
|
|
17523
17525
|
this.ensureFlow(flowId);
|
|
17524
17526
|
const condition = this.conditions.get(flowId);
|
|
17525
|
-
logger$
|
|
17527
|
+
logger$1g.debug('flow_controller_acquire_attempt', {
|
|
17526
17528
|
flow_id: flowId,
|
|
17527
17529
|
current_balance: this.credits.get(flowId),
|
|
17528
17530
|
});
|
|
17529
17531
|
while (this.credits.get(flowId) <= 0) {
|
|
17530
|
-
logger$
|
|
17532
|
+
logger$1g.debug('flow_controller_waiting_for_credits', {
|
|
17531
17533
|
flow_id: flowId,
|
|
17532
17534
|
current_balance: this.credits.get(flowId),
|
|
17533
17535
|
});
|
|
@@ -17535,12 +17537,12 @@
|
|
|
17535
17537
|
}
|
|
17536
17538
|
const newBalance = this.credits.get(flowId) - 1;
|
|
17537
17539
|
this.credits.set(flowId, newBalance);
|
|
17538
|
-
logger$
|
|
17540
|
+
logger$1g.debug('flow_controller_acquire_success', {
|
|
17539
17541
|
flow_id: flowId,
|
|
17540
17542
|
new_balance: newBalance,
|
|
17541
17543
|
});
|
|
17542
17544
|
if (newBalance <= this.lowWatermark) {
|
|
17543
|
-
logger$
|
|
17545
|
+
logger$1g.debug('flow_controller_acquire_below_low_watermark', {
|
|
17544
17546
|
flow_id: flowId,
|
|
17545
17547
|
low_watermark: this.lowWatermark,
|
|
17546
17548
|
});
|
|
@@ -17564,7 +17566,7 @@
|
|
|
17564
17566
|
const current = this.credits.get(flowId);
|
|
17565
17567
|
const remaining = Math.max(current - credits, 0);
|
|
17566
17568
|
this.credits.set(flowId, remaining);
|
|
17567
|
-
logger$
|
|
17569
|
+
logger$1g.debug('flow_controller_consume', {
|
|
17568
17570
|
flow_id: flowId,
|
|
17569
17571
|
requested: credits,
|
|
17570
17572
|
prev_balance: current,
|
|
@@ -17590,7 +17592,7 @@
|
|
|
17590
17592
|
this.windowIds.delete(flowId);
|
|
17591
17593
|
this.credits.set(flowId, this.initialWindow);
|
|
17592
17594
|
this.wakeWaiters(flowId);
|
|
17593
|
-
logger$
|
|
17595
|
+
logger$1g.debug('flow_controller_flow_reset', {
|
|
17594
17596
|
flow_id: flowId,
|
|
17595
17597
|
reset_balance: this.initialWindow,
|
|
17596
17598
|
});
|
|
@@ -17971,7 +17973,7 @@
|
|
|
17971
17973
|
return new EnvCredentialProvider(resolved.varName);
|
|
17972
17974
|
}
|
|
17973
17975
|
}
|
|
17974
|
-
const FACTORY_META$
|
|
17976
|
+
const FACTORY_META$1c = {
|
|
17975
17977
|
base: CREDENTIAL_PROVIDER_FACTORY_BASE_TYPE,
|
|
17976
17978
|
key: 'EnvCredentialProvider',
|
|
17977
17979
|
};
|
|
@@ -17979,7 +17981,7 @@
|
|
|
17979
17981
|
var envCredentialProviderFactory = /*#__PURE__*/Object.freeze({
|
|
17980
17982
|
__proto__: null,
|
|
17981
17983
|
EnvCredentialProviderFactory: EnvCredentialProviderFactory,
|
|
17982
|
-
FACTORY_META: FACTORY_META$
|
|
17984
|
+
FACTORY_META: FACTORY_META$1c,
|
|
17983
17985
|
default: EnvCredentialProviderFactory,
|
|
17984
17986
|
normalizeEnvConfig: normalizeEnvConfig
|
|
17985
17987
|
});
|
|
@@ -18077,14 +18079,14 @@
|
|
|
18077
18079
|
return new PromptCredentialProvider(resolved.credentialName);
|
|
18078
18080
|
}
|
|
18079
18081
|
}
|
|
18080
|
-
const FACTORY_META$
|
|
18082
|
+
const FACTORY_META$1b = {
|
|
18081
18083
|
base: CREDENTIAL_PROVIDER_FACTORY_BASE_TYPE,
|
|
18082
18084
|
key: 'PromptCredentialProvider',
|
|
18083
18085
|
};
|
|
18084
18086
|
|
|
18085
18087
|
var promptCredentialProviderFactory = /*#__PURE__*/Object.freeze({
|
|
18086
18088
|
__proto__: null,
|
|
18087
|
-
FACTORY_META: FACTORY_META$
|
|
18089
|
+
FACTORY_META: FACTORY_META$1b,
|
|
18088
18090
|
PromptCredentialProviderFactory: PromptCredentialProviderFactory,
|
|
18089
18091
|
default: PromptCredentialProviderFactory,
|
|
18090
18092
|
normalizePromptConfig: normalizePromptConfig
|
|
@@ -18138,14 +18140,14 @@
|
|
|
18138
18140
|
return new SecretStoreCredentialProvider(resolved.secretName);
|
|
18139
18141
|
}
|
|
18140
18142
|
}
|
|
18141
|
-
const FACTORY_META$
|
|
18143
|
+
const FACTORY_META$1a = {
|
|
18142
18144
|
base: CREDENTIAL_PROVIDER_FACTORY_BASE_TYPE,
|
|
18143
18145
|
key: 'SecretStoreCredentialProvider',
|
|
18144
18146
|
};
|
|
18145
18147
|
|
|
18146
18148
|
var secretStoreCredentialProviderFactory = /*#__PURE__*/Object.freeze({
|
|
18147
18149
|
__proto__: null,
|
|
18148
|
-
FACTORY_META: FACTORY_META$
|
|
18150
|
+
FACTORY_META: FACTORY_META$1a,
|
|
18149
18151
|
SecretStoreCredentialProviderFactory: SecretStoreCredentialProviderFactory,
|
|
18150
18152
|
default: SecretStoreCredentialProviderFactory,
|
|
18151
18153
|
normalizeSecretStoreConfig: normalizeSecretStoreConfig
|
|
@@ -18194,14 +18196,14 @@
|
|
|
18194
18196
|
return new StaticCredentialProvider(resolved.credentialValue);
|
|
18195
18197
|
}
|
|
18196
18198
|
}
|
|
18197
|
-
const FACTORY_META$
|
|
18199
|
+
const FACTORY_META$19 = {
|
|
18198
18200
|
base: CREDENTIAL_PROVIDER_FACTORY_BASE_TYPE,
|
|
18199
18201
|
key: 'StaticCredentialProvider',
|
|
18200
18202
|
};
|
|
18201
18203
|
|
|
18202
18204
|
var staticCredentialProviderFactory = /*#__PURE__*/Object.freeze({
|
|
18203
18205
|
__proto__: null,
|
|
18204
|
-
FACTORY_META: FACTORY_META$
|
|
18206
|
+
FACTORY_META: FACTORY_META$19,
|
|
18205
18207
|
StaticCredentialProviderFactory: StaticCredentialProviderFactory,
|
|
18206
18208
|
default: StaticCredentialProviderFactory,
|
|
18207
18209
|
normalizeStaticConfig: normalizeStaticConfig
|
|
@@ -19412,7 +19414,7 @@
|
|
|
19412
19414
|
return value;
|
|
19413
19415
|
}
|
|
19414
19416
|
|
|
19415
|
-
const logger$
|
|
19417
|
+
const logger$1e = getLogger('naylence.fame.node.binding_manager');
|
|
19416
19418
|
const SYSTEM_INBOX$3 = '__sys__';
|
|
19417
19419
|
const DEFAULT_ACK_TIMEOUT_MS = 20000;
|
|
19418
19420
|
class BindingStoreEntryRecord {
|
|
@@ -19498,7 +19500,7 @@
|
|
|
19498
19500
|
if (!this.bindings.has(key)) {
|
|
19499
19501
|
const binding = this.bindingFactory(new FameAddress(key));
|
|
19500
19502
|
this.bindings.set(key, binding);
|
|
19501
|
-
logger$
|
|
19503
|
+
logger$1e.debug('restored_binding', { address: key });
|
|
19502
19504
|
}
|
|
19503
19505
|
}
|
|
19504
19506
|
if (!this.hasUpstream) {
|
|
@@ -19508,13 +19510,13 @@
|
|
|
19508
19510
|
await this.readvertiseCapabilitiesUpstream();
|
|
19509
19511
|
}
|
|
19510
19512
|
async bind(participant, capabilities) {
|
|
19511
|
-
logger$
|
|
19513
|
+
logger$1e.debug('binding_participant', { participant });
|
|
19512
19514
|
const { prefixAddress, addresses, propagateAddress, capabilityAddress } = this.computeBindingAddresses(participant);
|
|
19513
19515
|
for (const address of addresses) {
|
|
19514
19516
|
if (!this.bindings.has(address)) {
|
|
19515
19517
|
const binding = this.bindingFactory(new FameAddress(address));
|
|
19516
19518
|
this.bindings.set(address, binding);
|
|
19517
|
-
logger$
|
|
19519
|
+
logger$1e.debug('bound_address', { address, participant });
|
|
19518
19520
|
}
|
|
19519
19521
|
}
|
|
19520
19522
|
let propagatedAddress = null;
|
|
@@ -19543,7 +19545,7 @@
|
|
|
19543
19545
|
await this.unbindAddressUpstream(propagatedAddress);
|
|
19544
19546
|
}
|
|
19545
19547
|
catch (rollbackError) {
|
|
19546
|
-
logger$
|
|
19548
|
+
logger$1e.error('bind_rollback_failed', {
|
|
19547
19549
|
address: propagatedAddress.toString(),
|
|
19548
19550
|
error: rollbackError.message,
|
|
19549
19551
|
});
|
|
@@ -19562,7 +19564,7 @@
|
|
|
19562
19564
|
physicalPath: null,
|
|
19563
19565
|
});
|
|
19564
19566
|
}
|
|
19565
|
-
logger$
|
|
19567
|
+
logger$1e.debug('bind_success', {
|
|
19566
19568
|
participant,
|
|
19567
19569
|
address: prefixAddress.toString(),
|
|
19568
19570
|
capabilities,
|
|
@@ -19598,7 +19600,7 @@
|
|
|
19598
19600
|
await this.bindingStore.delete(address);
|
|
19599
19601
|
}
|
|
19600
19602
|
}
|
|
19601
|
-
logger$
|
|
19603
|
+
logger$1e.debug('unbind_success', {
|
|
19602
19604
|
participant,
|
|
19603
19605
|
address: prefixAddress.toString(),
|
|
19604
19606
|
totalBindings: this.bindings.size,
|
|
@@ -19628,7 +19630,7 @@
|
|
|
19628
19630
|
await this.bindAddressUpstream(new FameAddress(address));
|
|
19629
19631
|
}
|
|
19630
19632
|
catch (error) {
|
|
19631
|
-
logger$
|
|
19633
|
+
logger$1e.error('rebind_failed', {
|
|
19632
19634
|
address,
|
|
19633
19635
|
error: error.message,
|
|
19634
19636
|
});
|
|
@@ -19647,7 +19649,7 @@
|
|
|
19647
19649
|
await this.advertiseCapabilities(new FameAddress(address), Array.from(capabilities));
|
|
19648
19650
|
}
|
|
19649
19651
|
catch (error) {
|
|
19650
|
-
logger$
|
|
19652
|
+
logger$1e.error('capability_replay_failed', {
|
|
19651
19653
|
address,
|
|
19652
19654
|
error: error.message,
|
|
19653
19655
|
});
|
|
@@ -19914,7 +19916,7 @@
|
|
|
19914
19916
|
}
|
|
19915
19917
|
}
|
|
19916
19918
|
|
|
19917
|
-
const logger$
|
|
19919
|
+
const logger$1d = getLogger('naylence.fame.node.response_context_manager');
|
|
19918
19920
|
function cloneSecurityContext(source) {
|
|
19919
19921
|
if (!source) {
|
|
19920
19922
|
return undefined;
|
|
@@ -19942,7 +19944,7 @@
|
|
|
19942
19944
|
security: responseSecurity,
|
|
19943
19945
|
expectedResponseType: FameResponseType.NONE,
|
|
19944
19946
|
};
|
|
19945
|
-
logger$
|
|
19947
|
+
logger$1d.debug('created_response_context', {
|
|
19946
19948
|
request_id: requestEnvelope.id,
|
|
19947
19949
|
inherited_crypto_level: responseSecurity?.inboundCryptoLevel ?? null,
|
|
19948
19950
|
channel_id: responseSecurity?.cryptoChannelId ?? null,
|
|
@@ -19962,14 +19964,14 @@
|
|
|
19962
19964
|
responseContext.fromSystemId = this.getId();
|
|
19963
19965
|
}
|
|
19964
19966
|
// Envelope-level metadata is intentionally omitted to defer to context usage.
|
|
19965
|
-
logger$
|
|
19967
|
+
logger$1d.debug('ensured_response_metadata', {
|
|
19966
19968
|
response_id: responseEnvelope.id,
|
|
19967
19969
|
request_id: requestEnvelope.id,
|
|
19968
19970
|
});
|
|
19969
19971
|
}
|
|
19970
19972
|
}
|
|
19971
19973
|
|
|
19972
|
-
const logger$
|
|
19974
|
+
const logger$1c = getLogger('naylence.fame.node.streaming_response_handler');
|
|
19973
19975
|
function isObject$1(value) {
|
|
19974
19976
|
return typeof value === 'object' && value !== null;
|
|
19975
19977
|
}
|
|
@@ -20088,12 +20090,12 @@
|
|
|
20088
20090
|
}
|
|
20089
20091
|
async handleStreamingFameMessageResponses(responses, requestEnvelope, requestContext) {
|
|
20090
20092
|
const asyncResponses = toAsyncIterable(responses);
|
|
20091
|
-
logger$
|
|
20093
|
+
logger$1c.debug('handling_streaming_fame_message_responses', {
|
|
20092
20094
|
request_id: requestEnvelope.id,
|
|
20093
20095
|
});
|
|
20094
20096
|
for await (const response of asyncResponses) {
|
|
20095
20097
|
if (!response?.envelope) {
|
|
20096
|
-
logger$
|
|
20098
|
+
logger$1c.warning('invalid_streaming_response_type', {
|
|
20097
20099
|
request_id: requestEnvelope.id,
|
|
20098
20100
|
actual_type: typeof response,
|
|
20099
20101
|
});
|
|
@@ -20107,7 +20109,7 @@
|
|
|
20107
20109
|
}
|
|
20108
20110
|
async handleStreamingResponse(result, requestEnvelope, requestContext, replyTo, requestId) {
|
|
20109
20111
|
const iterable = toAsyncIterable(result);
|
|
20110
|
-
logger$
|
|
20112
|
+
logger$1c.debug('handling_streaming_response', {
|
|
20111
20113
|
request_id: requestId,
|
|
20112
20114
|
reply_to: replyTo,
|
|
20113
20115
|
});
|
|
@@ -20118,7 +20120,7 @@
|
|
|
20118
20120
|
await this.sendRpcResponse(null, requestEnvelope, requestContext, replyTo, requestId);
|
|
20119
20121
|
}
|
|
20120
20122
|
catch (error) {
|
|
20121
|
-
logger$
|
|
20123
|
+
logger$1c.error('streaming_response_handler_error', {
|
|
20122
20124
|
request_id: requestId,
|
|
20123
20125
|
error: error instanceof Error ? error.message : String(error),
|
|
20124
20126
|
});
|
|
@@ -20145,7 +20147,7 @@
|
|
|
20145
20147
|
});
|
|
20146
20148
|
const responseContext = this.responseContextManager.createResponseContext(requestEnvelope, requestContext);
|
|
20147
20149
|
this.responseContextManager.ensureResponseMetadata(responseEnvelope, requestEnvelope, responseContext);
|
|
20148
|
-
logger$
|
|
20150
|
+
logger$1c.debug('sending_streaming_rpc_response', {
|
|
20149
20151
|
request_id: requestId,
|
|
20150
20152
|
response_envelope_id: responseEnvelope.id,
|
|
20151
20153
|
reply_to: replyTo,
|
|
@@ -20158,7 +20160,7 @@
|
|
|
20158
20160
|
}
|
|
20159
20161
|
}
|
|
20160
20162
|
|
|
20161
|
-
const logger$
|
|
20163
|
+
const logger$1b = getLogger('naylence.fame.node.channel_polling_manager');
|
|
20162
20164
|
class ChannelPollingManager {
|
|
20163
20165
|
constructor(deliverWrapper, responseContextManager, streamingResponseHandler) {
|
|
20164
20166
|
this.deliverWrapper = deliverWrapper;
|
|
@@ -20166,7 +20168,7 @@
|
|
|
20166
20168
|
this.streamingResponseHandler = streamingResponseHandler;
|
|
20167
20169
|
}
|
|
20168
20170
|
async startPollingLoop(serviceName, channel, handler, stopState, pollTimeoutMs = DEFAULT_POLLING_TIMEOUT_MS) {
|
|
20169
|
-
logger$
|
|
20171
|
+
logger$1b.debug('poll_loop_started', {
|
|
20170
20172
|
recipient: serviceName,
|
|
20171
20173
|
});
|
|
20172
20174
|
try {
|
|
@@ -20174,7 +20176,7 @@
|
|
|
20174
20176
|
while (true) {
|
|
20175
20177
|
if (this.isStopRequested(stopState) && !draining) {
|
|
20176
20178
|
draining = true;
|
|
20177
|
-
logger$
|
|
20179
|
+
logger$1b.debug('poll_loop_draining_pending_messages', {
|
|
20178
20180
|
recipient: serviceName,
|
|
20179
20181
|
});
|
|
20180
20182
|
}
|
|
@@ -20184,7 +20186,7 @@
|
|
|
20184
20186
|
}
|
|
20185
20187
|
catch (error) {
|
|
20186
20188
|
if (error instanceof FameTransportClose) {
|
|
20187
|
-
logger$
|
|
20189
|
+
logger$1b.debug('channel_closed', {
|
|
20188
20190
|
recipient: serviceName,
|
|
20189
20191
|
message: error.message,
|
|
20190
20192
|
});
|
|
@@ -20197,7 +20199,7 @@
|
|
|
20197
20199
|
continue;
|
|
20198
20200
|
}
|
|
20199
20201
|
if (error instanceof Error && error.name === 'AbortError') {
|
|
20200
|
-
logger$
|
|
20202
|
+
logger$1b.debug('listener_cancelled', {
|
|
20201
20203
|
recipient: serviceName,
|
|
20202
20204
|
});
|
|
20203
20205
|
throw error;
|
|
@@ -20209,13 +20211,13 @@
|
|
|
20209
20211
|
continue;
|
|
20210
20212
|
}
|
|
20211
20213
|
if (error instanceof Error && error.message === 'Channel is closed') {
|
|
20212
|
-
logger$
|
|
20214
|
+
logger$1b.debug('channel_closed', {
|
|
20213
20215
|
recipient: serviceName,
|
|
20214
20216
|
});
|
|
20215
20217
|
break;
|
|
20216
20218
|
}
|
|
20217
20219
|
if (error instanceof Error && error.name === 'TaskCancelledError') {
|
|
20218
|
-
logger$
|
|
20220
|
+
logger$1b.debug('listener_cancelled', {
|
|
20219
20221
|
recipient: serviceName,
|
|
20220
20222
|
});
|
|
20221
20223
|
throw error;
|
|
@@ -20227,12 +20229,12 @@
|
|
|
20227
20229
|
continue;
|
|
20228
20230
|
}
|
|
20229
20231
|
if (error instanceof Error && error.message.includes('closed')) {
|
|
20230
|
-
logger$
|
|
20232
|
+
logger$1b.debug('channel_closed', {
|
|
20231
20233
|
recipient: serviceName,
|
|
20232
20234
|
});
|
|
20233
20235
|
break;
|
|
20234
20236
|
}
|
|
20235
|
-
logger$
|
|
20237
|
+
logger$1b.error('transport_error', {
|
|
20236
20238
|
recipient: serviceName,
|
|
20237
20239
|
error: error instanceof Error ? error.message : String(error),
|
|
20238
20240
|
});
|
|
@@ -20248,7 +20250,7 @@
|
|
|
20248
20250
|
}
|
|
20249
20251
|
}
|
|
20250
20252
|
finally {
|
|
20251
|
-
logger$
|
|
20253
|
+
logger$1b.debug('poll_loop_exiting', {
|
|
20252
20254
|
recipient: serviceName,
|
|
20253
20255
|
});
|
|
20254
20256
|
}
|
|
@@ -20261,7 +20263,7 @@
|
|
|
20261
20263
|
await this.processHandlerResult(result, envelope, deliveryContext, serviceName);
|
|
20262
20264
|
}
|
|
20263
20265
|
catch (error) {
|
|
20264
|
-
logger$
|
|
20266
|
+
logger$1b.error('handler_crashed', {
|
|
20265
20267
|
recipient: serviceName,
|
|
20266
20268
|
error: error instanceof Error ? error.message : String(error),
|
|
20267
20269
|
});
|
|
@@ -20275,7 +20277,7 @@
|
|
|
20275
20277
|
return;
|
|
20276
20278
|
}
|
|
20277
20279
|
if (this.streamingResponseHandler.isStreamingFameMessageResponse(result)) {
|
|
20278
|
-
logger$
|
|
20280
|
+
logger$1b.debug('handling_streaming_fame_message_responses', {
|
|
20279
20281
|
service_name: serviceName,
|
|
20280
20282
|
envelope_id: envelope.id,
|
|
20281
20283
|
});
|
|
@@ -20283,7 +20285,7 @@
|
|
|
20283
20285
|
}
|
|
20284
20286
|
}
|
|
20285
20287
|
async handleMessageResponse(response, requestEnvelope, requestContext, serviceName) {
|
|
20286
|
-
logger$
|
|
20288
|
+
logger$1b.debug('delivering_envelope_response_message', {
|
|
20287
20289
|
service_name: serviceName,
|
|
20288
20290
|
response_envelope_id: response.envelope.id,
|
|
20289
20291
|
});
|
|
@@ -20303,7 +20305,7 @@
|
|
|
20303
20305
|
}
|
|
20304
20306
|
}
|
|
20305
20307
|
|
|
20306
|
-
const logger$
|
|
20308
|
+
const logger$1a = getLogger('naylence.fame.node.rpc_server_handler');
|
|
20307
20309
|
function isPlainRecord$6(value) {
|
|
20308
20310
|
if (typeof value !== 'object' || value === null) {
|
|
20309
20311
|
return false;
|
|
@@ -20347,13 +20349,13 @@
|
|
|
20347
20349
|
}
|
|
20348
20350
|
async handleRpcRequest(envelope, handlerContext, handler, serviceName) {
|
|
20349
20351
|
if (!this.isDataFrame(envelope.frame)) {
|
|
20350
|
-
logger$
|
|
20352
|
+
logger$1a.warning('rpc_request_missing_data_frame', {
|
|
20351
20353
|
service_name: serviceName,
|
|
20352
20354
|
envelope_id: envelope.id,
|
|
20353
20355
|
});
|
|
20354
20356
|
return;
|
|
20355
20357
|
}
|
|
20356
|
-
logger$
|
|
20358
|
+
logger$1a.debug('rpc_request_received', {
|
|
20357
20359
|
service_name: serviceName,
|
|
20358
20360
|
envelope_id: envelope.id,
|
|
20359
20361
|
trace_id: envelope.traceId,
|
|
@@ -20365,7 +20367,7 @@
|
|
|
20365
20367
|
request = parseRequest(envelope.frame.payload);
|
|
20366
20368
|
params = cloneParams(request.params);
|
|
20367
20369
|
const paramKeys = Object.keys(params);
|
|
20368
|
-
logger$
|
|
20370
|
+
logger$1a.debug('parsed_rpc_request', {
|
|
20369
20371
|
service_name: serviceName,
|
|
20370
20372
|
method: request.method,
|
|
20371
20373
|
request_id: request.id,
|
|
@@ -20374,7 +20376,7 @@
|
|
|
20374
20376
|
});
|
|
20375
20377
|
}
|
|
20376
20378
|
catch (error) {
|
|
20377
|
-
logger$
|
|
20379
|
+
logger$1a.warning('request_decode_error', {
|
|
20378
20380
|
service_name: serviceName,
|
|
20379
20381
|
envelope_id: envelope.id,
|
|
20380
20382
|
error: error instanceof Error ? error.message : String(error),
|
|
@@ -20382,7 +20384,7 @@
|
|
|
20382
20384
|
return;
|
|
20383
20385
|
}
|
|
20384
20386
|
if (request.id == null) {
|
|
20385
|
-
logger$
|
|
20387
|
+
logger$1a.warning('request_missing_id', {
|
|
20386
20388
|
service_name: serviceName,
|
|
20387
20389
|
envelope_id: envelope.id,
|
|
20388
20390
|
});
|
|
@@ -20390,7 +20392,7 @@
|
|
|
20390
20392
|
}
|
|
20391
20393
|
const replyTo = this.resolveReplyTo(envelope, params);
|
|
20392
20394
|
if (!replyTo) {
|
|
20393
|
-
logger$
|
|
20395
|
+
logger$1a.warning('missing_reply_to', {
|
|
20394
20396
|
service_name: serviceName,
|
|
20395
20397
|
envelope_id: envelope.id,
|
|
20396
20398
|
request_id: request.id,
|
|
@@ -20399,13 +20401,13 @@
|
|
|
20399
20401
|
}
|
|
20400
20402
|
let handlerResult;
|
|
20401
20403
|
try {
|
|
20402
|
-
logger$
|
|
20404
|
+
logger$1a.debug('calling_rpc_handler', {
|
|
20403
20405
|
service_name: serviceName,
|
|
20404
20406
|
method: request.method,
|
|
20405
20407
|
request_id: request.id,
|
|
20406
20408
|
});
|
|
20407
20409
|
handlerResult = await handler(request.method, params);
|
|
20408
|
-
logger$
|
|
20410
|
+
logger$1a.debug('rpc_handler_returned', {
|
|
20409
20411
|
service_name: serviceName,
|
|
20410
20412
|
method: request.method,
|
|
20411
20413
|
request_id: request.id,
|
|
@@ -20414,7 +20416,7 @@
|
|
|
20414
20416
|
});
|
|
20415
20417
|
}
|
|
20416
20418
|
catch (error) {
|
|
20417
|
-
logger$
|
|
20419
|
+
logger$1a.error('rpc_handler_error', {
|
|
20418
20420
|
service_name: serviceName,
|
|
20419
20421
|
request_id: request.id,
|
|
20420
20422
|
envelope_id: envelope.id,
|
|
@@ -20424,7 +20426,7 @@
|
|
|
20424
20426
|
return this.createTraditionalResponse(response, request.id, envelope, replyTo, handlerContext, serviceName);
|
|
20425
20427
|
}
|
|
20426
20428
|
if (isFameMessageResponse(handlerResult)) {
|
|
20427
|
-
logger$
|
|
20429
|
+
logger$1a.debug('returning_response_message', {
|
|
20428
20430
|
service_name: serviceName,
|
|
20429
20431
|
request_id: request.id,
|
|
20430
20432
|
response_envelope_id: handlerResult.envelope.id,
|
|
@@ -20432,7 +20434,7 @@
|
|
|
20432
20434
|
return handlerResult;
|
|
20433
20435
|
}
|
|
20434
20436
|
if (this.streamingResponseHandler.isStreamingResult(handlerResult)) {
|
|
20435
|
-
logger$
|
|
20437
|
+
logger$1a.debug('handling_streaming_response', {
|
|
20436
20438
|
service_name: serviceName,
|
|
20437
20439
|
request_id: request.id,
|
|
20438
20440
|
envelope_id: envelope.id,
|
|
@@ -20461,7 +20463,7 @@
|
|
|
20461
20463
|
return null;
|
|
20462
20464
|
}
|
|
20463
20465
|
async createTraditionalResponse(payload, requestId, requestEnvelope, replyTo, handlerContext, serviceName) {
|
|
20464
|
-
logger$
|
|
20466
|
+
logger$1a.debug('creating_traditional_response_envelope', {
|
|
20465
20467
|
service_name: serviceName,
|
|
20466
20468
|
request_id: requestId,
|
|
20467
20469
|
envelope_id: requestEnvelope.id,
|
|
@@ -20485,7 +20487,7 @@
|
|
|
20485
20487
|
if (requestEnvelope.id) {
|
|
20486
20488
|
responseContext.meta['response-to-id'] = requestEnvelope.id;
|
|
20487
20489
|
}
|
|
20488
|
-
logger$
|
|
20490
|
+
logger$1a.debug('returning_traditional_response', {
|
|
20489
20491
|
service_name: serviceName,
|
|
20490
20492
|
request_id: requestId,
|
|
20491
20493
|
envelope_id: requestEnvelope.id,
|
|
@@ -20550,7 +20552,7 @@
|
|
|
20550
20552
|
return code;
|
|
20551
20553
|
}
|
|
20552
20554
|
|
|
20553
|
-
const logger$
|
|
20555
|
+
const logger$19 = getLogger('naylence.fame.node.rpc_client_manager');
|
|
20554
20556
|
function isPlainRecord$5(value) {
|
|
20555
20557
|
if (typeof value !== 'object' || value === null) {
|
|
20556
20558
|
return false;
|
|
@@ -20767,7 +20769,7 @@
|
|
|
20767
20769
|
const metaReason = tracked.meta?.['nack_reason'];
|
|
20768
20770
|
const formattedMessage = formatDeliveryErrorMessage(typeof metaCode === 'string' ? metaCode : 'DELIVERY_ERROR', reason ??
|
|
20769
20771
|
(typeof metaReason === 'string' ? metaReason : undefined));
|
|
20770
|
-
logger$
|
|
20772
|
+
logger$19.debug('pending_request_rejected_by_delivery_nack', {
|
|
20771
20773
|
envelope_id: envelopeId,
|
|
20772
20774
|
request_id: requestId,
|
|
20773
20775
|
code: typeof metaCode === 'string' ? metaCode : 'DELIVERY_ERROR',
|
|
@@ -20790,7 +20792,7 @@
|
|
|
20790
20792
|
this.trackerWithEvents.removeEventHandler?.(this.trackerEventHandler);
|
|
20791
20793
|
}
|
|
20792
20794
|
catch (error) {
|
|
20793
|
-
logger$
|
|
20795
|
+
logger$19.debug('rpc_tracker_handler_remove_failed', {
|
|
20794
20796
|
error: error instanceof Error ? error.message : String(error),
|
|
20795
20797
|
});
|
|
20796
20798
|
}
|
|
@@ -20833,7 +20835,7 @@
|
|
|
20833
20835
|
this.rpcListenerAddress = await this.listenCallback(recipient, handler);
|
|
20834
20836
|
this.rpcBound = true;
|
|
20835
20837
|
this.boundPhysicalPath = currentPhysicalPath;
|
|
20836
|
-
logger$
|
|
20838
|
+
logger$19.debug('rpc_reply_listener_bound', {
|
|
20837
20839
|
reply_recipient: recipient,
|
|
20838
20840
|
reply_address: this.rpcReplyAddress?.toString(),
|
|
20839
20841
|
listener_address: this.rpcListenerAddress?.toString(),
|
|
@@ -20927,7 +20929,7 @@
|
|
|
20927
20929
|
const finalizePromise = this.notifyStreamClosed(envelopeId);
|
|
20928
20930
|
if (finalizePromise) {
|
|
20929
20931
|
finalizePromise.catch((notifyError) => {
|
|
20930
|
-
logger$
|
|
20932
|
+
logger$19.debug('stream_tracker_finalize_failed', {
|
|
20931
20933
|
request_id: requestId,
|
|
20932
20934
|
envelope_id: envelopeId,
|
|
20933
20935
|
error: notifyError instanceof Error
|
|
@@ -20988,7 +20990,7 @@
|
|
|
20988
20990
|
return iterator;
|
|
20989
20991
|
}
|
|
20990
20992
|
async sendRpcRequest(requestId, envelope, expectedResponseType, timeoutMs) {
|
|
20991
|
-
logger$
|
|
20993
|
+
logger$19.debug('sending_rpc_request', {
|
|
20992
20994
|
envp_id: envelope.id,
|
|
20993
20995
|
corr_id: envelope.corrId,
|
|
20994
20996
|
request_id: requestId,
|
|
@@ -21004,7 +21006,7 @@
|
|
|
21004
21006
|
}
|
|
21005
21007
|
}
|
|
21006
21008
|
catch (error) {
|
|
21007
|
-
logger$
|
|
21009
|
+
logger$19.warning('delivery_tracker_track_failed', {
|
|
21008
21010
|
request_id: requestId,
|
|
21009
21011
|
error: error instanceof Error ? error.message : String(error),
|
|
21010
21012
|
});
|
|
@@ -21017,14 +21019,14 @@
|
|
|
21017
21019
|
await this.deliverWrapper()(envelope, context);
|
|
21018
21020
|
}
|
|
21019
21021
|
async handleReplyEnvelope(envelope) {
|
|
21020
|
-
logger$
|
|
21022
|
+
logger$19.debug('handle_reply_envelope_received', {
|
|
21021
21023
|
envelope_id: envelope.id,
|
|
21022
21024
|
corr_id: envelope.corrId,
|
|
21023
21025
|
frame_type: envelope.frame?.['type'],
|
|
21024
21026
|
});
|
|
21025
21027
|
let requestId = envelope.corrId ?? envelope.id;
|
|
21026
21028
|
if (!requestId) {
|
|
21027
|
-
logger$
|
|
21029
|
+
logger$19.warning('reply_envelope_missing_corr_id', {
|
|
21028
21030
|
envelope_id: envelope.id,
|
|
21029
21031
|
});
|
|
21030
21032
|
return;
|
|
@@ -21042,12 +21044,12 @@
|
|
|
21042
21044
|
}
|
|
21043
21045
|
}
|
|
21044
21046
|
if (!entry) {
|
|
21045
|
-
logger$
|
|
21047
|
+
logger$19.debug('no_pending_request_for_reply', {
|
|
21046
21048
|
request_id: requestId,
|
|
21047
21049
|
});
|
|
21048
21050
|
return;
|
|
21049
21051
|
}
|
|
21050
|
-
logger$
|
|
21052
|
+
logger$19.debug('handle_reply_envelope', {
|
|
21051
21053
|
envelope_id: envelope.id,
|
|
21052
21054
|
request_id: requestId,
|
|
21053
21055
|
corr_id: envelope.corrId,
|
|
@@ -21060,7 +21062,7 @@
|
|
|
21060
21062
|
const ackIndicatesSuccess = frame.ok === true ||
|
|
21061
21063
|
(frame.ok === undefined && !frame.code && !frame.reason);
|
|
21062
21064
|
if (ackIndicatesSuccess) {
|
|
21063
|
-
logger$
|
|
21065
|
+
logger$19.debug('pending_request_delivery_acknowledged', {
|
|
21064
21066
|
request_id: requestId,
|
|
21065
21067
|
envelope_id: envelope.id,
|
|
21066
21068
|
ref_id: frame.refId ?? null,
|
|
@@ -21088,7 +21090,7 @@
|
|
|
21088
21090
|
entry.timer = null;
|
|
21089
21091
|
}
|
|
21090
21092
|
if (!this.isDataFrame(envelope.frame)) {
|
|
21091
|
-
logger$
|
|
21093
|
+
logger$19.warning('unexpected_reply_frame_type', {
|
|
21092
21094
|
request_id: requestId,
|
|
21093
21095
|
frame_type: envelope.frame?.['type'],
|
|
21094
21096
|
});
|
|
@@ -21154,7 +21156,7 @@
|
|
|
21154
21156
|
return;
|
|
21155
21157
|
}
|
|
21156
21158
|
Promise.resolve(this.deliveryTracker.onStreamItem(envelopeId, envelope)).catch((error) => {
|
|
21157
|
-
logger$
|
|
21159
|
+
logger$19.debug('stream_tracker_push_failed', {
|
|
21158
21160
|
envelope_id: envelopeId,
|
|
21159
21161
|
error: error instanceof Error ? error.message : String(error),
|
|
21160
21162
|
});
|
|
@@ -21269,7 +21271,7 @@
|
|
|
21269
21271
|
return mailbox;
|
|
21270
21272
|
}
|
|
21271
21273
|
|
|
21272
|
-
const logger$
|
|
21274
|
+
const logger$18 = getLogger('naylence.fame.node.envelope_listener_manager');
|
|
21273
21275
|
const SYSTEM_INBOX$2 = '__sys__';
|
|
21274
21276
|
class EnvelopeListener {
|
|
21275
21277
|
constructor(stopFn, task) {
|
|
@@ -21277,7 +21279,7 @@
|
|
|
21277
21279
|
this.task = task;
|
|
21278
21280
|
}
|
|
21279
21281
|
stop() {
|
|
21280
|
-
logger$
|
|
21282
|
+
logger$18.debug('stopping_listener', {
|
|
21281
21283
|
task_name: this.task.name,
|
|
21282
21284
|
});
|
|
21283
21285
|
try {
|
|
@@ -21285,7 +21287,7 @@
|
|
|
21285
21287
|
if (maybeCleanup &&
|
|
21286
21288
|
typeof maybeCleanup.then === 'function') {
|
|
21287
21289
|
void maybeCleanup.catch((error) => {
|
|
21288
|
-
logger$
|
|
21290
|
+
logger$18.debug('listener_stop_cleanup_failed', {
|
|
21289
21291
|
task_name: this.task.name,
|
|
21290
21292
|
error: error instanceof Error ? error.message : String(error),
|
|
21291
21293
|
});
|
|
@@ -21293,7 +21295,7 @@
|
|
|
21293
21295
|
}
|
|
21294
21296
|
}
|
|
21295
21297
|
catch (error) {
|
|
21296
|
-
logger$
|
|
21298
|
+
logger$18.debug('listener_stop_cleanup_failed', {
|
|
21297
21299
|
task_name: this.task.name,
|
|
21298
21300
|
error: error instanceof Error ? error.message : String(error),
|
|
21299
21301
|
});
|
|
@@ -21323,7 +21325,7 @@
|
|
|
21323
21325
|
envelope.replyTo = formatAddress(SYSTEM_INBOX$2, this.nodeLike.physicalPath);
|
|
21324
21326
|
}
|
|
21325
21327
|
catch (error) {
|
|
21326
|
-
logger$
|
|
21328
|
+
logger$18.warning('default_reply_to_assignment_failed', {
|
|
21327
21329
|
envelope_id: envelope.id,
|
|
21328
21330
|
service_name: envelope.capabilities?.[0] ?? null,
|
|
21329
21331
|
error: error instanceof Error ? error.message : String(error),
|
|
@@ -21348,7 +21350,7 @@
|
|
|
21348
21350
|
if (serviceName === SYSTEM_INBOX$2) {
|
|
21349
21351
|
continue;
|
|
21350
21352
|
}
|
|
21351
|
-
logger$
|
|
21353
|
+
logger$18.debug('stopping_listener_for_service', {
|
|
21352
21354
|
service_name: serviceName,
|
|
21353
21355
|
});
|
|
21354
21356
|
entry.listener.stop();
|
|
@@ -21358,7 +21360,7 @@
|
|
|
21358
21360
|
catch (error) {
|
|
21359
21361
|
if (!(error instanceof Error) ||
|
|
21360
21362
|
error.name !== 'TaskCancelledError') {
|
|
21361
|
-
logger$
|
|
21363
|
+
logger$18.debug('listener_task_stopped', {
|
|
21362
21364
|
service_name: serviceName,
|
|
21363
21365
|
error: error instanceof Error ? error.message : String(error),
|
|
21364
21366
|
});
|
|
@@ -21366,7 +21368,7 @@
|
|
|
21366
21368
|
}
|
|
21367
21369
|
}
|
|
21368
21370
|
if (systemEntry) {
|
|
21369
|
-
logger$
|
|
21371
|
+
logger$18.debug('stopping_listener_for_service', {
|
|
21370
21372
|
service_name: SYSTEM_INBOX$2,
|
|
21371
21373
|
});
|
|
21372
21374
|
systemEntry.listener.stop();
|
|
@@ -21376,7 +21378,7 @@
|
|
|
21376
21378
|
catch (error) {
|
|
21377
21379
|
if (!(error instanceof Error) ||
|
|
21378
21380
|
error.name !== 'TaskCancelledError') {
|
|
21379
|
-
logger$
|
|
21381
|
+
logger$18.debug('listener_task_stopped', {
|
|
21380
21382
|
service_name: SYSTEM_INBOX$2,
|
|
21381
21383
|
error: error instanceof Error ? error.message : String(error),
|
|
21382
21384
|
});
|
|
@@ -21393,13 +21395,13 @@
|
|
|
21393
21395
|
}
|
|
21394
21396
|
async recoverUnhandledInboundEnvelopes() {
|
|
21395
21397
|
if (typeof this.deliveryTracker.listInbound !== 'function') {
|
|
21396
|
-
logger$
|
|
21398
|
+
logger$18.debug('delivery_tracker_missing_inbound_listing');
|
|
21397
21399
|
return;
|
|
21398
21400
|
}
|
|
21399
21401
|
const failedInbound = await this.deliveryTracker.listInbound((env) => env.status === EnvelopeStatus.RECEIVED ||
|
|
21400
21402
|
env.status === EnvelopeStatus.FAILED_TO_HANDLE);
|
|
21401
21403
|
if (!failedInbound.length) {
|
|
21402
|
-
logger$
|
|
21404
|
+
logger$18.debug('no_failed_inbound_envelopes_to_recover');
|
|
21403
21405
|
return;
|
|
21404
21406
|
}
|
|
21405
21407
|
const grouped = new Map();
|
|
@@ -21416,7 +21418,7 @@
|
|
|
21416
21418
|
this.pendingRecoveryEnvelopes.set(serviceName, envelopes);
|
|
21417
21419
|
}
|
|
21418
21420
|
});
|
|
21419
|
-
logger$
|
|
21421
|
+
logger$18.debug('discovered_failed_inbound_envelopes', {
|
|
21420
21422
|
total: failedInbound.length,
|
|
21421
21423
|
services: Array.from(grouped.keys()),
|
|
21422
21424
|
});
|
|
@@ -21426,7 +21428,7 @@
|
|
|
21426
21428
|
const pollTimeoutMs = options.pollTimeoutMs ??
|
|
21427
21429
|
options.poll_timeout_ms ??
|
|
21428
21430
|
DEFAULT_POLLING_TIMEOUT_MS;
|
|
21429
|
-
logger$
|
|
21431
|
+
logger$18.debug('listen_start', {
|
|
21430
21432
|
recipient: serviceName,
|
|
21431
21433
|
poll_timeout_ms: pollTimeoutMs ?? DEFAULT_POLLING_TIMEOUT_MS,
|
|
21432
21434
|
});
|
|
@@ -21457,7 +21459,7 @@
|
|
|
21457
21459
|
tracked?.mailboxType === MailboxType.OUTBOX ||
|
|
21458
21460
|
envelope.frame?.['type'] === 'DeliveryAck';
|
|
21459
21461
|
if (!shouldInvoke) {
|
|
21460
|
-
logger$
|
|
21462
|
+
logger$18.debug('skipping_listener_handler', {
|
|
21461
21463
|
recipient: serviceName,
|
|
21462
21464
|
envelope_id: envelope.id,
|
|
21463
21465
|
tracked_status: tracked?.status,
|
|
@@ -21471,13 +21473,13 @@
|
|
|
21471
21473
|
? undefined
|
|
21472
21474
|
: (tracked ?? undefined);
|
|
21473
21475
|
if (trackedForHandler && trackedForHandler.attempt > 0) {
|
|
21474
|
-
logger$
|
|
21476
|
+
logger$18.info('resuming_handler_retry_after_restart', {
|
|
21475
21477
|
envelope_id: envelope.id,
|
|
21476
21478
|
current_attempts: trackedForHandler.attempt,
|
|
21477
21479
|
service_name: serviceName,
|
|
21478
21480
|
});
|
|
21479
21481
|
}
|
|
21480
|
-
logger$
|
|
21482
|
+
logger$18.debug('forwarding_to_listener_handler', {
|
|
21481
21483
|
recipient: serviceName,
|
|
21482
21484
|
envelope_id: envelope.id,
|
|
21483
21485
|
frame_type: envelope.frame?.['type'],
|
|
@@ -21496,7 +21498,7 @@
|
|
|
21496
21498
|
await channel.send(null);
|
|
21497
21499
|
}
|
|
21498
21500
|
catch (error) {
|
|
21499
|
-
logger$
|
|
21501
|
+
logger$18.debug('listener_stop_signal_failed', {
|
|
21500
21502
|
service_name: serviceName,
|
|
21501
21503
|
error: error instanceof Error ? error.message : String(error),
|
|
21502
21504
|
});
|
|
@@ -21505,7 +21507,7 @@
|
|
|
21505
21507
|
await this.listenersLock.runExclusive(async () => {
|
|
21506
21508
|
const existing = this.listeners.get(serviceName);
|
|
21507
21509
|
if (existing) {
|
|
21508
|
-
logger$
|
|
21510
|
+
logger$18.debug('replacing_envelope_listener', { recipient: serviceName });
|
|
21509
21511
|
existing.listener.stop();
|
|
21510
21512
|
try {
|
|
21511
21513
|
await existing.listener.task.promise;
|
|
@@ -21523,13 +21525,13 @@
|
|
|
21523
21525
|
return binding.address;
|
|
21524
21526
|
}
|
|
21525
21527
|
async listenRpc(serviceName, handler, options = {}) {
|
|
21526
|
-
logger$
|
|
21528
|
+
logger$18.debug('rpc_listen_start', { service_name: serviceName });
|
|
21527
21529
|
const rpcHandler = async (envelope, context) => {
|
|
21528
21530
|
const result = await this.rpcServerHandler.handleRpcRequest(envelope, context, handler, serviceName);
|
|
21529
21531
|
return result ?? null;
|
|
21530
21532
|
};
|
|
21531
21533
|
const address = await this.listen(serviceName, rpcHandler, options);
|
|
21532
|
-
logger$
|
|
21534
|
+
logger$18.debug('rpc_listen_bound', {
|
|
21533
21535
|
service_name: serviceName,
|
|
21534
21536
|
address: address.toString(),
|
|
21535
21537
|
});
|
|
@@ -21598,12 +21600,12 @@
|
|
|
21598
21600
|
return cached;
|
|
21599
21601
|
});
|
|
21600
21602
|
if (!envelopes.length) {
|
|
21601
|
-
logger$
|
|
21603
|
+
logger$18.debug('no_cached_recovery_for_service', {
|
|
21602
21604
|
service_name: serviceName,
|
|
21603
21605
|
});
|
|
21604
21606
|
return;
|
|
21605
21607
|
}
|
|
21606
|
-
logger$
|
|
21608
|
+
logger$18.debug('recovering_unhandled_envelopes_on_listen', {
|
|
21607
21609
|
service_name: serviceName,
|
|
21608
21610
|
count: envelopes.length,
|
|
21609
21611
|
envelope_ids: envelopes.map((trackedEnvelope) => trackedEnvelope.envelopeId),
|
|
@@ -21614,7 +21616,7 @@
|
|
|
21614
21616
|
async recoverServiceEnvelopes(serviceName, envelopes, handler) {
|
|
21615
21617
|
for (const tracked of envelopes) {
|
|
21616
21618
|
try {
|
|
21617
|
-
logger$
|
|
21619
|
+
logger$18.warning('recovering_unhandled_envelope', {
|
|
21618
21620
|
envelope_id: tracked.envelopeId,
|
|
21619
21621
|
service_name: serviceName,
|
|
21620
21622
|
current_attempts: tracked.attempt,
|
|
@@ -21623,13 +21625,13 @@
|
|
|
21623
21625
|
const originalEnvelope = tracked.originalEnvelope;
|
|
21624
21626
|
const receiverPolicy = this.nodeLike.deliveryPolicy?.receiverRetryPolicy ?? undefined;
|
|
21625
21627
|
await this.executeHandlerWithRetries(handler, originalEnvelope, undefined, receiverPolicy, tracked, serviceName);
|
|
21626
|
-
logger$
|
|
21628
|
+
logger$18.debug('envelope_recovery_completed', {
|
|
21627
21629
|
envelope_id: tracked.envelopeId,
|
|
21628
21630
|
service_name: serviceName,
|
|
21629
21631
|
});
|
|
21630
21632
|
}
|
|
21631
21633
|
catch (error) {
|
|
21632
|
-
logger$
|
|
21634
|
+
logger$18.error('envelope_recovery_failed', {
|
|
21633
21635
|
envelope_id: tracked.envelopeId,
|
|
21634
21636
|
service_name: serviceName,
|
|
21635
21637
|
error: error instanceof Error ? error.message : String(error),
|
|
@@ -21675,7 +21677,7 @@
|
|
|
21675
21677
|
await this.deliveryTracker.onEnvelopeHandled(trackedEnvelope);
|
|
21676
21678
|
}
|
|
21677
21679
|
if (currentAttempt > 0) {
|
|
21678
|
-
logger$
|
|
21680
|
+
logger$18.info('handler_retry_succeeded', {
|
|
21679
21681
|
envelope_id: envelope.id,
|
|
21680
21682
|
attempt: currentAttempt + 1,
|
|
21681
21683
|
total_attempts: currentAttempt + 1,
|
|
@@ -21691,7 +21693,7 @@
|
|
|
21691
21693
|
await this.deliveryTracker.onEnvelopeHandleFailed(inboxName, trackedEnvelope, context, error instanceof Error ? error : new Error(String(error)), isFinalAttempt);
|
|
21692
21694
|
}
|
|
21693
21695
|
if (isFinalAttempt) {
|
|
21694
|
-
logger$
|
|
21696
|
+
logger$18.error('handler_execution_failed_exhausted_retries', {
|
|
21695
21697
|
envelope_id: envelope.id,
|
|
21696
21698
|
total_attempts: attemptNumber,
|
|
21697
21699
|
max_retries: retryPolicy?.maxRetries ?? 0,
|
|
@@ -21700,7 +21702,7 @@
|
|
|
21700
21702
|
break;
|
|
21701
21703
|
}
|
|
21702
21704
|
const delayMs = retryPolicy?.nextDelayMs(attemptNumber) ?? 0;
|
|
21703
|
-
logger$
|
|
21705
|
+
logger$18.warning('handler_execution_failed_will_retry', {
|
|
21704
21706
|
envelope_id: envelope.id,
|
|
21705
21707
|
attempt: attemptNumber,
|
|
21706
21708
|
max_retries: retryPolicy?.maxRetries ?? 0,
|
|
@@ -21730,7 +21732,7 @@
|
|
|
21730
21732
|
}
|
|
21731
21733
|
}
|
|
21732
21734
|
|
|
21733
|
-
const logger$
|
|
21735
|
+
const logger$17 = getLogger('naylence.fame.delivery.default_delivery_tracker');
|
|
21734
21736
|
const STREAM_END = Symbol('stream-end');
|
|
21735
21737
|
const SWEEPER_TICK = Symbol('tracker-sweeper-tick');
|
|
21736
21738
|
function createDeferred$2() {
|
|
@@ -21949,7 +21951,7 @@
|
|
|
21949
21951
|
const expectedResponseType = options.expectedResponseType;
|
|
21950
21952
|
const tracked = await this.lock.runExclusive(async () => {
|
|
21951
21953
|
if (this.ackFutures.has(envelope.id)) {
|
|
21952
|
-
logger$
|
|
21954
|
+
logger$17.debug('tracker_envelope_already_tracked', {
|
|
21953
21955
|
envp_id: envelope.id,
|
|
21954
21956
|
});
|
|
21955
21957
|
return null;
|
|
@@ -21959,7 +21961,7 @@
|
|
|
21959
21961
|
if (expectedResponseType & FameResponseType.REPLY ||
|
|
21960
21962
|
expectedResponseType & FameResponseType.STREAM) {
|
|
21961
21963
|
if (existingEnvId && existingEnvId !== envelope.id) {
|
|
21962
|
-
logger$
|
|
21964
|
+
logger$17.debug('envelope_already_tracked_for_replies', {
|
|
21963
21965
|
envp_id: envelope.id,
|
|
21964
21966
|
corr_id: corrId,
|
|
21965
21967
|
expected_response_type: expectedResponseType,
|
|
@@ -22008,7 +22010,7 @@
|
|
|
22008
22010
|
return null;
|
|
22009
22011
|
}
|
|
22010
22012
|
await this.scheduleTimer(tracked, options.retryPolicy ?? null, options.retryHandler ?? null);
|
|
22011
|
-
logger$
|
|
22013
|
+
logger$17.debug('tracker_registered_envelope', {
|
|
22012
22014
|
envp_id: envelope.id,
|
|
22013
22015
|
corr_id: tracked.originalEnvelope.corrId,
|
|
22014
22016
|
expected_response: tracked.expectedResponseType,
|
|
@@ -22032,21 +22034,21 @@
|
|
|
22032
22034
|
return this.awaitEnvelopeFuture(envelopeId, FameResponseType.REPLY | FameResponseType.STREAM, future, timeoutMs);
|
|
22033
22035
|
}
|
|
22034
22036
|
async onEnvelopeDelivered(inboxName, envelope, context) {
|
|
22035
|
-
logger$
|
|
22037
|
+
logger$17.debug('envelope_delivered', {
|
|
22036
22038
|
envp_id: envelope.id,
|
|
22037
22039
|
corr_id: envelope.corrId,
|
|
22038
22040
|
rtype: envelope.rtype ?? FameResponseType.NONE,
|
|
22039
22041
|
frame_type: envelope.frame?.type ?? 'unknown',
|
|
22040
22042
|
});
|
|
22041
22043
|
if (!envelope.corrId) {
|
|
22042
|
-
logger$
|
|
22044
|
+
logger$17.debug('envelope_delivered_no_corr_id', {
|
|
22043
22045
|
envelope_id: envelope.id,
|
|
22044
22046
|
});
|
|
22045
22047
|
return null;
|
|
22046
22048
|
}
|
|
22047
22049
|
if (this.isDeliveryAckFrame(envelope.frame)) {
|
|
22048
22050
|
if (!envelope.frame.refId) {
|
|
22049
|
-
logger$
|
|
22051
|
+
logger$17.debug('envelope_delivered_no_ref_id', {
|
|
22050
22052
|
envelope_id: envelope.id,
|
|
22051
22053
|
});
|
|
22052
22054
|
return null;
|
|
@@ -22083,7 +22085,7 @@
|
|
|
22083
22085
|
await inbox.set(envelope.id, tracked);
|
|
22084
22086
|
}
|
|
22085
22087
|
else {
|
|
22086
|
-
logger$
|
|
22088
|
+
logger$17.debug('tracker_duplicate_envelope_already_handled', {
|
|
22087
22089
|
envp_id: envelope.id,
|
|
22088
22090
|
status: tracked.status,
|
|
22089
22091
|
});
|
|
@@ -22125,7 +22127,7 @@
|
|
|
22125
22127
|
}
|
|
22126
22128
|
if (isFinalFailure) {
|
|
22127
22129
|
envelope.status = EnvelopeStatus.FAILED_TO_HANDLE;
|
|
22128
|
-
logger$
|
|
22130
|
+
logger$17.error('envelope_handle_failed_final', {
|
|
22129
22131
|
inbox_name: inboxName,
|
|
22130
22132
|
envp_id: envelope.originalEnvelope.id,
|
|
22131
22133
|
error: error?.message ?? 'unknown',
|
|
@@ -22136,7 +22138,7 @@
|
|
|
22136
22138
|
await inbox.delete(envelope.originalEnvelope.id);
|
|
22137
22139
|
return;
|
|
22138
22140
|
}
|
|
22139
|
-
logger$
|
|
22141
|
+
logger$17.warning('envelope_handle_failed_retry', {
|
|
22140
22142
|
inbox_name: inboxName,
|
|
22141
22143
|
envp_id: envelope.originalEnvelope.id,
|
|
22142
22144
|
error: error?.message ?? 'unknown',
|
|
@@ -22181,14 +22183,14 @@
|
|
|
22181
22183
|
if (handledViaFuture) {
|
|
22182
22184
|
await this.markDoneSince(this.ackFutures, refId, this.ackDoneSince);
|
|
22183
22185
|
await this.clearTimer(refId);
|
|
22184
|
-
logger$
|
|
22186
|
+
logger$17.debug('tracker_ack_resolved_without_tracked_envelope', {
|
|
22185
22187
|
envp_id: envelope.id,
|
|
22186
22188
|
ref_id: refId,
|
|
22187
22189
|
corr_id: envelope.corrId,
|
|
22188
22190
|
});
|
|
22189
22191
|
return;
|
|
22190
22192
|
}
|
|
22191
|
-
logger$
|
|
22193
|
+
logger$17.debug('tracker_ack_for_unknown_envelope', {
|
|
22192
22194
|
envp_id: envelope.id,
|
|
22193
22195
|
ref_id: refId,
|
|
22194
22196
|
corr_id: envelope.corrId,
|
|
@@ -22196,7 +22198,7 @@
|
|
|
22196
22198
|
return;
|
|
22197
22199
|
}
|
|
22198
22200
|
if (tracked.originalEnvelope.corrId !== envelope.corrId) {
|
|
22199
|
-
logger$
|
|
22201
|
+
logger$17.debug('tracker_ack_corr_id_mismatch', {
|
|
22200
22202
|
envp_id: envelope.id,
|
|
22201
22203
|
expected_corr_id: tracked.originalEnvelope.corrId,
|
|
22202
22204
|
actual_corr_id: envelope.corrId,
|
|
@@ -22221,7 +22223,7 @@
|
|
|
22221
22223
|
for (const handler of this.eventHandlers) {
|
|
22222
22224
|
await handler.onEnvelopeAcked?.(tracked);
|
|
22223
22225
|
}
|
|
22224
|
-
logger$
|
|
22226
|
+
logger$17.debug('tracker_envelope_acked', {
|
|
22225
22227
|
envp_id: tracked.originalEnvelope.id,
|
|
22226
22228
|
});
|
|
22227
22229
|
}
|
|
@@ -22238,13 +22240,13 @@
|
|
|
22238
22240
|
const outbox = this.ensureOutbox();
|
|
22239
22241
|
const tracked = await outbox.get(envelope.frame.refId);
|
|
22240
22242
|
if (!tracked) {
|
|
22241
|
-
logger$
|
|
22243
|
+
logger$17.debug('tracker_nack_for_unknown_envelope', {
|
|
22242
22244
|
envp_id: envelope.id,
|
|
22243
22245
|
});
|
|
22244
22246
|
return;
|
|
22245
22247
|
}
|
|
22246
22248
|
if (tracked.originalEnvelope.corrId !== envelope.corrId) {
|
|
22247
|
-
logger$
|
|
22249
|
+
logger$17.debug('tracker_nack_corr_id_mismatch', {
|
|
22248
22250
|
envp_id: envelope.id,
|
|
22249
22251
|
expected_corr_id: tracked.originalEnvelope.corrId,
|
|
22250
22252
|
actual_corr_id: envelope.corrId,
|
|
@@ -22286,7 +22288,7 @@
|
|
|
22286
22288
|
for (const handler of this.eventHandlers) {
|
|
22287
22289
|
await handler.onEnvelopeNacked?.(tracked, ackFrame.reason ?? null);
|
|
22288
22290
|
}
|
|
22289
|
-
logger$
|
|
22291
|
+
logger$17.debug('tracker_envelope_nacked', {
|
|
22290
22292
|
envp_id: tracked.originalEnvelope.id,
|
|
22291
22293
|
reason: ackFrame.reason,
|
|
22292
22294
|
});
|
|
@@ -22333,7 +22335,7 @@
|
|
|
22333
22335
|
for (const handler of this.eventHandlers) {
|
|
22334
22336
|
await handler.onEnvelopeReplied?.(trackedEnvelope, envelope);
|
|
22335
22337
|
}
|
|
22336
|
-
logger$
|
|
22338
|
+
logger$17.debug('tracked_envelope_replied', {
|
|
22337
22339
|
envp_id: trackedEnvelope.originalEnvelope.id,
|
|
22338
22340
|
corr_id: envelope.corrId,
|
|
22339
22341
|
});
|
|
@@ -22407,7 +22409,7 @@
|
|
|
22407
22409
|
async addToInboxDlq(trackedEnvelope, reason = null) {
|
|
22408
22410
|
const dlq = this.inboxDlq;
|
|
22409
22411
|
if (!dlq) {
|
|
22410
|
-
logger$
|
|
22412
|
+
logger$17.error('dlq_not_initialized', {
|
|
22411
22413
|
envp_id: trackedEnvelope.originalEnvelope.id,
|
|
22412
22414
|
});
|
|
22413
22415
|
return;
|
|
@@ -22422,7 +22424,7 @@
|
|
|
22422
22424
|
const deadLetteredAt = Date.now();
|
|
22423
22425
|
setMetaWithLegacy(trackedEnvelope.meta, 'deadLetteredAtMs', 'dead_lettered_at_ms', deadLetteredAt);
|
|
22424
22426
|
await dlq.set(trackedEnvelope.originalEnvelope.id, trackedEnvelope);
|
|
22425
|
-
logger$
|
|
22427
|
+
logger$17.warning('envelope_moved_to_dlq', {
|
|
22426
22428
|
envp_id: trackedEnvelope.originalEnvelope.id,
|
|
22427
22429
|
service_name: trackedEnvelope.serviceName,
|
|
22428
22430
|
});
|
|
@@ -22451,7 +22453,7 @@
|
|
|
22451
22453
|
const toDelete = Object.entries(items).filter(([, value]) => predicate ? predicate(value) : true);
|
|
22452
22454
|
await Promise.all(toDelete.map(([key]) => dlq.delete(key)));
|
|
22453
22455
|
if (toDelete.length) {
|
|
22454
|
-
logger$
|
|
22456
|
+
logger$17.debug('dlq_purged', { count: toDelete.length });
|
|
22455
22457
|
}
|
|
22456
22458
|
return toDelete.length;
|
|
22457
22459
|
}
|
|
@@ -22504,11 +22506,11 @@
|
|
|
22504
22506
|
}
|
|
22505
22507
|
this.futuresSweeper = null;
|
|
22506
22508
|
}
|
|
22507
|
-
logger$
|
|
22509
|
+
logger$17.debug('tracker_cleanup_completed');
|
|
22508
22510
|
}
|
|
22509
22511
|
async recoverPending() {
|
|
22510
22512
|
const pending = await this.listPending();
|
|
22511
|
-
logger$
|
|
22513
|
+
logger$17.debug('tracker_recovering_pending', { count: pending.length });
|
|
22512
22514
|
await this.lock.runExclusive(async () => {
|
|
22513
22515
|
for (const tracked of pending) {
|
|
22514
22516
|
if (tracked.expectedResponseType & FameResponseType.ACK) {
|
|
@@ -22534,7 +22536,7 @@
|
|
|
22534
22536
|
for (const tracked of pending) {
|
|
22535
22537
|
await this.scheduleTimer(tracked, null, null);
|
|
22536
22538
|
}
|
|
22537
|
-
logger$
|
|
22539
|
+
logger$17.debug('tracker_recovery_completed', { count: pending.length });
|
|
22538
22540
|
}
|
|
22539
22541
|
ensureOutbox() {
|
|
22540
22542
|
if (!this.outbox) {
|
|
@@ -22549,7 +22551,7 @@
|
|
|
22549
22551
|
return this.inbox;
|
|
22550
22552
|
}
|
|
22551
22553
|
async waitForPendingAcks() {
|
|
22552
|
-
logger$
|
|
22554
|
+
logger$17.debug('tracker_node_preparing_to_stop_waiting_for_pending_acks');
|
|
22553
22555
|
const outbox = this.outbox;
|
|
22554
22556
|
if (!outbox) {
|
|
22555
22557
|
return;
|
|
@@ -22561,7 +22563,7 @@
|
|
|
22561
22563
|
continue;
|
|
22562
22564
|
}
|
|
22563
22565
|
if (!future.done) {
|
|
22564
|
-
logger$
|
|
22566
|
+
logger$17.debug('tracker_pending_ack_future_detected', {
|
|
22565
22567
|
envelope_id: envelopeId,
|
|
22566
22568
|
});
|
|
22567
22569
|
pending.push({ envelopeId, future });
|
|
@@ -22569,10 +22571,10 @@
|
|
|
22569
22571
|
}
|
|
22570
22572
|
});
|
|
22571
22573
|
if (!pending.length) {
|
|
22572
|
-
logger$
|
|
22574
|
+
logger$17.debug('tracker_no_pending_acks_to_wait_for');
|
|
22573
22575
|
return;
|
|
22574
22576
|
}
|
|
22575
|
-
logger$
|
|
22577
|
+
logger$17.debug('tracker_waiting_for_pending_acks', { count: pending.length });
|
|
22576
22578
|
for (const entry of pending) {
|
|
22577
22579
|
if (!entry) {
|
|
22578
22580
|
continue;
|
|
@@ -22589,19 +22591,19 @@
|
|
|
22589
22591
|
}
|
|
22590
22592
|
try {
|
|
22591
22593
|
await this.awaitWithTimeout(entry.future.promise, remainingMs);
|
|
22592
|
-
logger$
|
|
22594
|
+
logger$17.debug('tracker_received_ack', {
|
|
22593
22595
|
envelope_id: entry.envelopeId,
|
|
22594
22596
|
});
|
|
22595
22597
|
await outbox.delete(entry.envelopeId);
|
|
22596
22598
|
}
|
|
22597
22599
|
catch (error) {
|
|
22598
22600
|
if (error instanceof Error && error.name === 'TimeoutError') {
|
|
22599
|
-
logger$
|
|
22601
|
+
logger$17.debug('tracker_ack_timeout_expired', {
|
|
22600
22602
|
envelope_id: entry.envelopeId,
|
|
22601
22603
|
});
|
|
22602
22604
|
}
|
|
22603
22605
|
else {
|
|
22604
|
-
logger$
|
|
22606
|
+
logger$17.debug('tracker_ack_wait_error', {
|
|
22605
22607
|
envelope_id: entry.envelopeId,
|
|
22606
22608
|
error: error instanceof Error ? error.message : String(error),
|
|
22607
22609
|
});
|
|
@@ -22609,13 +22611,13 @@
|
|
|
22609
22611
|
}
|
|
22610
22612
|
}
|
|
22611
22613
|
catch (error) {
|
|
22612
|
-
logger$
|
|
22614
|
+
logger$17.error('tracker_error_waiting_for_ack', {
|
|
22613
22615
|
envelope_id: entry.envelopeId,
|
|
22614
22616
|
error: error instanceof Error ? error.message : String(error),
|
|
22615
22617
|
});
|
|
22616
22618
|
}
|
|
22617
22619
|
}
|
|
22618
|
-
logger$
|
|
22620
|
+
logger$17.debug('tracker_finished_waiting_for_pending_acks');
|
|
22619
22621
|
}
|
|
22620
22622
|
async waitForPendingAckDispatches() {
|
|
22621
22623
|
while (this.pendingAckDispatches.size > 0) {
|
|
@@ -22673,7 +22675,7 @@
|
|
|
22673
22675
|
for (const handler of this.eventHandlers) {
|
|
22674
22676
|
await handler.onEnvelopeTimeout?.(currentTracked);
|
|
22675
22677
|
}
|
|
22676
|
-
logger$
|
|
22678
|
+
logger$17.debug('tracker_envelope_timed_out', {
|
|
22677
22679
|
envp_id: tracked.originalEnvelope.id,
|
|
22678
22680
|
});
|
|
22679
22681
|
return;
|
|
@@ -22686,7 +22688,7 @@
|
|
|
22686
22688
|
currentTracked.timeoutAtMs = nextTimeoutAt;
|
|
22687
22689
|
await outbox.set(tracked.originalEnvelope.id, currentTracked);
|
|
22688
22690
|
await this.scheduleTimer(currentTracked, retryPolicy, retryHandler);
|
|
22689
|
-
logger$
|
|
22691
|
+
logger$17.debug('tracker_retry_deferred_during_shutdown', {
|
|
22690
22692
|
envp_id: tracked.originalEnvelope.id,
|
|
22691
22693
|
defer_ms: shutdownDeferMs,
|
|
22692
22694
|
});
|
|
@@ -22709,7 +22711,7 @@
|
|
|
22709
22711
|
});
|
|
22710
22712
|
}
|
|
22711
22713
|
await this.scheduleTimer(currentTracked, retryPolicy, retryHandler);
|
|
22712
|
-
logger$
|
|
22714
|
+
logger$17.debug('envelope_delivery_retry_scheduled', {
|
|
22713
22715
|
envp_id: tracked.originalEnvelope.id,
|
|
22714
22716
|
attempt: currentTracked.attempt,
|
|
22715
22717
|
max_retries: retryPolicy.maxRetries,
|
|
@@ -22721,7 +22723,7 @@
|
|
|
22721
22723
|
currentTracked.timeoutAtMs = currentTracked.overallTimeoutAtMs;
|
|
22722
22724
|
await outbox.set(tracked.originalEnvelope.id, currentTracked);
|
|
22723
22725
|
await this.scheduleTimer(currentTracked, retryPolicy, retryHandler);
|
|
22724
|
-
logger$
|
|
22726
|
+
logger$17.debug('envelope_retries_exhausted_waiting_until_overall_timeout', {
|
|
22725
22727
|
envp_id: tracked.originalEnvelope.id,
|
|
22726
22728
|
attempt: currentTracked.attempt,
|
|
22727
22729
|
overall_timeout_at_ms: currentTracked.overallTimeoutAtMs,
|
|
@@ -22741,7 +22743,7 @@
|
|
|
22741
22743
|
for (const handler of this.eventHandlers) {
|
|
22742
22744
|
await handler.onEnvelopeTimeout?.(currentTracked);
|
|
22743
22745
|
}
|
|
22744
|
-
logger$
|
|
22746
|
+
logger$17.debug('tracker_envelope_timed_out', {
|
|
22745
22747
|
envp_id: tracked.originalEnvelope.id,
|
|
22746
22748
|
});
|
|
22747
22749
|
}
|
|
@@ -22749,7 +22751,7 @@
|
|
|
22749
22751
|
if (error instanceof TaskCancelledError) {
|
|
22750
22752
|
return;
|
|
22751
22753
|
}
|
|
22752
|
-
logger$
|
|
22754
|
+
logger$17.error('tracker_timer_error', {
|
|
22753
22755
|
envp_id: tracked.originalEnvelope.id,
|
|
22754
22756
|
error: error instanceof Error ? error.message : String(error),
|
|
22755
22757
|
});
|
|
@@ -22804,7 +22806,7 @@
|
|
|
22804
22806
|
if (timeoutSeconds !== null) {
|
|
22805
22807
|
return await this.awaitWithTimeout(future.promise, timeoutSeconds);
|
|
22806
22808
|
}
|
|
22807
|
-
logger$
|
|
22809
|
+
logger$17.debug('await_envelope_no_timeout_wait', {
|
|
22808
22810
|
envelope_id: envelopeId,
|
|
22809
22811
|
});
|
|
22810
22812
|
return await future.promise;
|
|
@@ -22813,7 +22815,7 @@
|
|
|
22813
22815
|
if (error instanceof Error && error.name !== 'TimeoutError') {
|
|
22814
22816
|
throw error;
|
|
22815
22817
|
}
|
|
22816
|
-
logger$
|
|
22818
|
+
logger$17.error('await_envelope_timeout_error', {
|
|
22817
22819
|
envelope_id: envelopeId,
|
|
22818
22820
|
timeout_ms: timeoutSeconds,
|
|
22819
22821
|
future_done: false,
|
|
@@ -22974,7 +22976,7 @@
|
|
|
22974
22976
|
this.replyDoneSince.delete(envId);
|
|
22975
22977
|
}
|
|
22976
22978
|
});
|
|
22977
|
-
logger$
|
|
22979
|
+
logger$17.debug('tracker_swept_completed_futures', {
|
|
22978
22980
|
ack_removed: toRemoveAck.length,
|
|
22979
22981
|
reply_removed: toRemoveReply.length,
|
|
22980
22982
|
grace_secs: this.futGcGraceSecs,
|
|
@@ -22988,7 +22990,7 @@
|
|
|
22988
22990
|
if (error instanceof Error && error.name === 'TimeoutError') {
|
|
22989
22991
|
continue;
|
|
22990
22992
|
}
|
|
22991
|
-
logger$
|
|
22993
|
+
logger$17.error('tracker_sweeper_error', {
|
|
22992
22994
|
error: error instanceof Error ? error.message : String(error),
|
|
22993
22995
|
});
|
|
22994
22996
|
}
|
|
@@ -23019,14 +23021,14 @@
|
|
|
23019
23021
|
}
|
|
23020
23022
|
const node = this.node;
|
|
23021
23023
|
if (!envelope.replyTo) {
|
|
23022
|
-
logger$
|
|
23024
|
+
logger$17.error('cannot_send_ack_no_reply_to', { envp_id: envelope.id });
|
|
23023
23025
|
return;
|
|
23024
23026
|
}
|
|
23025
23027
|
if (!envelope.corrId) {
|
|
23026
|
-
logger$
|
|
23028
|
+
logger$17.error('cannot_send_ack_no_corr_id', { envp_id: envelope.id });
|
|
23027
23029
|
return;
|
|
23028
23030
|
}
|
|
23029
|
-
logger$
|
|
23031
|
+
logger$17.debug('tracker_sending_ack', {
|
|
23030
23032
|
envp_id: envelope.id,
|
|
23031
23033
|
ref_id: envelope.id,
|
|
23032
23034
|
to: envelope.replyTo,
|
|
@@ -23046,7 +23048,7 @@
|
|
|
23046
23048
|
.send(ackEnvelope)
|
|
23047
23049
|
.then(() => undefined)
|
|
23048
23050
|
.catch((error) => {
|
|
23049
|
-
logger$
|
|
23051
|
+
logger$17.error('tracker_ack_dispatch_failed', {
|
|
23050
23052
|
envp_id: envelope.id,
|
|
23051
23053
|
error: error instanceof Error ? error.message : String(error),
|
|
23052
23054
|
});
|
|
@@ -23132,7 +23134,7 @@
|
|
|
23132
23134
|
}
|
|
23133
23135
|
}
|
|
23134
23136
|
|
|
23135
|
-
const logger$
|
|
23137
|
+
const logger$16 = getLogger('naylence.fame.node.root_session_manager');
|
|
23136
23138
|
function resolveOption$1(options, primary, ...aliases) {
|
|
23137
23139
|
const record = options;
|
|
23138
23140
|
const primaryKey = primary;
|
|
@@ -23213,7 +23215,7 @@
|
|
|
23213
23215
|
this.onAdmissionFailed =
|
|
23214
23216
|
typeof onAdmissionFailed === 'function' ? onAdmissionFailed : undefined;
|
|
23215
23217
|
this.enableContinuousRefresh = enableContinuousRefresh ?? true;
|
|
23216
|
-
logger$
|
|
23218
|
+
logger$16.debug('created_root_session_manager');
|
|
23217
23219
|
}
|
|
23218
23220
|
get isReady() {
|
|
23219
23221
|
return this.readyEvent.isSet();
|
|
@@ -23238,7 +23240,7 @@
|
|
|
23238
23240
|
if (this.admissionTask) {
|
|
23239
23241
|
return;
|
|
23240
23242
|
}
|
|
23241
|
-
logger$
|
|
23243
|
+
logger$16.debug('root_session_manager_starting');
|
|
23242
23244
|
this.stopEvent.clear();
|
|
23243
23245
|
this.readyEvent.clear();
|
|
23244
23246
|
const taskName = `root-admission-${this.admissionEpoch}`;
|
|
@@ -23258,10 +23260,10 @@
|
|
|
23258
23260
|
await this.admissionTask.promise;
|
|
23259
23261
|
throw new FameConnectError('Root session manager failed to become ready');
|
|
23260
23262
|
}
|
|
23261
|
-
logger$
|
|
23263
|
+
logger$16.debug('root_session_manager_started');
|
|
23262
23264
|
}
|
|
23263
23265
|
async stop() {
|
|
23264
|
-
logger$
|
|
23266
|
+
logger$16.debug('root_session_manager_stopping');
|
|
23265
23267
|
this.stopEvent.set();
|
|
23266
23268
|
if (this.admissionTask) {
|
|
23267
23269
|
this.admissionTask.cancel();
|
|
@@ -23273,7 +23275,7 @@
|
|
|
23273
23275
|
await this.consumeTask(this.expiryGuardTask);
|
|
23274
23276
|
this.expiryGuardTask = null;
|
|
23275
23277
|
}
|
|
23276
|
-
logger$
|
|
23278
|
+
logger$16.debug('root_session_manager_stopped');
|
|
23277
23279
|
}
|
|
23278
23280
|
async awaitReady(timeoutMs) {
|
|
23279
23281
|
if (this.isReady) {
|
|
@@ -23314,12 +23316,12 @@
|
|
|
23314
23316
|
await this.onEpochChange(epoch);
|
|
23315
23317
|
}
|
|
23316
23318
|
else {
|
|
23317
|
-
logger$
|
|
23319
|
+
logger$16.debug('epoch_change_ignored_no_handler', { epoch });
|
|
23318
23320
|
}
|
|
23319
23321
|
}
|
|
23320
23322
|
static createForRootSentinel(node, admissionClient, requestedLogicals = [], enableContinuousRefresh = true, onEpochChange) {
|
|
23321
23323
|
const handleWelcome = async (frame) => {
|
|
23322
|
-
logger$
|
|
23324
|
+
logger$16.info('root_admission_successful', {
|
|
23323
23325
|
system_id: frame.systemId,
|
|
23324
23326
|
assigned_path: frame.assignedPath ?? null,
|
|
23325
23327
|
accepted_logicals: frame.acceptedLogicals ?? [],
|
|
@@ -23330,12 +23332,12 @@
|
|
|
23330
23332
|
? grant.purpose
|
|
23331
23333
|
: undefined;
|
|
23332
23334
|
if (purpose) {
|
|
23333
|
-
logger$
|
|
23335
|
+
logger$16.debug('received_admission_grant', { purpose });
|
|
23334
23336
|
}
|
|
23335
23337
|
}
|
|
23336
23338
|
};
|
|
23337
23339
|
const handleFailure = async (error) => {
|
|
23338
|
-
logger$
|
|
23340
|
+
logger$16.error('root_admission_failed_permanently', {
|
|
23339
23341
|
error: error.message,
|
|
23340
23342
|
});
|
|
23341
23343
|
};
|
|
@@ -23364,10 +23366,10 @@
|
|
|
23364
23366
|
this.readyEvent.set();
|
|
23365
23367
|
}
|
|
23366
23368
|
if (this.hadSuccessfulAdmission) {
|
|
23367
|
-
logger$
|
|
23369
|
+
logger$16.debug('root_admission_refreshed');
|
|
23368
23370
|
}
|
|
23369
23371
|
else {
|
|
23370
|
-
logger$
|
|
23372
|
+
logger$16.debug('root_admission_completed');
|
|
23371
23373
|
}
|
|
23372
23374
|
this.hadSuccessfulAdmission = true;
|
|
23373
23375
|
delay = RootSessionManager.BACKOFF_INITIAL;
|
|
@@ -23376,7 +23378,7 @@
|
|
|
23376
23378
|
await this.startExpiryGuard(welcomeFrame);
|
|
23377
23379
|
const expiryTriggered = await this.waitForExpiryOrStop();
|
|
23378
23380
|
if (expiryTriggered && !this.stopEvent.isSet()) {
|
|
23379
|
-
logger$
|
|
23381
|
+
logger$16.debug('performing_scheduled_re_admission');
|
|
23380
23382
|
continue;
|
|
23381
23383
|
}
|
|
23382
23384
|
}
|
|
@@ -23388,7 +23390,7 @@
|
|
|
23388
23390
|
}
|
|
23389
23391
|
const errorObject = error instanceof Error ? error : new Error(String(error));
|
|
23390
23392
|
const willRetry = attempts < RootSessionManager.RETRY_MAX_ATTEMPTS;
|
|
23391
|
-
logger$
|
|
23393
|
+
logger$16.warning('root_admission_failed', {
|
|
23392
23394
|
error: errorObject.message,
|
|
23393
23395
|
attempt: attempts,
|
|
23394
23396
|
will_retry: willRetry,
|
|
@@ -23406,7 +23408,7 @@
|
|
|
23406
23408
|
}
|
|
23407
23409
|
}
|
|
23408
23410
|
if (attempts >= RootSessionManager.RETRY_MAX_ATTEMPTS) {
|
|
23409
|
-
logger$
|
|
23411
|
+
logger$16.error('root_admission_max_attempts_exceeded', {
|
|
23410
23412
|
max_attempts: RootSessionManager.RETRY_MAX_ATTEMPTS,
|
|
23411
23413
|
});
|
|
23412
23414
|
}
|
|
@@ -23483,7 +23485,7 @@
|
|
|
23483
23485
|
}
|
|
23484
23486
|
async expiryGuard(welcomeFrame, signal) {
|
|
23485
23487
|
if (!welcomeFrame.expiresAt) {
|
|
23486
|
-
logger$
|
|
23488
|
+
logger$16.debug('no_admission_expiry_configured');
|
|
23487
23489
|
await Promise.race([this.stopEvent.wait(), this.waitForAbort(signal)]);
|
|
23488
23490
|
return;
|
|
23489
23491
|
}
|
|
@@ -23492,7 +23494,7 @@
|
|
|
23492
23494
|
let delaySeconds = (expiresAt.getTime() - now.getTime()) / 1000 -
|
|
23493
23495
|
RootSessionManager.JWT_REFRESH_SAFETY;
|
|
23494
23496
|
delaySeconds = Math.max(delaySeconds, 0);
|
|
23495
|
-
logger$
|
|
23497
|
+
logger$16.debug('admission_expiry_guard_started', {
|
|
23496
23498
|
welcome_expires_at: expiresAt.toISOString(),
|
|
23497
23499
|
delay_seconds: delaySeconds,
|
|
23498
23500
|
refresh_safety_seconds: RootSessionManager.JWT_REFRESH_SAFETY,
|
|
@@ -23501,7 +23503,7 @@
|
|
|
23501
23503
|
if (this.stopEvent.isSet() || signal?.aborted) {
|
|
23502
23504
|
return;
|
|
23503
23505
|
}
|
|
23504
|
-
logger$
|
|
23506
|
+
logger$16.debug('admission_expiry_triggered_refresh', {
|
|
23505
23507
|
expires_at: expiresAt.toISOString(),
|
|
23506
23508
|
current_time: new Date().toISOString(),
|
|
23507
23509
|
seconds_before_expiry: RootSessionManager.JWT_REFRESH_SAFETY,
|
|
@@ -23516,7 +23518,7 @@
|
|
|
23516
23518
|
return;
|
|
23517
23519
|
}
|
|
23518
23520
|
const errorObject = error instanceof Error ? error : new Error(String(error));
|
|
23519
|
-
logger$
|
|
23521
|
+
logger$16.debug('background_task_error', {
|
|
23520
23522
|
task_name: task.name,
|
|
23521
23523
|
error: errorObject.message,
|
|
23522
23524
|
});
|
|
@@ -23557,7 +23559,7 @@
|
|
|
23557
23559
|
* Concrete implementations must define supported grant types and provide grant-to-connector
|
|
23558
23560
|
* conversion logic.
|
|
23559
23561
|
*/
|
|
23560
|
-
const logger$
|
|
23562
|
+
const logger$15 = getLogger('naylence.fame.connector.connector_factory');
|
|
23561
23563
|
const CONNECTOR_FACTORY_BASE_TYPE = 'ConnectorFactory';
|
|
23562
23564
|
/**
|
|
23563
23565
|
* Abstract base class for connector factories
|
|
@@ -23593,7 +23595,7 @@
|
|
|
23593
23595
|
}
|
|
23594
23596
|
}
|
|
23595
23597
|
catch (error) {
|
|
23596
|
-
logger$
|
|
23598
|
+
logger$15.warning(`Failed to evaluate grant with factory ${factoryInfo.constructor.name}: ${error}`);
|
|
23597
23599
|
continue;
|
|
23598
23600
|
}
|
|
23599
23601
|
}
|
|
@@ -23636,7 +23638,7 @@
|
|
|
23636
23638
|
}
|
|
23637
23639
|
}
|
|
23638
23640
|
catch (error) {
|
|
23639
|
-
logger$
|
|
23641
|
+
logger$15.warning(`Failed to create connector config from grant: ${error}`);
|
|
23640
23642
|
continue;
|
|
23641
23643
|
}
|
|
23642
23644
|
}
|
|
@@ -23703,20 +23705,20 @@
|
|
|
23703
23705
|
return existing;
|
|
23704
23706
|
}
|
|
23705
23707
|
if (existing && !this.isGrantAware(existing)) {
|
|
23706
|
-
logger$
|
|
23708
|
+
logger$15.warning(`Factory ${factoryInfo.constructor.name} is registered under ${CONNECTOR_FACTORY_BASE_TYPE} but is missing grant conversion APIs; skipping.`);
|
|
23707
23709
|
return null;
|
|
23708
23710
|
}
|
|
23709
23711
|
try {
|
|
23710
23712
|
const instance = new factoryInfo.constructor();
|
|
23711
23713
|
if (!this.isGrantAware(instance)) {
|
|
23712
|
-
logger$
|
|
23714
|
+
logger$15.warning(`Factory ${factoryInfo.constructor.name} does not implement grant conversion APIs required by ${CONNECTOR_FACTORY_BASE_TYPE}; skipping.`);
|
|
23713
23715
|
return null;
|
|
23714
23716
|
}
|
|
23715
23717
|
factoryInfo.instance = instance;
|
|
23716
23718
|
return instance;
|
|
23717
23719
|
}
|
|
23718
23720
|
catch (error) {
|
|
23719
|
-
logger$
|
|
23721
|
+
logger$15.warning(`Failed to instantiate factory ${factoryInfo.constructor.name} while resolving grant conversion APIs: ${error}`);
|
|
23720
23722
|
return null;
|
|
23721
23723
|
}
|
|
23722
23724
|
}
|
|
@@ -23819,7 +23821,7 @@
|
|
|
23819
23821
|
this.name = 'TaskCancellationError';
|
|
23820
23822
|
}
|
|
23821
23823
|
}
|
|
23822
|
-
const logger$
|
|
23824
|
+
const logger$14 = getLogger('naylence.fame.connector.base_async_connector');
|
|
23823
23825
|
// Environment variables
|
|
23824
23826
|
const ENV_VAR_FAME_FLOW_CONTROL = 'FAME_FLOW_CONTROL';
|
|
23825
23827
|
const FLOW_CONTROL_ENABLED = typeof process !== 'undefined' && process?.env
|
|
@@ -23902,7 +23904,7 @@
|
|
|
23902
23904
|
if (this._state !== newState) {
|
|
23903
23905
|
const oldState = this._state;
|
|
23904
23906
|
this._state = newState;
|
|
23905
|
-
logger$
|
|
23907
|
+
logger$14.debug('connector_state_transition', {
|
|
23906
23908
|
connector_id: this._connectorFlowId,
|
|
23907
23909
|
old_state: oldState,
|
|
23908
23910
|
new_state: newState,
|
|
@@ -23941,12 +23943,12 @@
|
|
|
23941
23943
|
* Stop the connector gracefully
|
|
23942
23944
|
*/
|
|
23943
23945
|
async stop() {
|
|
23944
|
-
logger$
|
|
23946
|
+
logger$14.debug('stopping_connector', {
|
|
23945
23947
|
current_state: this._state,
|
|
23946
23948
|
connector_id: this._connectorFlowId,
|
|
23947
23949
|
});
|
|
23948
23950
|
if (!ConnectorStateUtils.canStop(this._state)) {
|
|
23949
|
-
logger$
|
|
23951
|
+
logger$14.debug('connector_stop_already_stopped', {
|
|
23950
23952
|
current_state: this._state,
|
|
23951
23953
|
connector_id: this._connectorFlowId,
|
|
23952
23954
|
});
|
|
@@ -23957,7 +23959,7 @@
|
|
|
23957
23959
|
if (this._lastError) {
|
|
23958
23960
|
throw this._lastError;
|
|
23959
23961
|
}
|
|
23960
|
-
logger$
|
|
23962
|
+
logger$14.debug('connector_stopped', {
|
|
23961
23963
|
current_state: this._state,
|
|
23962
23964
|
connector_id: this._connectorFlowId,
|
|
23963
23965
|
});
|
|
@@ -23966,19 +23968,19 @@
|
|
|
23966
23968
|
* Pause the connector (suspends heartbeat and housekeeping, but keeps connection alive)
|
|
23967
23969
|
*/
|
|
23968
23970
|
async pause() {
|
|
23969
|
-
logger$
|
|
23971
|
+
logger$14.debug('pausing_connector', {
|
|
23970
23972
|
current_state: this._state,
|
|
23971
23973
|
connector_id: this._connectorFlowId,
|
|
23972
23974
|
});
|
|
23973
23975
|
if (this._state !== ConnectorState.STARTED) {
|
|
23974
|
-
logger$
|
|
23976
|
+
logger$14.debug('connector_pause_invalid_state', {
|
|
23975
23977
|
current_state: this._state,
|
|
23976
23978
|
connector_id: this._connectorFlowId,
|
|
23977
23979
|
});
|
|
23978
23980
|
return;
|
|
23979
23981
|
}
|
|
23980
23982
|
this._setState(ConnectorState.PAUSED);
|
|
23981
|
-
logger$
|
|
23983
|
+
logger$14.debug('connector_paused', {
|
|
23982
23984
|
current_state: this._state,
|
|
23983
23985
|
connector_id: this._connectorFlowId,
|
|
23984
23986
|
});
|
|
@@ -23987,19 +23989,19 @@
|
|
|
23987
23989
|
* Resume the connector from paused state
|
|
23988
23990
|
*/
|
|
23989
23991
|
async resume() {
|
|
23990
|
-
logger$
|
|
23992
|
+
logger$14.debug('resuming_connector', {
|
|
23991
23993
|
current_state: this._state,
|
|
23992
23994
|
connector_id: this._connectorFlowId,
|
|
23993
23995
|
});
|
|
23994
23996
|
if (this._state !== ConnectorState.PAUSED) {
|
|
23995
|
-
logger$
|
|
23997
|
+
logger$14.debug('connector_resume_invalid_state', {
|
|
23996
23998
|
current_state: this._state,
|
|
23997
23999
|
connector_id: this._connectorFlowId,
|
|
23998
24000
|
});
|
|
23999
24001
|
return;
|
|
24000
24002
|
}
|
|
24001
24003
|
this._setState(ConnectorState.STARTED);
|
|
24002
|
-
logger$
|
|
24004
|
+
logger$14.debug('connector_resumed', {
|
|
24003
24005
|
current_state: this._state,
|
|
24004
24006
|
connector_id: this._connectorFlowId,
|
|
24005
24007
|
});
|
|
@@ -24009,7 +24011,7 @@
|
|
|
24009
24011
|
*/
|
|
24010
24012
|
async close(code = 1000, reason = 'normal closure') {
|
|
24011
24013
|
if (!ConnectorStateUtils.canClose(this._state)) {
|
|
24012
|
-
logger$
|
|
24014
|
+
logger$14.warning('connector_close_invalid_state', {
|
|
24013
24015
|
current_state: this._state,
|
|
24014
24016
|
connector_id: this._connectorFlowId,
|
|
24015
24017
|
});
|
|
@@ -24090,7 +24092,7 @@
|
|
|
24090
24092
|
// Add to queue and notify send loop
|
|
24091
24093
|
this._sendQueue.push(raw);
|
|
24092
24094
|
// Log for debugging
|
|
24093
|
-
logger$
|
|
24095
|
+
logger$14.debug('send_envelope_queued', {
|
|
24094
24096
|
queue_length: this._sendQueue.length,
|
|
24095
24097
|
max_queue_size: this._maxQueueSize,
|
|
24096
24098
|
});
|
|
@@ -24139,14 +24141,14 @@
|
|
|
24139
24141
|
const item = this._sendQueue[0];
|
|
24140
24142
|
if (!item)
|
|
24141
24143
|
continue;
|
|
24142
|
-
logger$
|
|
24144
|
+
logger$14.debug('send_loop_processing_item', {
|
|
24143
24145
|
queue_length_before_send: this._sendQueue.length,
|
|
24144
24146
|
});
|
|
24145
24147
|
// Send through transport (this may block)
|
|
24146
24148
|
await this._transportSendBytes(item);
|
|
24147
24149
|
// Only remove from queue after successful send
|
|
24148
24150
|
this._sendQueue.shift();
|
|
24149
|
-
logger$
|
|
24151
|
+
logger$14.debug('send_loop_item_sent', {
|
|
24150
24152
|
queue_length_after_send: this._sendQueue.length,
|
|
24151
24153
|
});
|
|
24152
24154
|
}
|
|
@@ -24159,14 +24161,14 @@
|
|
|
24159
24161
|
}
|
|
24160
24162
|
else if (error instanceof TaskCancellationError) {
|
|
24161
24163
|
// Task cancellation is expected during shutdown - log as debug, not critical
|
|
24162
|
-
logger$
|
|
24164
|
+
logger$14.debug('send loop cancelled', {
|
|
24163
24165
|
connector: this.constructor.name,
|
|
24164
24166
|
reason: error.message,
|
|
24165
24167
|
});
|
|
24166
24168
|
// Don't re-throw - this is normal during shutdown
|
|
24167
24169
|
}
|
|
24168
24170
|
else {
|
|
24169
|
-
logger$
|
|
24171
|
+
logger$14.critical('unexpected exception in send loop', {
|
|
24170
24172
|
connector: this.constructor.name,
|
|
24171
24173
|
error: error instanceof Error ? error.message : String(error),
|
|
24172
24174
|
});
|
|
@@ -24207,7 +24209,7 @@
|
|
|
24207
24209
|
env = JSON.parse(jsonStr);
|
|
24208
24210
|
}
|
|
24209
24211
|
catch (error) {
|
|
24210
|
-
logger$
|
|
24212
|
+
logger$14.error('Invalid envelope', {
|
|
24211
24213
|
message: message.toString(),
|
|
24212
24214
|
error: error instanceof Error ? error.message : String(error),
|
|
24213
24215
|
});
|
|
@@ -24231,7 +24233,7 @@
|
|
|
24231
24233
|
};
|
|
24232
24234
|
await withEnvelopeContextAsync(envelopeContext, async () => {
|
|
24233
24235
|
const prettyEnvelope = prettyModel$1(env);
|
|
24234
|
-
logger$
|
|
24236
|
+
logger$14.trace('connector_received_envelope', {
|
|
24235
24237
|
envelope: env,
|
|
24236
24238
|
pretty: prettyEnvelope,
|
|
24237
24239
|
});
|
|
@@ -24260,7 +24262,7 @@
|
|
|
24260
24262
|
if (error instanceof TaskCancellationError) {
|
|
24261
24263
|
throw error;
|
|
24262
24264
|
}
|
|
24263
|
-
logger$
|
|
24265
|
+
logger$14.error('handler_failed', {
|
|
24264
24266
|
error: error instanceof Error ? error.message : String(error),
|
|
24265
24267
|
envelope_id: env.id ?? null,
|
|
24266
24268
|
trace_id: env.traceId ?? null,
|
|
@@ -24281,14 +24283,14 @@
|
|
|
24281
24283
|
}
|
|
24282
24284
|
else if (error instanceof TaskCancellationError) {
|
|
24283
24285
|
// Task cancellation is expected during shutdown - log as debug, not critical
|
|
24284
|
-
logger$
|
|
24286
|
+
logger$14.debug('receive loop cancelled', {
|
|
24285
24287
|
connector: this.constructor.name,
|
|
24286
24288
|
reason: error.message,
|
|
24287
24289
|
});
|
|
24288
24290
|
// Don't re-throw - this is normal during shutdown
|
|
24289
24291
|
}
|
|
24290
24292
|
else {
|
|
24291
|
-
logger$
|
|
24293
|
+
logger$14.critical('unexpected_error_in recv_loop', {
|
|
24292
24294
|
error: error instanceof Error ? error.message : String(error),
|
|
24293
24295
|
});
|
|
24294
24296
|
throw error;
|
|
@@ -24304,7 +24306,7 @@
|
|
|
24304
24306
|
async _maybeEmitCredit(flowId, traceId) {
|
|
24305
24307
|
const remainingCredits = this._flowCtrl.getCredits(flowId);
|
|
24306
24308
|
const needsRefill = this._flowCtrl.needsRefill(flowId);
|
|
24307
|
-
logger$
|
|
24309
|
+
logger$14.debug('maybe_emit_credit_check', {
|
|
24308
24310
|
connector_id: this._connectorFlowId,
|
|
24309
24311
|
flow_id: flowId,
|
|
24310
24312
|
trace_id: traceId ?? null,
|
|
@@ -24320,7 +24322,7 @@
|
|
|
24320
24322
|
}
|
|
24321
24323
|
const delta = this._initialWindow;
|
|
24322
24324
|
this._flowCtrl.addCredits(flowId, delta);
|
|
24323
|
-
logger$
|
|
24325
|
+
logger$14.debug('maybe_emit_credit_emit', {
|
|
24324
24326
|
connector_id: this._connectorFlowId,
|
|
24325
24327
|
flow_id: flowId,
|
|
24326
24328
|
trace_id: traceId ?? null,
|
|
@@ -24340,7 +24342,7 @@
|
|
|
24340
24342
|
});
|
|
24341
24343
|
try {
|
|
24342
24344
|
await this.send(ackEnv);
|
|
24343
|
-
logger$
|
|
24345
|
+
logger$14.debug('maybe_emit_credit_sent', {
|
|
24344
24346
|
connector_id: this._connectorFlowId,
|
|
24345
24347
|
flow_id: flowId,
|
|
24346
24348
|
trace_id: traceId ?? null,
|
|
@@ -24348,7 +24350,7 @@
|
|
|
24348
24350
|
});
|
|
24349
24351
|
}
|
|
24350
24352
|
catch (error) {
|
|
24351
|
-
logger$
|
|
24353
|
+
logger$14.error('maybe_emit_credit_send_failed', {
|
|
24352
24354
|
connector_id: this._connectorFlowId,
|
|
24353
24355
|
flow_id: flowId,
|
|
24354
24356
|
trace_id: traceId ?? null,
|
|
@@ -24373,13 +24375,13 @@
|
|
|
24373
24375
|
*/
|
|
24374
24376
|
async _shutdown(code, reason, gracePeriod, exc) {
|
|
24375
24377
|
if (this._closed) {
|
|
24376
|
-
logger$
|
|
24378
|
+
logger$14.debug('shutdown_already_closed', {
|
|
24377
24379
|
connector_id: this._connectorFlowId,
|
|
24378
24380
|
current_state: this._state,
|
|
24379
24381
|
});
|
|
24380
24382
|
return;
|
|
24381
24383
|
}
|
|
24382
|
-
logger$
|
|
24384
|
+
logger$14.debug('connector_shutdown_starting', {
|
|
24383
24385
|
connector_id: this._connectorFlowId,
|
|
24384
24386
|
connector_type: this.constructor.name,
|
|
24385
24387
|
code,
|
|
@@ -24409,19 +24411,19 @@
|
|
|
24409
24411
|
this._sendPromiseResolve = undefined;
|
|
24410
24412
|
}
|
|
24411
24413
|
// Close transport
|
|
24412
|
-
logger$
|
|
24414
|
+
logger$14.debug('connector_closing_transport', {
|
|
24413
24415
|
connector_id: this._connectorFlowId,
|
|
24414
24416
|
connector_type: this.constructor.name,
|
|
24415
24417
|
timestamp: new Date().toISOString(),
|
|
24416
24418
|
});
|
|
24417
24419
|
await this._transportClose(code, reason);
|
|
24418
|
-
logger$
|
|
24420
|
+
logger$14.debug('connector_transport_closed', {
|
|
24419
24421
|
connector_id: this._connectorFlowId,
|
|
24420
24422
|
connector_type: this.constructor.name,
|
|
24421
24423
|
timestamp: new Date().toISOString(),
|
|
24422
24424
|
});
|
|
24423
24425
|
// Shutdown spawned tasks
|
|
24424
|
-
logger$
|
|
24426
|
+
logger$14.debug('connector_shutting_down_tasks', {
|
|
24425
24427
|
connector_id: this._connectorFlowId,
|
|
24426
24428
|
connector_type: this.constructor.name,
|
|
24427
24429
|
grace_period_ms: effectiveGracePeriod * 1000,
|
|
@@ -24433,14 +24435,14 @@
|
|
|
24433
24435
|
gracePeriod: effectiveGracePeriod * 1000, // Convert to milliseconds
|
|
24434
24436
|
joinTimeout: this._shutdownJoinTimeout,
|
|
24435
24437
|
});
|
|
24436
|
-
logger$
|
|
24438
|
+
logger$14.debug('connector_tasks_shutdown_complete', {
|
|
24437
24439
|
connector_id: this._connectorFlowId,
|
|
24438
24440
|
connector_type: this.constructor.name,
|
|
24439
24441
|
timestamp: new Date().toISOString(),
|
|
24440
24442
|
});
|
|
24441
24443
|
}
|
|
24442
24444
|
catch (error) {
|
|
24443
|
-
logger$
|
|
24445
|
+
logger$14.warning('task_shutdown_error', {
|
|
24444
24446
|
connector_id: this._connectorFlowId,
|
|
24445
24447
|
error: error instanceof Error ? error.message : String(error),
|
|
24446
24448
|
});
|
|
@@ -24453,7 +24455,7 @@
|
|
|
24453
24455
|
if (this._closeResolver) {
|
|
24454
24456
|
this._closeResolver();
|
|
24455
24457
|
}
|
|
24456
|
-
logger$
|
|
24458
|
+
logger$14.debug('connector_shutdown_complete', {
|
|
24457
24459
|
connector_id: this._connectorFlowId,
|
|
24458
24460
|
connector_type: this.constructor.name,
|
|
24459
24461
|
final_state: this._state,
|
|
@@ -24529,7 +24531,7 @@
|
|
|
24529
24531
|
}
|
|
24530
24532
|
}
|
|
24531
24533
|
|
|
24532
|
-
const logger$
|
|
24534
|
+
const logger$13 = getLogger('naylence.fame.connector.broadcast_channel_connector');
|
|
24533
24535
|
const BROADCAST_CHANNEL_CONNECTOR_TYPE = 'broadcast-channel-connector';
|
|
24534
24536
|
const DEFAULT_CHANNEL$7 = 'naylence-fabric';
|
|
24535
24537
|
const DEFAULT_INBOX_CAPACITY$7 = 2048;
|
|
@@ -24618,7 +24620,7 @@
|
|
|
24618
24620
|
this.localNodeId = normalizedLocalNodeId;
|
|
24619
24621
|
this.targetNodeId = BroadcastChannelConnector.normalizeTargetNodeId(config.initialTargetNodeId);
|
|
24620
24622
|
this.channel = new BroadcastChannel(this.channelName);
|
|
24621
|
-
logger$
|
|
24623
|
+
logger$13.debug('broadcast_channel_connector_created', {
|
|
24622
24624
|
channel: this.channelName,
|
|
24623
24625
|
connector_id: this.connectorId,
|
|
24624
24626
|
local_node_id: this.localNodeId,
|
|
@@ -24630,7 +24632,7 @@
|
|
|
24630
24632
|
this.onMsg = (event) => {
|
|
24631
24633
|
// Guard: Don't process if listener was unregistered
|
|
24632
24634
|
if (!this.listenerRegistered) {
|
|
24633
|
-
logger$
|
|
24635
|
+
logger$13.warning('broadcast_channel_message_after_unregister', {
|
|
24634
24636
|
channel: this.channelName,
|
|
24635
24637
|
connector_id: this.connectorId,
|
|
24636
24638
|
timestamp: new Date().toISOString(),
|
|
@@ -24638,7 +24640,7 @@
|
|
|
24638
24640
|
return;
|
|
24639
24641
|
}
|
|
24640
24642
|
const message = event.data;
|
|
24641
|
-
logger$
|
|
24643
|
+
logger$13.debug('broadcast_channel_raw_event', {
|
|
24642
24644
|
channel: this.channelName,
|
|
24643
24645
|
connector_id: this.connectorId,
|
|
24644
24646
|
message_type: message && typeof message === 'object'
|
|
@@ -24654,7 +24656,7 @@
|
|
|
24654
24656
|
const busMessage = message;
|
|
24655
24657
|
const senderNodeId = BroadcastChannelConnector.normalizeNodeId(busMessage.senderNodeId);
|
|
24656
24658
|
if (!senderNodeId) {
|
|
24657
|
-
logger$
|
|
24659
|
+
logger$13.debug('broadcast_channel_message_rejected', {
|
|
24658
24660
|
channel: this.channelName,
|
|
24659
24661
|
connector_id: this.connectorId,
|
|
24660
24662
|
reason: 'missing_sender_node_id',
|
|
@@ -24662,7 +24664,7 @@
|
|
|
24662
24664
|
return;
|
|
24663
24665
|
}
|
|
24664
24666
|
if (senderNodeId === this.localNodeId) {
|
|
24665
|
-
logger$
|
|
24667
|
+
logger$13.debug('broadcast_channel_message_rejected', {
|
|
24666
24668
|
channel: this.channelName,
|
|
24667
24669
|
connector_id: this.connectorId,
|
|
24668
24670
|
reason: 'self_echo',
|
|
@@ -24676,14 +24678,14 @@
|
|
|
24676
24678
|
}
|
|
24677
24679
|
const payload = BroadcastChannelConnector.coercePayload(busMessage.payload);
|
|
24678
24680
|
if (!payload) {
|
|
24679
|
-
logger$
|
|
24681
|
+
logger$13.debug('broadcast_channel_payload_rejected', {
|
|
24680
24682
|
channel: this.channelName,
|
|
24681
24683
|
connector_id: this.connectorId,
|
|
24682
24684
|
reason: 'unrecognized_payload_type',
|
|
24683
24685
|
});
|
|
24684
24686
|
return;
|
|
24685
24687
|
}
|
|
24686
|
-
logger$
|
|
24688
|
+
logger$13.debug('broadcast_channel_message_received', {
|
|
24687
24689
|
channel: this.channelName,
|
|
24688
24690
|
sender_id: message?.senderId,
|
|
24689
24691
|
sender_node_id: senderNodeId,
|
|
@@ -24712,14 +24714,14 @@
|
|
|
24712
24714
|
}
|
|
24713
24715
|
catch (error) {
|
|
24714
24716
|
if (error instanceof QueueFullError) {
|
|
24715
|
-
logger$
|
|
24717
|
+
logger$13.warning('broadcast_channel_receive_queue_full', {
|
|
24716
24718
|
channel: this.channelName,
|
|
24717
24719
|
inbox_capacity: this.inboxCapacity,
|
|
24718
24720
|
inbox_remaining_capacity: this.inbox.remainingCapacity,
|
|
24719
24721
|
});
|
|
24720
24722
|
}
|
|
24721
24723
|
else {
|
|
24722
|
-
logger$
|
|
24724
|
+
logger$13.error('broadcast_channel_receive_error', {
|
|
24723
24725
|
channel: this.channelName,
|
|
24724
24726
|
error: error instanceof Error ? error.message : String(error),
|
|
24725
24727
|
});
|
|
@@ -24733,7 +24735,7 @@
|
|
|
24733
24735
|
// Setup visibility change monitoring
|
|
24734
24736
|
this.visibilityChangeHandler = () => {
|
|
24735
24737
|
const isHidden = document.hidden;
|
|
24736
|
-
logger$
|
|
24738
|
+
logger$13.debug('broadcast_channel_visibility_changed', {
|
|
24737
24739
|
channel: this.channelName,
|
|
24738
24740
|
connector_id: this.connectorId,
|
|
24739
24741
|
visibility: isHidden ? 'hidden' : 'visible',
|
|
@@ -24742,7 +24744,7 @@
|
|
|
24742
24744
|
// Pause/resume connector based on visibility
|
|
24743
24745
|
if (isHidden && this.state === ConnectorState.STARTED) {
|
|
24744
24746
|
this.pause().catch((err) => {
|
|
24745
|
-
logger$
|
|
24747
|
+
logger$13.warning('broadcast_channel_pause_failed', {
|
|
24746
24748
|
channel: this.channelName,
|
|
24747
24749
|
connector_id: this.connectorId,
|
|
24748
24750
|
error: err instanceof Error ? err.message : String(err),
|
|
@@ -24751,7 +24753,7 @@
|
|
|
24751
24753
|
}
|
|
24752
24754
|
else if (!isHidden && this.state === ConnectorState.PAUSED) {
|
|
24753
24755
|
this.resume().catch((err) => {
|
|
24754
|
-
logger$
|
|
24756
|
+
logger$13.warning('broadcast_channel_resume_failed', {
|
|
24755
24757
|
channel: this.channelName,
|
|
24756
24758
|
connector_id: this.connectorId,
|
|
24757
24759
|
error: err instanceof Error ? err.message : String(err),
|
|
@@ -24765,7 +24767,7 @@
|
|
|
24765
24767
|
// Track page lifecycle events to detect browser unload/discard
|
|
24766
24768
|
if (typeof window !== 'undefined') {
|
|
24767
24769
|
const lifecycleLogger = (event) => {
|
|
24768
|
-
logger$
|
|
24770
|
+
logger$13.debug('broadcast_channel_page_lifecycle', {
|
|
24769
24771
|
channel: this.channelName,
|
|
24770
24772
|
connector_id: this.connectorId,
|
|
24771
24773
|
event_type: event.type,
|
|
@@ -24781,7 +24783,7 @@
|
|
|
24781
24783
|
document.addEventListener('resume', lifecycleLogger);
|
|
24782
24784
|
}
|
|
24783
24785
|
// Log initial state with detailed visibility info
|
|
24784
|
-
logger$
|
|
24786
|
+
logger$13.debug('broadcast_channel_initial_visibility', {
|
|
24785
24787
|
channel: this.channelName,
|
|
24786
24788
|
connector_id: this.connectorId,
|
|
24787
24789
|
visibility: document.hidden ? 'hidden' : 'visible',
|
|
@@ -24813,14 +24815,14 @@
|
|
|
24813
24815
|
}
|
|
24814
24816
|
catch (error) {
|
|
24815
24817
|
if (error instanceof QueueFullError) {
|
|
24816
|
-
logger$
|
|
24818
|
+
logger$13.warning('broadcast_channel_push_queue_full', {
|
|
24817
24819
|
channel: this.channelName,
|
|
24818
24820
|
inbox_capacity: this.inboxCapacity,
|
|
24819
24821
|
inbox_remaining_capacity: this.inbox.remainingCapacity,
|
|
24820
24822
|
});
|
|
24821
24823
|
throw error;
|
|
24822
24824
|
}
|
|
24823
|
-
logger$
|
|
24825
|
+
logger$13.error('broadcast_channel_push_failed', {
|
|
24824
24826
|
channel: this.channelName,
|
|
24825
24827
|
error: error instanceof Error ? error.message : String(error),
|
|
24826
24828
|
});
|
|
@@ -24830,7 +24832,7 @@
|
|
|
24830
24832
|
async _transportSendBytes(data) {
|
|
24831
24833
|
ensureBroadcastEnvironment();
|
|
24832
24834
|
const targetNodeId = this.targetNodeId ?? '*';
|
|
24833
|
-
logger$
|
|
24835
|
+
logger$13.debug('broadcast_channel_message_sending', {
|
|
24834
24836
|
channel: this.channelName,
|
|
24835
24837
|
sender_id: this.connectorId,
|
|
24836
24838
|
sender_node_id: this.localNodeId,
|
|
@@ -24851,7 +24853,7 @@
|
|
|
24851
24853
|
return item;
|
|
24852
24854
|
}
|
|
24853
24855
|
async _transportClose(code, reason) {
|
|
24854
|
-
logger$
|
|
24856
|
+
logger$13.debug('broadcast_channel_transport_closing', {
|
|
24855
24857
|
channel: this.channelName,
|
|
24856
24858
|
connector_id: this.connectorId,
|
|
24857
24859
|
code,
|
|
@@ -24860,14 +24862,14 @@
|
|
|
24860
24862
|
timestamp: new Date().toISOString(),
|
|
24861
24863
|
});
|
|
24862
24864
|
if (this.listenerRegistered) {
|
|
24863
|
-
logger$
|
|
24865
|
+
logger$13.debug('broadcast_channel_removing_listener', {
|
|
24864
24866
|
channel: this.channelName,
|
|
24865
24867
|
connector_id: this.connectorId,
|
|
24866
24868
|
timestamp: new Date().toISOString(),
|
|
24867
24869
|
});
|
|
24868
24870
|
this.channel.removeEventListener('message', this.onMsg);
|
|
24869
24871
|
this.listenerRegistered = false;
|
|
24870
|
-
logger$
|
|
24872
|
+
logger$13.debug('broadcast_channel_listener_removed', {
|
|
24871
24873
|
channel: this.channelName,
|
|
24872
24874
|
connector_id: this.connectorId,
|
|
24873
24875
|
timestamp: new Date().toISOString(),
|
|
@@ -24880,13 +24882,13 @@
|
|
|
24880
24882
|
this.visibilityChangeListenerRegistered = false;
|
|
24881
24883
|
this.visibilityChangeHandler = undefined;
|
|
24882
24884
|
}
|
|
24883
|
-
logger$
|
|
24885
|
+
logger$13.debug('broadcast_channel_closing', {
|
|
24884
24886
|
channel: this.channelName,
|
|
24885
24887
|
connector_id: this.connectorId,
|
|
24886
24888
|
timestamp: new Date().toISOString(),
|
|
24887
24889
|
});
|
|
24888
24890
|
this.channel.close();
|
|
24889
|
-
logger$
|
|
24891
|
+
logger$13.debug('broadcast_channel_closed', {
|
|
24890
24892
|
channel: this.channelName,
|
|
24891
24893
|
connector_id: this.connectorId,
|
|
24892
24894
|
timestamp: new Date().toISOString(),
|
|
@@ -24910,7 +24912,7 @@
|
|
|
24910
24912
|
if (targetNodeId &&
|
|
24911
24913
|
targetNodeId !== '*' &&
|
|
24912
24914
|
targetNodeId !== this.localNodeId) {
|
|
24913
|
-
logger$
|
|
24915
|
+
logger$13.debug('broadcast_channel_message_rejected', {
|
|
24914
24916
|
channel: this.channelName,
|
|
24915
24917
|
connector_id: this.connectorId,
|
|
24916
24918
|
reason: 'wildcard_target_mismatch',
|
|
@@ -24926,7 +24928,7 @@
|
|
|
24926
24928
|
if (expectedSender &&
|
|
24927
24929
|
expectedSender !== '*' &&
|
|
24928
24930
|
senderNodeId !== expectedSender) {
|
|
24929
|
-
logger$
|
|
24931
|
+
logger$13.debug('broadcast_channel_message_rejected', {
|
|
24930
24932
|
channel: this.channelName,
|
|
24931
24933
|
connector_id: this.connectorId,
|
|
24932
24934
|
reason: 'unexpected_sender',
|
|
@@ -24939,7 +24941,7 @@
|
|
|
24939
24941
|
if (targetNodeId &&
|
|
24940
24942
|
targetNodeId !== '*' &&
|
|
24941
24943
|
targetNodeId !== this.localNodeId) {
|
|
24942
|
-
logger$
|
|
24944
|
+
logger$13.debug('broadcast_channel_message_rejected', {
|
|
24943
24945
|
channel: this.channelName,
|
|
24944
24946
|
connector_id: this.connectorId,
|
|
24945
24947
|
reason: 'unexpected_target',
|
|
@@ -24964,7 +24966,7 @@
|
|
|
24964
24966
|
return 'unknown';
|
|
24965
24967
|
}
|
|
24966
24968
|
logInboxSnapshot(event, extra = {}) {
|
|
24967
|
-
logger$
|
|
24969
|
+
logger$13.debug(event, {
|
|
24968
24970
|
channel: this.channelName,
|
|
24969
24971
|
connector_id: this.connectorId,
|
|
24970
24972
|
connector_state: this.state,
|
|
@@ -24980,7 +24982,7 @@
|
|
|
24980
24982
|
await super.start(inboundHandler);
|
|
24981
24983
|
// After transitioning to STARTED, check if tab is already hidden
|
|
24982
24984
|
if (typeof document !== 'undefined' && document.hidden) {
|
|
24983
|
-
logger$
|
|
24985
|
+
logger$13.debug('broadcast_channel_start_in_hidden_tab', {
|
|
24984
24986
|
channel: this.channelName,
|
|
24985
24987
|
connector_id: this.connectorId,
|
|
24986
24988
|
document_hidden: document.hidden,
|
|
@@ -24990,7 +24992,7 @@
|
|
|
24990
24992
|
});
|
|
24991
24993
|
// Immediately pause if tab is hidden at start time
|
|
24992
24994
|
await this.pause().catch((err) => {
|
|
24993
|
-
logger$
|
|
24995
|
+
logger$13.warning('broadcast_channel_initial_pause_failed', {
|
|
24994
24996
|
channel: this.channelName,
|
|
24995
24997
|
connector_id: this.connectorId,
|
|
24996
24998
|
error: err instanceof Error ? err.message : String(err),
|
|
@@ -25008,7 +25010,7 @@
|
|
|
25008
25010
|
return;
|
|
25009
25011
|
}
|
|
25010
25012
|
this.targetNodeId = normalized;
|
|
25011
|
-
logger$
|
|
25013
|
+
logger$13.debug('broadcast_channel_target_updated', {
|
|
25012
25014
|
channel: this.channelName,
|
|
25013
25015
|
connector_id: this.connectorId,
|
|
25014
25016
|
local_node_id: this.localNodeId,
|
|
@@ -25018,7 +25020,7 @@
|
|
|
25018
25020
|
}
|
|
25019
25021
|
setWildcardTarget() {
|
|
25020
25022
|
this.targetNodeId = '*';
|
|
25021
|
-
logger$
|
|
25023
|
+
logger$13.debug('broadcast_channel_target_updated', {
|
|
25022
25024
|
channel: this.channelName,
|
|
25023
25025
|
connector_id: this.connectorId,
|
|
25024
25026
|
local_node_id: this.localNodeId,
|
|
@@ -25164,7 +25166,7 @@
|
|
|
25164
25166
|
return config;
|
|
25165
25167
|
}
|
|
25166
25168
|
|
|
25167
|
-
const logger$
|
|
25169
|
+
const logger$12 = getLogger('naylence.fame.node.upstream_session_manager');
|
|
25168
25170
|
function isPlainRecord$4(value) {
|
|
25169
25171
|
if (typeof value !== 'object' || value === null) {
|
|
25170
25172
|
return false;
|
|
@@ -25237,6 +25239,7 @@
|
|
|
25237
25239
|
const onEpochChangeValue = pickOption$2(record, 'onEpochChange', 'on_epoch_change');
|
|
25238
25240
|
const onEpochChange = typeof onEpochChangeValue === 'function' ? onEpochChangeValue : undefined;
|
|
25239
25241
|
const admissionClient = pickOption$2(record, 'admissionClient', 'admission_client');
|
|
25242
|
+
const retryPolicy = pickOption$2(record, 'retryPolicy', 'retry_policy');
|
|
25240
25243
|
return {
|
|
25241
25244
|
node,
|
|
25242
25245
|
attachClient,
|
|
@@ -25248,6 +25251,7 @@
|
|
|
25248
25251
|
onAttach: validatedOnAttach,
|
|
25249
25252
|
onEpochChange,
|
|
25250
25253
|
admissionClient: admissionClient ?? undefined,
|
|
25254
|
+
retryPolicy: retryPolicy ?? undefined,
|
|
25251
25255
|
};
|
|
25252
25256
|
}
|
|
25253
25257
|
class UpstreamSessionManager extends TaskSpawner {
|
|
@@ -25267,6 +25271,7 @@
|
|
|
25267
25271
|
this.hadSuccessfulAttach = false;
|
|
25268
25272
|
this.lastConnectorState = null;
|
|
25269
25273
|
this.connectEpoch = 0;
|
|
25274
|
+
this.initialAttempts = 0;
|
|
25270
25275
|
this._visibilityHandler = null;
|
|
25271
25276
|
const options = normalizeOptions$k(optionsInput);
|
|
25272
25277
|
this.node = options.node;
|
|
@@ -25280,31 +25285,34 @@
|
|
|
25280
25285
|
this.admissionClient =
|
|
25281
25286
|
options.admissionClient ?? options.node.admissionClient;
|
|
25282
25287
|
this.wrappedHandler = this.makeHeartbeatEnabledHandler(options.inboundHandler);
|
|
25283
|
-
|
|
25288
|
+
// Store the connection retry policy (can be null, in which case default behavior applies)
|
|
25289
|
+
this.connectionRetryPolicy = options.retryPolicy ?? null;
|
|
25290
|
+
logger$12.debug('created_upstream_session_manager', {
|
|
25284
25291
|
target_system_id: this.targetSystemId,
|
|
25292
|
+
has_retry_policy: this.connectionRetryPolicy !== null,
|
|
25285
25293
|
});
|
|
25286
25294
|
}
|
|
25287
25295
|
get systemId() {
|
|
25288
25296
|
return this.targetSystemId;
|
|
25289
25297
|
}
|
|
25290
25298
|
setupVisibilityListener() {
|
|
25291
|
-
logger$
|
|
25299
|
+
logger$12.debug('setup_visibility_listener_called', {
|
|
25292
25300
|
has_document: typeof document !== 'undefined',
|
|
25293
25301
|
});
|
|
25294
25302
|
if (typeof document !== 'undefined' && document.addEventListener) {
|
|
25295
25303
|
this._visibilityHandler = () => {
|
|
25296
|
-
logger$
|
|
25304
|
+
logger$12.debug('visibility_change_event_fired', {
|
|
25297
25305
|
state: document.visibilityState,
|
|
25298
25306
|
});
|
|
25299
25307
|
if (document.visibilityState === 'visible') {
|
|
25300
|
-
logger$
|
|
25308
|
+
logger$12.debug('visibility_change_detected_waking_up');
|
|
25301
25309
|
this.wakeEvent.set();
|
|
25302
25310
|
}
|
|
25303
25311
|
};
|
|
25304
25312
|
document.addEventListener('visibilitychange', this._visibilityHandler);
|
|
25305
25313
|
}
|
|
25306
25314
|
else {
|
|
25307
|
-
logger$
|
|
25315
|
+
logger$12.debug('setup_visibility_listener_skipped_no_document');
|
|
25308
25316
|
}
|
|
25309
25317
|
}
|
|
25310
25318
|
teardownVisibilityListener() {
|
|
@@ -25337,13 +25345,13 @@
|
|
|
25337
25345
|
}
|
|
25338
25346
|
throw new FameConnectError('Upstream session manager failed to attach');
|
|
25339
25347
|
}
|
|
25340
|
-
logger$
|
|
25348
|
+
logger$12.debug('upstream_session_manager_started');
|
|
25341
25349
|
}
|
|
25342
25350
|
getActiveConnector() {
|
|
25343
25351
|
return this.connector;
|
|
25344
25352
|
}
|
|
25345
25353
|
async stop() {
|
|
25346
|
-
logger$
|
|
25354
|
+
logger$12.debug('upstream_session_manager_stopping');
|
|
25347
25355
|
this.teardownVisibilityListener();
|
|
25348
25356
|
this.stopEvent.set();
|
|
25349
25357
|
this.currentStopSubtasks?.set();
|
|
@@ -25354,7 +25362,7 @@
|
|
|
25354
25362
|
}
|
|
25355
25363
|
catch (error) {
|
|
25356
25364
|
if (!(error instanceof TaskCancelledError)) {
|
|
25357
|
-
logger$
|
|
25365
|
+
logger$12.debug('fsm_task_stopped_with_error', {
|
|
25358
25366
|
error: error.message,
|
|
25359
25367
|
});
|
|
25360
25368
|
}
|
|
@@ -25363,13 +25371,13 @@
|
|
|
25363
25371
|
}
|
|
25364
25372
|
if (this.connector) {
|
|
25365
25373
|
await this.connector.stop().catch((error) => {
|
|
25366
|
-
logger$
|
|
25374
|
+
logger$12.debug('connector_stop_error', {
|
|
25367
25375
|
error: error.message,
|
|
25368
25376
|
});
|
|
25369
25377
|
});
|
|
25370
25378
|
this.connector = null;
|
|
25371
25379
|
}
|
|
25372
|
-
logger$
|
|
25380
|
+
logger$12.debug('upstream_session_manager_stopped');
|
|
25373
25381
|
}
|
|
25374
25382
|
async send(envelope) {
|
|
25375
25383
|
if (this.messageQueue.length >= UpstreamSessionManager.TX_QUEUE_MAX) {
|
|
@@ -25397,11 +25405,14 @@
|
|
|
25397
25405
|
}
|
|
25398
25406
|
async fsmLoop() {
|
|
25399
25407
|
let delay = UpstreamSessionManager.BACKOFF_INITIAL;
|
|
25408
|
+
this.initialAttempts = 0;
|
|
25400
25409
|
while (!this.stopEvent.isSet()) {
|
|
25401
25410
|
const startTime = Date.now();
|
|
25411
|
+
this.initialAttempts += 1;
|
|
25402
25412
|
try {
|
|
25403
25413
|
await this.connectCycle();
|
|
25404
25414
|
delay = UpstreamSessionManager.BACKOFF_INITIAL;
|
|
25415
|
+
this.initialAttempts = 0; // Reset on success
|
|
25405
25416
|
}
|
|
25406
25417
|
catch (error) {
|
|
25407
25418
|
// Reset backoff if the connection was alive for more than 10 seconds
|
|
@@ -25411,32 +25422,38 @@
|
|
|
25411
25422
|
if (error instanceof TaskCancelledError) {
|
|
25412
25423
|
throw error;
|
|
25413
25424
|
}
|
|
25425
|
+
// Determine if we should fail-fast or retry
|
|
25426
|
+
const shouldFailFast = this.shouldFailFastOnError(error);
|
|
25414
25427
|
if (error instanceof FameTransportClose ||
|
|
25415
25428
|
error instanceof FameConnectError) {
|
|
25416
|
-
logger$
|
|
25429
|
+
logger$12.warning('upstream_link_closed', {
|
|
25417
25430
|
error: error.message,
|
|
25418
|
-
will_retry:
|
|
25431
|
+
will_retry: !shouldFailFast,
|
|
25432
|
+
attempt: this.initialAttempts,
|
|
25433
|
+
has_retry_policy: this.connectionRetryPolicy !== null,
|
|
25419
25434
|
});
|
|
25420
|
-
if (
|
|
25435
|
+
if (shouldFailFast && error instanceof FameConnectError) {
|
|
25421
25436
|
throw error;
|
|
25422
25437
|
}
|
|
25423
25438
|
}
|
|
25424
25439
|
else {
|
|
25425
25440
|
const err = error;
|
|
25426
25441
|
if (err.name === 'OAuth2PkceRedirectInitiatedError') {
|
|
25427
|
-
logger$
|
|
25442
|
+
logger$12.info('upstream_link_redirecting', {
|
|
25428
25443
|
error: err.message,
|
|
25429
25444
|
will_retry: true,
|
|
25430
25445
|
});
|
|
25431
25446
|
}
|
|
25432
25447
|
else {
|
|
25433
|
-
logger$
|
|
25448
|
+
logger$12.warning('upstream_link_closed', {
|
|
25434
25449
|
error: err.message,
|
|
25435
|
-
will_retry:
|
|
25450
|
+
will_retry: !shouldFailFast,
|
|
25451
|
+
attempt: this.initialAttempts,
|
|
25452
|
+
has_retry_policy: this.connectionRetryPolicy !== null,
|
|
25436
25453
|
exc_info: true,
|
|
25437
25454
|
});
|
|
25438
25455
|
}
|
|
25439
|
-
if (
|
|
25456
|
+
if (shouldFailFast) {
|
|
25440
25457
|
throw error;
|
|
25441
25458
|
}
|
|
25442
25459
|
}
|
|
@@ -25444,52 +25461,77 @@
|
|
|
25444
25461
|
}
|
|
25445
25462
|
}
|
|
25446
25463
|
}
|
|
25464
|
+
/**
|
|
25465
|
+
* Determine whether to fail immediately or continue retrying.
|
|
25466
|
+
* Returns true if we should throw the error instead of retrying.
|
|
25467
|
+
*/
|
|
25468
|
+
shouldFailFastOnError(error) {
|
|
25469
|
+
// If no policy is configured, use legacy behavior (fail-fast after first attempt)
|
|
25470
|
+
if (!this.connectionRetryPolicy) {
|
|
25471
|
+
// After first successful attach, always retry (existing behavior)
|
|
25472
|
+
if (this.hadSuccessfulAttach) {
|
|
25473
|
+
return false;
|
|
25474
|
+
}
|
|
25475
|
+
// Without a policy, fail on first error
|
|
25476
|
+
return true;
|
|
25477
|
+
}
|
|
25478
|
+
// Delegate decision to the policy
|
|
25479
|
+
const shouldRetry = this.connectionRetryPolicy.shouldRetry({
|
|
25480
|
+
hadSuccessfulAttach: this.hadSuccessfulAttach,
|
|
25481
|
+
attemptNumber: this.initialAttempts,
|
|
25482
|
+
error,
|
|
25483
|
+
});
|
|
25484
|
+
return !shouldRetry;
|
|
25485
|
+
}
|
|
25447
25486
|
async applyBackoff(delay) {
|
|
25448
25487
|
const jitter = Math.random() * delay;
|
|
25449
|
-
await this.sleepWithStop(delay + jitter);
|
|
25488
|
+
const wasWoken = await this.sleepWithStop(delay + jitter);
|
|
25489
|
+
// If sleep was interrupted by visibility change (user returned to tab),
|
|
25490
|
+
// reset backoff to initial delay for immediate retry with fresh backoff
|
|
25491
|
+
if (wasWoken) {
|
|
25492
|
+
logger$12.debug('backoff_reset_on_visibility_change', {
|
|
25493
|
+
previous_delay: delay,
|
|
25494
|
+
new_delay: UpstreamSessionManager.BACKOFF_INITIAL,
|
|
25495
|
+
});
|
|
25496
|
+
return UpstreamSessionManager.BACKOFF_INITIAL;
|
|
25497
|
+
}
|
|
25450
25498
|
return Math.min(delay * 2, UpstreamSessionManager.BACKOFF_CAP);
|
|
25451
25499
|
}
|
|
25500
|
+
/**
|
|
25501
|
+
* Sleep for the specified duration, but can be interrupted by stop or wake events.
|
|
25502
|
+
* @returns true if interrupted by wake event (e.g., visibility change), false otherwise
|
|
25503
|
+
*/
|
|
25452
25504
|
async sleepWithStop(delaySeconds) {
|
|
25453
25505
|
if (delaySeconds <= 0) {
|
|
25454
|
-
return;
|
|
25455
|
-
}
|
|
25456
|
-
// If the document is visible, cap the backoff delay to improve UX
|
|
25457
|
-
// This ensures that if the user is watching, we retry quickly (e.g. 1s)
|
|
25458
|
-
// instead of waiting for the full exponential backoff (up to 30s).
|
|
25459
|
-
let effectiveDelay = delaySeconds;
|
|
25460
|
-
if (typeof document !== 'undefined' &&
|
|
25461
|
-
document.visibilityState === 'visible') {
|
|
25462
|
-
effectiveDelay = Math.min(delaySeconds, 1.0);
|
|
25463
|
-
if (effectiveDelay < delaySeconds) {
|
|
25464
|
-
logger$11.debug('sleep_reduced_document_visible', {
|
|
25465
|
-
original: delaySeconds,
|
|
25466
|
-
new: effectiveDelay,
|
|
25467
|
-
});
|
|
25468
|
-
}
|
|
25506
|
+
return false;
|
|
25469
25507
|
}
|
|
25508
|
+
// Check if wake event is already set (e.g., visibility just changed)
|
|
25470
25509
|
if (this.wakeEvent.isSet()) {
|
|
25471
25510
|
this.wakeEvent.clear();
|
|
25472
|
-
|
|
25511
|
+
logger$12.debug('sleep_skipped_wake_event_pending');
|
|
25512
|
+
return true;
|
|
25473
25513
|
}
|
|
25474
25514
|
let timeout;
|
|
25475
25515
|
const sleepPromise = new Promise((resolve) => {
|
|
25476
25516
|
timeout = setTimeout(() => {
|
|
25477
25517
|
timeout = undefined;
|
|
25478
25518
|
resolve();
|
|
25479
|
-
},
|
|
25519
|
+
}, delaySeconds * 1000);
|
|
25480
25520
|
});
|
|
25481
25521
|
await Promise.race([
|
|
25482
25522
|
sleepPromise,
|
|
25483
25523
|
this.stopEvent.wait(),
|
|
25484
25524
|
this.wakeEvent.wait(),
|
|
25485
25525
|
]);
|
|
25486
|
-
|
|
25487
|
-
|
|
25526
|
+
const wasWoken = this.wakeEvent.isSet();
|
|
25527
|
+
if (wasWoken) {
|
|
25528
|
+
logger$12.debug('sleep_interrupted_by_wake_event');
|
|
25488
25529
|
this.wakeEvent.clear();
|
|
25489
25530
|
}
|
|
25490
25531
|
if (timeout !== undefined) {
|
|
25491
25532
|
clearTimeout(timeout);
|
|
25492
25533
|
}
|
|
25534
|
+
return wasWoken;
|
|
25493
25535
|
}
|
|
25494
25536
|
getNodeAttachGrant(connectionGrants) {
|
|
25495
25537
|
if (!connectionGrants) {
|
|
@@ -25546,7 +25588,7 @@
|
|
|
25546
25588
|
await connector.start(this.wrappedHandler);
|
|
25547
25589
|
this.connector = connector;
|
|
25548
25590
|
const callbackGrants = this.node.gatherSupportedCallbackGrants();
|
|
25549
|
-
logger$
|
|
25591
|
+
logger$12.debug('callback_grants_before_augmentation', {
|
|
25550
25592
|
count: callbackGrants.length,
|
|
25551
25593
|
types: callbackGrants.map((g) => g.type),
|
|
25552
25594
|
});
|
|
@@ -25556,7 +25598,7 @@
|
|
|
25556
25598
|
const broadcastCallbackGrant = shouldAddBroadcastGrant
|
|
25557
25599
|
? this.createBroadcastCallbackGrant(grant)
|
|
25558
25600
|
: null;
|
|
25559
|
-
logger$
|
|
25601
|
+
logger$12.debug('broadcast_callback_grant_check', {
|
|
25560
25602
|
should_add: shouldAddBroadcastGrant,
|
|
25561
25603
|
grant_created: !!broadcastCallbackGrant,
|
|
25562
25604
|
});
|
|
@@ -25575,12 +25617,12 @@
|
|
|
25575
25617
|
const isDuplicate = callbackGrants.some((existing) => JSON.stringify(existing) === JSON.stringify(grant));
|
|
25576
25618
|
if (!isDuplicate) {
|
|
25577
25619
|
callbackGrants.push(grant);
|
|
25578
|
-
logger$
|
|
25620
|
+
logger$12.debug('added_connection_grant_as_callback', {
|
|
25579
25621
|
type: grant.type,
|
|
25580
25622
|
});
|
|
25581
25623
|
}
|
|
25582
25624
|
else {
|
|
25583
|
-
logger$
|
|
25625
|
+
logger$12.debug('skipped_duplicate_connection_grant', {
|
|
25584
25626
|
type: grant.type,
|
|
25585
25627
|
});
|
|
25586
25628
|
}
|
|
@@ -25592,12 +25634,12 @@
|
|
|
25592
25634
|
if (broadcastCallbackGrant &&
|
|
25593
25635
|
this.shouldAdvertiseBroadcastGrant(grant, callbackGrants)) {
|
|
25594
25636
|
callbackGrants.push(broadcastCallbackGrant);
|
|
25595
|
-
logger$
|
|
25637
|
+
logger$12.debug('added_broadcast_callback_grant');
|
|
25596
25638
|
}
|
|
25597
25639
|
else if (broadcastCallbackGrant) {
|
|
25598
|
-
logger$
|
|
25640
|
+
logger$12.debug('skipped_duplicate_broadcast_callback_grant');
|
|
25599
25641
|
}
|
|
25600
|
-
logger$
|
|
25642
|
+
logger$12.debug('callback_grants_after_augmentation', {
|
|
25601
25643
|
count: callbackGrants.length,
|
|
25602
25644
|
types: callbackGrants.map((g) => g.type),
|
|
25603
25645
|
});
|
|
@@ -25610,7 +25652,7 @@
|
|
|
25610
25652
|
targetAware.setTargetNodeId(this.targetSystemId);
|
|
25611
25653
|
}
|
|
25612
25654
|
catch (error) {
|
|
25613
|
-
logger$
|
|
25655
|
+
logger$12.warning('broadcast_channel_target_apply_failed', {
|
|
25614
25656
|
error: error instanceof Error ? error.message : String(error),
|
|
25615
25657
|
target_node_id: this.targetSystemId,
|
|
25616
25658
|
});
|
|
@@ -25632,14 +25674,14 @@
|
|
|
25632
25674
|
});
|
|
25633
25675
|
}
|
|
25634
25676
|
else {
|
|
25635
|
-
logger$
|
|
25677
|
+
logger$12.warning('parent_epoch_changed', { epoch });
|
|
25636
25678
|
}
|
|
25637
25679
|
}
|
|
25638
25680
|
if (!this.readyEvent.isSet()) {
|
|
25639
25681
|
this.readyEvent.set();
|
|
25640
25682
|
}
|
|
25641
25683
|
if (this.messageQueue.length > 0) {
|
|
25642
|
-
logger$
|
|
25684
|
+
logger$12.debug('flushing_buffered_frames', {
|
|
25643
25685
|
queue_size: this.messageQueue.length,
|
|
25644
25686
|
});
|
|
25645
25687
|
this.queueEvent.set();
|
|
@@ -25656,12 +25698,12 @@
|
|
|
25656
25698
|
name: `expiry-guard-${this.connectEpoch}`,
|
|
25657
25699
|
});
|
|
25658
25700
|
if (this.hadSuccessfulAttach) {
|
|
25659
|
-
logger$
|
|
25701
|
+
logger$12.debug('reconnected_to_upstream', {
|
|
25660
25702
|
attach_expires_at: attachInfo.attachExpiresAt?.toISOString?.() ?? null,
|
|
25661
25703
|
});
|
|
25662
25704
|
}
|
|
25663
25705
|
else {
|
|
25664
|
-
logger$
|
|
25706
|
+
logger$12.debug('connected_to_upstream', {
|
|
25665
25707
|
attach_expires_at: attachInfo.attachExpiresAt?.toISOString?.() ?? null,
|
|
25666
25708
|
});
|
|
25667
25709
|
}
|
|
@@ -25679,18 +25721,18 @@
|
|
|
25679
25721
|
this.currentStopSubtasks = null;
|
|
25680
25722
|
await Promise.allSettled(tasks.map((task) => task.promise));
|
|
25681
25723
|
if (this.connector) {
|
|
25682
|
-
logger$
|
|
25724
|
+
logger$12.debug('upstream_stopping_old_connector', {
|
|
25683
25725
|
connect_epoch: this.connectEpoch,
|
|
25684
25726
|
target_system_id: this.targetSystemId,
|
|
25685
25727
|
timestamp: new Date().toISOString(),
|
|
25686
25728
|
});
|
|
25687
25729
|
await this.connector.stop().catch((err) => {
|
|
25688
|
-
logger$
|
|
25730
|
+
logger$12.warning('upstream_connector_stop_error', {
|
|
25689
25731
|
connect_epoch: this.connectEpoch,
|
|
25690
25732
|
error: err instanceof Error ? err.message : String(err),
|
|
25691
25733
|
});
|
|
25692
25734
|
});
|
|
25693
|
-
logger$
|
|
25735
|
+
logger$12.debug('upstream_old_connector_stopped', {
|
|
25694
25736
|
connect_epoch: this.connectEpoch,
|
|
25695
25737
|
target_system_id: this.targetSystemId,
|
|
25696
25738
|
timestamp: new Date().toISOString(),
|
|
@@ -25743,7 +25785,7 @@
|
|
|
25743
25785
|
});
|
|
25744
25786
|
}
|
|
25745
25787
|
catch (error) {
|
|
25746
|
-
logger$
|
|
25788
|
+
logger$12.debug('broadcast_callback_grant_generation_failed', {
|
|
25747
25789
|
error: error instanceof Error ? error.message : String(error),
|
|
25748
25790
|
});
|
|
25749
25791
|
return null;
|
|
@@ -25798,7 +25840,7 @@
|
|
|
25798
25840
|
}
|
|
25799
25841
|
}
|
|
25800
25842
|
async heartbeatLoop(connector, stopEvt, signal) {
|
|
25801
|
-
logger$
|
|
25843
|
+
logger$12.debug('starting_heartbeat_loop');
|
|
25802
25844
|
const intervalMs = UpstreamSessionManager.HEARTBEAT_INTERVAL * 1000;
|
|
25803
25845
|
const graceMs = intervalMs * UpstreamSessionManager.HEARTBEAT_GRACE;
|
|
25804
25846
|
this.lastHeartbeatAckTime = Date.now();
|
|
@@ -25834,7 +25876,7 @@
|
|
|
25834
25876
|
// Skip heartbeat if connector is paused (e.g., tab is hidden)
|
|
25835
25877
|
// Keep ack time current so we don't timeout immediately after resuming
|
|
25836
25878
|
if (currentState === ConnectorState.PAUSED) {
|
|
25837
|
-
logger$
|
|
25879
|
+
logger$12.debug('skipping_heartbeat_connector_paused', {
|
|
25838
25880
|
connector_state: currentState,
|
|
25839
25881
|
});
|
|
25840
25882
|
this.lastHeartbeatAckTime = Date.now();
|
|
@@ -25843,14 +25885,14 @@
|
|
|
25843
25885
|
// Reset ack time if just resumed from pause (prevents immediate timeout)
|
|
25844
25886
|
if (previousState === ConnectorState.PAUSED &&
|
|
25845
25887
|
currentState === ConnectorState.STARTED) {
|
|
25846
|
-
logger$
|
|
25888
|
+
logger$12.debug('connector_just_resumed_resetting_ack_time', {
|
|
25847
25889
|
previous_state: previousState,
|
|
25848
25890
|
current_state: currentState,
|
|
25849
25891
|
});
|
|
25850
25892
|
this.lastHeartbeatAckTime = Date.now();
|
|
25851
25893
|
}
|
|
25852
25894
|
const envelope = await this.makeHeartbeatEnvelope();
|
|
25853
|
-
logger$
|
|
25895
|
+
logger$12.debug('sending_heartbeat', {
|
|
25854
25896
|
hb_corr_id: envelope.corrId,
|
|
25855
25897
|
hb_env_id: envelope.id,
|
|
25856
25898
|
});
|
|
@@ -25876,7 +25918,7 @@
|
|
|
25876
25918
|
throw new FameConnectError('missed heartbeat acknowledgement');
|
|
25877
25919
|
}
|
|
25878
25920
|
}
|
|
25879
|
-
logger$
|
|
25921
|
+
logger$12.debug('completed_heartbeat_loop');
|
|
25880
25922
|
}
|
|
25881
25923
|
async messagePumpLoop(connector, stopEvt, signal) {
|
|
25882
25924
|
while (!stopEvt.isSet() && !signal?.aborted) {
|
|
@@ -25893,19 +25935,19 @@
|
|
|
25893
25935
|
if (!envelope) {
|
|
25894
25936
|
continue;
|
|
25895
25937
|
}
|
|
25896
|
-
logger$
|
|
25938
|
+
logger$12.debug('upstream_pump_sending_envelope', {
|
|
25897
25939
|
envelopeId: envelope.id,
|
|
25898
25940
|
type: envelope.frame?.type,
|
|
25899
25941
|
});
|
|
25900
25942
|
try {
|
|
25901
25943
|
await connector.send(envelope);
|
|
25902
|
-
logger$
|
|
25944
|
+
logger$12.debug('upstream_pump_sent_envelope', {
|
|
25903
25945
|
envelopeId: envelope.id,
|
|
25904
25946
|
});
|
|
25905
25947
|
}
|
|
25906
25948
|
catch (error) {
|
|
25907
25949
|
if (error instanceof FameMessageTooLarge) {
|
|
25908
|
-
logger$
|
|
25950
|
+
logger$12.error('failed_to_send_message', { error: error.message });
|
|
25909
25951
|
await this.handleMessageTooLarge(envelope, error.message);
|
|
25910
25952
|
}
|
|
25911
25953
|
else if (error instanceof FameTransportClose) {
|
|
@@ -25967,7 +26009,7 @@
|
|
|
25967
26009
|
await fabric.send(ackEnvelope);
|
|
25968
26010
|
}
|
|
25969
26011
|
catch (error) {
|
|
25970
|
-
logger$
|
|
26012
|
+
logger$12.warning('failed_to_send_nack', {
|
|
25971
26013
|
error: error.message,
|
|
25972
26014
|
});
|
|
25973
26015
|
}
|
|
@@ -25981,7 +26023,7 @@
|
|
|
25981
26023
|
timestamps.push(info.attachExpiresAt);
|
|
25982
26024
|
}
|
|
25983
26025
|
if (!timestamps.length) {
|
|
25984
|
-
logger$
|
|
26026
|
+
logger$12.debug('no_ttl_expiry_configured');
|
|
25985
26027
|
await this.waitEvent(stopEvt, signal);
|
|
25986
26028
|
return;
|
|
25987
26029
|
}
|
|
@@ -25990,7 +26032,7 @@
|
|
|
25990
26032
|
let delaySeconds = (earliest.getTime() - now.getTime()) / 1000 -
|
|
25991
26033
|
UpstreamSessionManager.JWT_REFRESH_SAFETY;
|
|
25992
26034
|
delaySeconds = Math.max(delaySeconds, UpstreamSessionManager.JWT_REFRESH_SAFETY);
|
|
25993
|
-
logger$
|
|
26035
|
+
logger$12.debug('ttl_expiry_guard_started', {
|
|
25994
26036
|
welcome_expires_at: welcome.frame.expiresAt ?? null,
|
|
25995
26037
|
attach_expires_at: info.attachExpiresAt?.toISOString?.() ?? null,
|
|
25996
26038
|
earliest_expiry: earliest.toISOString(),
|
|
@@ -26018,7 +26060,7 @@
|
|
|
26018
26060
|
}
|
|
26019
26061
|
}
|
|
26020
26062
|
if (!stopEvt.isSet()) {
|
|
26021
|
-
logger$
|
|
26063
|
+
logger$12.debug('ttl_expiry_triggered_reconnect', {
|
|
26022
26064
|
expires_at: earliest.toISOString(),
|
|
26023
26065
|
current_time: new Date().toISOString(),
|
|
26024
26066
|
seconds_before_expiry: UpstreamSessionManager.JWT_REFRESH_SAFETY,
|
|
@@ -26063,7 +26105,7 @@
|
|
|
26063
26105
|
}
|
|
26064
26106
|
await this.node.dispatchEnvelopeEvent('onEnvelopeReceived', this.node, env, context);
|
|
26065
26107
|
if (env.frame.type === 'NodeHeartbeatAck') {
|
|
26066
|
-
logger$
|
|
26108
|
+
logger$12.debug('received_heartbeat_ack', {
|
|
26067
26109
|
hb_ack_env_id: env.id,
|
|
26068
26110
|
hb_ack_corr_id: env.corrId,
|
|
26069
26111
|
hb_routing_epoch: env.frame.routingEpoch,
|
|
@@ -26077,7 +26119,7 @@
|
|
|
26077
26119
|
await this.onEpochChange(epoch);
|
|
26078
26120
|
}
|
|
26079
26121
|
else {
|
|
26080
|
-
logger$
|
|
26122
|
+
logger$12.warning('parent_epoch_changed', { epoch });
|
|
26081
26123
|
}
|
|
26082
26124
|
}
|
|
26083
26125
|
return;
|
|
@@ -26096,7 +26138,7 @@
|
|
|
26096
26138
|
UpstreamSessionManager.BACKOFF_INITIAL = 1; // seconds
|
|
26097
26139
|
UpstreamSessionManager.BACKOFF_CAP = 30; // seconds
|
|
26098
26140
|
|
|
26099
|
-
const logger$
|
|
26141
|
+
const logger$11 = getLogger('naylence.fame.node.admission.noop_admission_client');
|
|
26100
26142
|
class NoopAdmissionClient {
|
|
26101
26143
|
constructor(options = {}) {
|
|
26102
26144
|
this.hasUpstream = false;
|
|
@@ -26110,7 +26152,7 @@
|
|
|
26110
26152
|
const acceptedLogicals = this.autoAcceptLogicals
|
|
26111
26153
|
? [...(requestedLogicals ?? [])]
|
|
26112
26154
|
: [];
|
|
26113
|
-
logger$
|
|
26155
|
+
logger$11.debug('noop_admission_hello', {
|
|
26114
26156
|
systemId: effectiveSystemId,
|
|
26115
26157
|
instanceId,
|
|
26116
26158
|
requestedLogicals,
|
|
@@ -26128,7 +26170,7 @@
|
|
|
26128
26170
|
});
|
|
26129
26171
|
}
|
|
26130
26172
|
async close() {
|
|
26131
|
-
logger$
|
|
26173
|
+
logger$11.debug('noop_admission_close');
|
|
26132
26174
|
}
|
|
26133
26175
|
}
|
|
26134
26176
|
|
|
@@ -26334,7 +26376,7 @@
|
|
|
26334
26376
|
}
|
|
26335
26377
|
|
|
26336
26378
|
const SYSTEM_INBOX$1 = '__sys__';
|
|
26337
|
-
const logger
|
|
26379
|
+
const logger$10 = getLogger('naylence.fame.node.node');
|
|
26338
26380
|
function isSnakeCase(name) {
|
|
26339
26381
|
return name.includes('_');
|
|
26340
26382
|
}
|
|
@@ -26461,6 +26503,8 @@
|
|
|
26461
26503
|
this._acceptedLogicals = new Set(acceptedLogicalsOption);
|
|
26462
26504
|
const deliveryPolicyOption = resolveOption(options, 'deliveryPolicy', 'delivery_policy');
|
|
26463
26505
|
this._deliveryPolicy = deliveryPolicyOption ?? null;
|
|
26506
|
+
const connectionRetryPolicyOption = resolveOption(options, 'connectionRetryPolicy', 'connection_retry_policy');
|
|
26507
|
+
this._connectionRetryPolicy = connectionRetryPolicyOption ?? null;
|
|
26464
26508
|
const admissionClientOption = resolveOption(options, 'admissionClient', 'admission_client');
|
|
26465
26509
|
this._admissionClient = admissionClientOption ?? null;
|
|
26466
26510
|
const attachClientOption = resolveOption(options, 'attachClient', 'attach_client');
|
|
@@ -26590,6 +26634,7 @@
|
|
|
26590
26634
|
onAttach: (info, connector) => this.handleAttach(info, connector),
|
|
26591
26635
|
onEpochChange: (epoch) => this.handleEpochChange(epoch),
|
|
26592
26636
|
admissionClient: this._admissionClient,
|
|
26637
|
+
retryPolicy: this._connectionRetryPolicy,
|
|
26593
26638
|
});
|
|
26594
26639
|
this._sessionManager = manager;
|
|
26595
26640
|
await manager.start();
|
|
@@ -26601,7 +26646,7 @@
|
|
|
26601
26646
|
confirmIdentity(systemId, source) {
|
|
26602
26647
|
if (this._confirmedId) {
|
|
26603
26648
|
if (this._confirmedId !== systemId) {
|
|
26604
|
-
logger
|
|
26649
|
+
logger$10.error('node_identity_mismatch', {
|
|
26605
26650
|
current_id: this._confirmedId,
|
|
26606
26651
|
new_id: systemId,
|
|
26607
26652
|
source,
|
|
@@ -26613,14 +26658,14 @@
|
|
|
26613
26658
|
const isReassignment = this._provisionalId !== systemId;
|
|
26614
26659
|
this._confirmedId = systemId;
|
|
26615
26660
|
if (isReassignment) {
|
|
26616
|
-
logger
|
|
26661
|
+
logger$10.debug('node_identity_reassigned', {
|
|
26617
26662
|
system_id: systemId,
|
|
26618
26663
|
previous_id: this._provisionalId,
|
|
26619
26664
|
source,
|
|
26620
26665
|
});
|
|
26621
26666
|
}
|
|
26622
26667
|
else {
|
|
26623
|
-
logger
|
|
26668
|
+
logger$10.debug('node_identity_confirmed', {
|
|
26624
26669
|
system_id: systemId,
|
|
26625
26670
|
source,
|
|
26626
26671
|
});
|
|
@@ -26688,7 +26733,7 @@
|
|
|
26688
26733
|
return;
|
|
26689
26734
|
}
|
|
26690
26735
|
if (frameType === 'NodeHeartbeat') {
|
|
26691
|
-
logger
|
|
26736
|
+
logger$10.debug('received_heartbeat_frame', {
|
|
26692
26737
|
envelopeId: envelope.id,
|
|
26693
26738
|
corrId: envelope.corrId ?? null,
|
|
26694
26739
|
});
|
|
@@ -26700,7 +26745,7 @@
|
|
|
26700
26745
|
await this.handleDeliveryAck(envelope, context);
|
|
26701
26746
|
return;
|
|
26702
26747
|
}
|
|
26703
|
-
logger
|
|
26748
|
+
logger$10.debug('unhandled_system_frame', {
|
|
26704
26749
|
envelopeId: envelope.id,
|
|
26705
26750
|
frameType,
|
|
26706
26751
|
});
|
|
@@ -26712,13 +26757,13 @@
|
|
|
26712
26757
|
}
|
|
26713
26758
|
await this._deliveryTracker.onEnvelopeDelivered(SYSTEM_INBOX$1, envelope, context);
|
|
26714
26759
|
if (frame.ok !== false) {
|
|
26715
|
-
logger
|
|
26760
|
+
logger$10.debug('delivery_ack_received', {
|
|
26716
26761
|
envelopeId: envelope.id,
|
|
26717
26762
|
corrId: envelope.corrId ?? null,
|
|
26718
26763
|
});
|
|
26719
26764
|
return;
|
|
26720
26765
|
}
|
|
26721
|
-
logger
|
|
26766
|
+
logger$10.warning('delivery_nack_received', {
|
|
26722
26767
|
envelopeId: envelope.id,
|
|
26723
26768
|
corrId: envelope.corrId ?? null,
|
|
26724
26769
|
code: frame.code ?? null,
|
|
@@ -26728,7 +26773,7 @@
|
|
|
26728
26773
|
await this.onDeliveryNack(frame, envelope, context);
|
|
26729
26774
|
}
|
|
26730
26775
|
async onDeliveryNack(frame, envelope, _context) {
|
|
26731
|
-
logger
|
|
26776
|
+
logger$10.debug('delivery_nack_processed', {
|
|
26732
26777
|
envelopeId: envelope.id,
|
|
26733
26778
|
code: frame.code ?? null,
|
|
26734
26779
|
reason: frame.reason ?? null,
|
|
@@ -26843,7 +26888,7 @@
|
|
|
26843
26888
|
await this._bindingManager.restore();
|
|
26844
26889
|
await this._envelopeListenerManager.start();
|
|
26845
26890
|
this._isStarted = true;
|
|
26846
|
-
logger
|
|
26891
|
+
logger$10.debug('node_started', {
|
|
26847
26892
|
node_id: this.id,
|
|
26848
26893
|
sid: this.sid,
|
|
26849
26894
|
path: this.physicalPath,
|
|
@@ -26875,7 +26920,7 @@
|
|
|
26875
26920
|
await this._serviceManager.stop();
|
|
26876
26921
|
await this.dispatchEvent('onNodeStopped', this);
|
|
26877
26922
|
this._isStarted = false;
|
|
26878
|
-
logger
|
|
26923
|
+
logger$10.debug('node_stopped', {
|
|
26879
26924
|
node_id: this.id,
|
|
26880
26925
|
});
|
|
26881
26926
|
}
|
|
@@ -27065,20 +27110,20 @@
|
|
|
27065
27110
|
await this.forwardUpstream(processedEnvelope, context);
|
|
27066
27111
|
}
|
|
27067
27112
|
else {
|
|
27068
|
-
logger
|
|
27113
|
+
logger$10.error('attempted_upstream_loop', {
|
|
27069
27114
|
envelopeId: processedEnvelope.id,
|
|
27070
27115
|
});
|
|
27071
27116
|
}
|
|
27072
27117
|
return;
|
|
27073
27118
|
}
|
|
27074
27119
|
if (!processedEnvelope.to) {
|
|
27075
|
-
logger
|
|
27120
|
+
logger$10.error('dropping_envelope_without_destination', {
|
|
27076
27121
|
envelopeId: processedEnvelope.id,
|
|
27077
27122
|
capabilities: processedEnvelope.capabilities ?? [],
|
|
27078
27123
|
});
|
|
27079
27124
|
return;
|
|
27080
27125
|
}
|
|
27081
|
-
logger
|
|
27126
|
+
logger$10.warning('no_local_handler_for_address', {
|
|
27082
27127
|
address: processedEnvelope.to.toString?.() ?? String(processedEnvelope.to),
|
|
27083
27128
|
originType: context?.originType ?? null,
|
|
27084
27129
|
});
|
|
@@ -27202,7 +27247,7 @@
|
|
|
27202
27247
|
}
|
|
27203
27248
|
}
|
|
27204
27249
|
catch (error) {
|
|
27205
|
-
logger
|
|
27250
|
+
logger$10.warning('callback_grant_collection_failed', {
|
|
27206
27251
|
error: error instanceof Error ? error.message : String(error),
|
|
27207
27252
|
});
|
|
27208
27253
|
}
|
|
@@ -27265,7 +27310,7 @@
|
|
|
27265
27310
|
await store.set('self', record);
|
|
27266
27311
|
}
|
|
27267
27312
|
catch (error) {
|
|
27268
|
-
logger
|
|
27313
|
+
logger$10.warning('node_meta_persist_failed', {
|
|
27269
27314
|
error: error instanceof Error ? error.message : String(error),
|
|
27270
27315
|
});
|
|
27271
27316
|
}
|
|
@@ -27294,6 +27339,7 @@
|
|
|
27294
27339
|
telemetry: unknown().optional().nullable(),
|
|
27295
27340
|
requestedCapabilities: array(string$1()).optional(),
|
|
27296
27341
|
identityPolicy: unknown().optional().nullable(),
|
|
27342
|
+
connectionRetryPolicy: unknown().optional().nullable(),
|
|
27297
27343
|
})
|
|
27298
27344
|
.passthrough();
|
|
27299
27345
|
function normalizeFameNodeConfig(input) {
|
|
@@ -27335,6 +27381,9 @@
|
|
|
27335
27381
|
identityPolicy: parsed.identityPolicy === undefined
|
|
27336
27382
|
? null
|
|
27337
27383
|
: parsed.identityPolicy,
|
|
27384
|
+
connectionRetryPolicy: parsed.connectionRetryPolicy === undefined
|
|
27385
|
+
? null
|
|
27386
|
+
: parsed.connectionRetryPolicy,
|
|
27338
27387
|
};
|
|
27339
27388
|
if (parsed.requestedCapabilities) {
|
|
27340
27389
|
normalized.requestedCapabilities = coerceStringArray$1(parsed.requestedCapabilities);
|
|
@@ -27379,6 +27428,24 @@
|
|
|
27379
27428
|
}
|
|
27380
27429
|
}
|
|
27381
27430
|
|
|
27431
|
+
const CONNECTION_RETRY_POLICY_FACTORY_BASE_TYPE = 'ConnectionRetryPolicyFactory';
|
|
27432
|
+
class ConnectionRetryPolicyFactory extends AbstractResourceFactory {
|
|
27433
|
+
static async createConnectionRetryPolicy(config, options = {}) {
|
|
27434
|
+
if (config) {
|
|
27435
|
+
const policy = await createResource$1(CONNECTION_RETRY_POLICY_FACTORY_BASE_TYPE, config, options);
|
|
27436
|
+
if (!policy) {
|
|
27437
|
+
throw new Error('Failed to create connection retry policy from configuration');
|
|
27438
|
+
}
|
|
27439
|
+
return policy;
|
|
27440
|
+
}
|
|
27441
|
+
const policy = await createDefaultResource(CONNECTION_RETRY_POLICY_FACTORY_BASE_TYPE, null, options);
|
|
27442
|
+
if (!policy) {
|
|
27443
|
+
throw new Error('Failed to create default connection retry policy');
|
|
27444
|
+
}
|
|
27445
|
+
return policy;
|
|
27446
|
+
}
|
|
27447
|
+
}
|
|
27448
|
+
|
|
27382
27449
|
const TOKEN_PROVIDER_FACTORY_BASE_TYPE = 'TokenProviderFactory';
|
|
27383
27450
|
class TokenProviderFactory extends AbstractResourceFactory {
|
|
27384
27451
|
static async createTokenProvider(config, options = {}) {
|
|
@@ -27416,7 +27483,7 @@
|
|
|
27416
27483
|
'function');
|
|
27417
27484
|
}
|
|
27418
27485
|
|
|
27419
|
-
const logger
|
|
27486
|
+
const logger$$ = getLogger('naylence.fame.node.default_node_identity_policy');
|
|
27420
27487
|
class DefaultNodeIdentityPolicy {
|
|
27421
27488
|
async resolveInitialNodeId(context) {
|
|
27422
27489
|
if (context.configuredId) {
|
|
@@ -27446,7 +27513,7 @@
|
|
|
27446
27513
|
if (isIdentityExposingTokenProvider(provider)) {
|
|
27447
27514
|
const identity = await provider.getIdentity();
|
|
27448
27515
|
if (identity && identity.subject) {
|
|
27449
|
-
logger
|
|
27516
|
+
logger$$.debug('identity_extracted_from_grant', {
|
|
27450
27517
|
identity_id: identity.subject,
|
|
27451
27518
|
grant_type: grant.type,
|
|
27452
27519
|
});
|
|
@@ -27455,7 +27522,7 @@
|
|
|
27455
27522
|
}
|
|
27456
27523
|
}
|
|
27457
27524
|
catch (error) {
|
|
27458
|
-
logger
|
|
27525
|
+
logger$$.warning('identity_extraction_failed', {
|
|
27459
27526
|
error: error instanceof Error ? error.message : String(error),
|
|
27460
27527
|
grant_type: grant.type,
|
|
27461
27528
|
});
|
|
@@ -27539,7 +27606,7 @@
|
|
|
27539
27606
|
}
|
|
27540
27607
|
}
|
|
27541
27608
|
|
|
27542
|
-
const logger$
|
|
27609
|
+
const logger$_ = getLogger('naylence.fame.node.admission.default_node_attach_client');
|
|
27543
27610
|
const HANDSHAKE_POLL_INTERVAL_MS = 20;
|
|
27544
27611
|
class DefaultNodeAttachClient {
|
|
27545
27612
|
constructor(options = {}) {
|
|
@@ -27563,7 +27630,7 @@
|
|
|
27563
27630
|
}
|
|
27564
27631
|
else {
|
|
27565
27632
|
// Silently ignore frames from other agents during concurrent handshakes
|
|
27566
|
-
logger$
|
|
27633
|
+
logger$_.debug('handshake_ignoring_frame_from_different_system', {
|
|
27567
27634
|
frame_type: envelope.frame.type,
|
|
27568
27635
|
frame_system_id: frameSystemId,
|
|
27569
27636
|
expected_system_id: this.expectedSystemId,
|
|
@@ -27606,7 +27673,7 @@
|
|
|
27606
27673
|
}
|
|
27607
27674
|
}
|
|
27608
27675
|
catch (error) {
|
|
27609
|
-
logger$
|
|
27676
|
+
logger$_.debug('stickiness_offer_skipped', {
|
|
27610
27677
|
error: error instanceof Error ? error.message : String(error),
|
|
27611
27678
|
});
|
|
27612
27679
|
}
|
|
@@ -27627,7 +27694,7 @@
|
|
|
27627
27694
|
if (!processedEnvelope) {
|
|
27628
27695
|
throw new Error('Envelope was blocked by onForwardUpstream event');
|
|
27629
27696
|
}
|
|
27630
|
-
logger$
|
|
27697
|
+
logger$_.debug('sending_node_attach_envelope', {
|
|
27631
27698
|
envp_id: processedEnvelope.id ?? envelope.id ?? null,
|
|
27632
27699
|
frame_type: processedEnvelope.frame?.type ?? 'unknown',
|
|
27633
27700
|
trace_id: processedEnvelope.traceId ?? envelope.traceId ?? null,
|
|
@@ -27663,7 +27730,7 @@
|
|
|
27663
27730
|
try {
|
|
27664
27731
|
const keyInfos = await this.attachmentKeyValidator.validateKeys(parentKeys);
|
|
27665
27732
|
if (Array.isArray(keyInfos) && keyInfos.length > 0) {
|
|
27666
|
-
logger$
|
|
27733
|
+
logger$_.debug('parent_certificate_validation_passed', {
|
|
27667
27734
|
parent_id: parentId,
|
|
27668
27735
|
correlation_id: corrId,
|
|
27669
27736
|
validated_keys: keyInfos.length,
|
|
@@ -27672,7 +27739,7 @@
|
|
|
27672
27739
|
}
|
|
27673
27740
|
catch (error) {
|
|
27674
27741
|
if (error instanceof KeyValidationError) {
|
|
27675
|
-
logger$
|
|
27742
|
+
logger$_.error('parent_certificate_validation_failed', {
|
|
27676
27743
|
parent_id: parentId,
|
|
27677
27744
|
correlation_id: corrId,
|
|
27678
27745
|
error_code: error.code,
|
|
@@ -27686,12 +27753,12 @@
|
|
|
27686
27753
|
}
|
|
27687
27754
|
}
|
|
27688
27755
|
else {
|
|
27689
|
-
logger$
|
|
27756
|
+
logger$_.debug('parent_certificate_validation_skipped', {
|
|
27690
27757
|
parent_id: parentId,
|
|
27691
27758
|
reason: 'no_validator',
|
|
27692
27759
|
});
|
|
27693
27760
|
}
|
|
27694
|
-
logger$
|
|
27761
|
+
logger$_.debug('processing_node_attach_ack', {
|
|
27695
27762
|
parent_id: ackFrame.targetSystemId,
|
|
27696
27763
|
});
|
|
27697
27764
|
this.inHandshake = false;
|
|
@@ -27722,7 +27789,7 @@
|
|
|
27722
27789
|
}
|
|
27723
27790
|
}
|
|
27724
27791
|
catch (error) {
|
|
27725
|
-
logger$
|
|
27792
|
+
logger$_.debug('stickiness_accept_skipped', {
|
|
27726
27793
|
error: error instanceof Error ? error.message : String(error),
|
|
27727
27794
|
});
|
|
27728
27795
|
}
|
|
@@ -27776,7 +27843,7 @@
|
|
|
27776
27843
|
// NodeAttach frames during handshake are expected in multi-agent scenarios
|
|
27777
27844
|
// where multiple agents attach concurrently to the same channel
|
|
27778
27845
|
if (envelope.frame.type === 'NodeAttach') {
|
|
27779
|
-
logger$
|
|
27846
|
+
logger$_.debug('handshake_ignoring_concurrent_attach', {
|
|
27780
27847
|
frame_type: envelope.frame.type,
|
|
27781
27848
|
frame_system_id: envelope.frame?.systemId ??
|
|
27782
27849
|
'unknown',
|
|
@@ -27784,7 +27851,7 @@
|
|
|
27784
27851
|
}
|
|
27785
27852
|
else {
|
|
27786
27853
|
// Other unexpected frames are still logged as errors
|
|
27787
|
-
logger$
|
|
27854
|
+
logger$_.error('unexpected_frame_during_handshake', {
|
|
27788
27855
|
frame_type: envelope.frame.type,
|
|
27789
27856
|
});
|
|
27790
27857
|
}
|
|
@@ -27919,7 +27986,7 @@
|
|
|
27919
27986
|
// void import('./trace-emitter-profile-factory.js');
|
|
27920
27987
|
|
|
27921
27988
|
const BINDING_STORE_NAMESPACE = '__binding_store';
|
|
27922
|
-
const logger$
|
|
27989
|
+
const logger$Z = getLogger('naylence.fame.node.factory_commons');
|
|
27923
27990
|
function isPlainRecord$2(value) {
|
|
27924
27991
|
return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
|
|
27925
27992
|
}
|
|
@@ -28026,6 +28093,7 @@
|
|
|
28026
28093
|
const telemetryConfig = pickOption$1(config.telemetry ?? null, aliasRecord, 'trace_emitter', 'telemetry_config');
|
|
28027
28094
|
const securityConfig = pickOption$1(config.security ?? null, aliasRecord, 'security_manager', 'security_profile');
|
|
28028
28095
|
const identityPolicyConfig = pickOption$1(config.identityPolicy ?? null, aliasRecord, 'identity_policy', 'node_identity_policy');
|
|
28096
|
+
const connectionRetryPolicyConfig = pickOption$1(config.connectionRetryPolicy ?? null, aliasRecord, 'connection_retry_policy', 'retry_policy');
|
|
28029
28097
|
const publicUrl = pickString$2(config.publicUrl ?? null, aliasRecord, 'public_url') ?? null;
|
|
28030
28098
|
const directParentUrl = pickString$2(config.directParentUrl ?? null, aliasRecord, 'direct_parent_url') ?? null;
|
|
28031
28099
|
const hasParentFlag = config.hasParent || Boolean(aliasRecord.has_parent ?? false);
|
|
@@ -28035,6 +28103,7 @@
|
|
|
28035
28103
|
const nodeMetaStore = await storageProvider.getKeyValueStore(NodeMetaRecord, NODE_META_NAMESPACE);
|
|
28036
28104
|
const nodeMeta = await nodeMetaStore.get('self');
|
|
28037
28105
|
const identityPolicy = await resolveNodeIdentityPolicy(identityPolicyConfig ?? null, expressionOptions);
|
|
28106
|
+
const connectionRetryPolicy = await resolveConnectionRetryPolicy(connectionRetryPolicyConfig ?? null, expressionOptions);
|
|
28038
28107
|
const admissionClient = await resolveAdmissionClient(admissionConfig ?? null, expressionOptions, identityPolicy ?? undefined);
|
|
28039
28108
|
const hasParent = determineHasParent(hasParentFlag, directParentUrl, admissionClient);
|
|
28040
28109
|
const replicaStickinessManager = await resolveReplicaStickinessManager(hasParent, requestedLogicals, expressionOptions);
|
|
@@ -28103,6 +28172,7 @@
|
|
|
28103
28172
|
transportListeners,
|
|
28104
28173
|
traceEmitter,
|
|
28105
28174
|
identityPolicy: identityPolicy ?? undefined,
|
|
28175
|
+
connectionRetryPolicy: connectionRetryPolicy ?? undefined,
|
|
28106
28176
|
};
|
|
28107
28177
|
}
|
|
28108
28178
|
async function resolveNodeIdentityPolicy(config, options) {
|
|
@@ -28110,7 +28180,18 @@
|
|
|
28110
28180
|
return await NodeIdentityPolicyFactory.createNodeIdentityPolicy(config ?? undefined, cloneCreateOptions(options));
|
|
28111
28181
|
}
|
|
28112
28182
|
catch (error) {
|
|
28113
|
-
logger$
|
|
28183
|
+
logger$Z.warning('node_identity_policy_creation_failed', {
|
|
28184
|
+
error: error instanceof Error ? error.message : String(error),
|
|
28185
|
+
});
|
|
28186
|
+
return null;
|
|
28187
|
+
}
|
|
28188
|
+
}
|
|
28189
|
+
async function resolveConnectionRetryPolicy(config, options) {
|
|
28190
|
+
try {
|
|
28191
|
+
return await ConnectionRetryPolicyFactory.createConnectionRetryPolicy(config ?? undefined, cloneCreateOptions(options));
|
|
28192
|
+
}
|
|
28193
|
+
catch (error) {
|
|
28194
|
+
logger$Z.warning('connection_retry_policy_creation_failed', {
|
|
28114
28195
|
error: error instanceof Error ? error.message : String(error),
|
|
28115
28196
|
});
|
|
28116
28197
|
return null;
|
|
@@ -28122,7 +28203,7 @@
|
|
|
28122
28203
|
return await StorageProviderFactory.createStorageProvider(config, cloneCreateOptions(options));
|
|
28123
28204
|
}
|
|
28124
28205
|
catch (error) {
|
|
28125
|
-
logger$
|
|
28206
|
+
logger$Z.warning('storage_provider_creation_failed', {
|
|
28126
28207
|
error: error instanceof Error ? error.message : String(error),
|
|
28127
28208
|
});
|
|
28128
28209
|
}
|
|
@@ -28144,7 +28225,7 @@
|
|
|
28144
28225
|
return await AdmissionClientFactory.createAdmissionClient((config ?? null), createOptions);
|
|
28145
28226
|
}
|
|
28146
28227
|
catch (error) {
|
|
28147
|
-
logger$
|
|
28228
|
+
logger$Z.warning('admission_client_creation_failed', {
|
|
28148
28229
|
error: error instanceof Error ? error.message : String(error),
|
|
28149
28230
|
});
|
|
28150
28231
|
return null;
|
|
@@ -28171,7 +28252,7 @@
|
|
|
28171
28252
|
return await ReplicaStickinessManagerFactory.createReplicaStickinessManager(undefined, cloneCreateOptions(options));
|
|
28172
28253
|
}
|
|
28173
28254
|
catch (error) {
|
|
28174
|
-
logger$
|
|
28255
|
+
logger$Z.debug('replica_stickiness_manager_unavailable', { error });
|
|
28175
28256
|
return null;
|
|
28176
28257
|
}
|
|
28177
28258
|
}
|
|
@@ -28180,7 +28261,7 @@
|
|
|
28180
28261
|
return await AttachmentKeyValidatorFactory.createAttachmentKeyValidator(config ?? undefined, cloneCreateOptions(options));
|
|
28181
28262
|
}
|
|
28182
28263
|
catch (error) {
|
|
28183
|
-
logger$
|
|
28264
|
+
logger$Z.warning('attachment_key_validator_creation_failed', {
|
|
28184
28265
|
error: error instanceof Error ? error.message : String(error),
|
|
28185
28266
|
});
|
|
28186
28267
|
return null;
|
|
@@ -28198,7 +28279,7 @@
|
|
|
28198
28279
|
return await DeliveryPolicyFactory.createDeliveryPolicy(config ?? undefined, cloneCreateOptions(options));
|
|
28199
28280
|
}
|
|
28200
28281
|
catch (error) {
|
|
28201
|
-
logger$
|
|
28282
|
+
logger$Z.warning('delivery_policy_creation_failed', {
|
|
28202
28283
|
error: error instanceof Error ? error.message : String(error),
|
|
28203
28284
|
});
|
|
28204
28285
|
return null;
|
|
@@ -28212,7 +28293,7 @@
|
|
|
28212
28293
|
return await TransportListenerFactory.createTransportListeners(configs, eventListeners, cloneCreateOptions(options));
|
|
28213
28294
|
}
|
|
28214
28295
|
catch (error) {
|
|
28215
|
-
logger$
|
|
28296
|
+
logger$Z.warning('transport_listener_creation_failed', {
|
|
28216
28297
|
error: error instanceof Error ? error.message : String(error),
|
|
28217
28298
|
});
|
|
28218
28299
|
return [];
|
|
@@ -28223,7 +28304,7 @@
|
|
|
28223
28304
|
return await TraceEmitterFactory.createTraceEmitter(config ?? undefined, cloneCreateOptions(options));
|
|
28224
28305
|
}
|
|
28225
28306
|
catch (error) {
|
|
28226
|
-
logger$
|
|
28307
|
+
logger$Z.warning('trace_emitter_creation_failed', {
|
|
28227
28308
|
error: error instanceof Error ? error.message : String(error),
|
|
28228
28309
|
});
|
|
28229
28310
|
return null;
|
|
@@ -28279,7 +28360,7 @@
|
|
|
28279
28360
|
return manager ?? null;
|
|
28280
28361
|
}
|
|
28281
28362
|
catch (error) {
|
|
28282
|
-
logger$
|
|
28363
|
+
logger$Z.warning('security_manager_creation_failed', {
|
|
28283
28364
|
error: error instanceof Error ? error.message : String(error),
|
|
28284
28365
|
});
|
|
28285
28366
|
return null;
|
|
@@ -28308,7 +28389,7 @@
|
|
|
28308
28389
|
// This happens with overlay security profiles that need envelope signing
|
|
28309
28390
|
if (requiresCryptoProvider(config)) {
|
|
28310
28391
|
try {
|
|
28311
|
-
logger$
|
|
28392
|
+
logger$Z.debug('auto_creating_crypto_provider', {
|
|
28312
28393
|
reason: 'overlay_security_requires_signing',
|
|
28313
28394
|
});
|
|
28314
28395
|
// Dynamically import to avoid circular dependencies
|
|
@@ -28328,7 +28409,7 @@
|
|
|
28328
28409
|
});
|
|
28329
28410
|
}
|
|
28330
28411
|
catch (error) {
|
|
28331
|
-
logger$
|
|
28412
|
+
logger$Z.error('failed_to_auto_create_crypto_provider', {
|
|
28332
28413
|
error: error instanceof Error ? error.message : String(error),
|
|
28333
28414
|
});
|
|
28334
28415
|
throw error;
|
|
@@ -28871,7 +28952,7 @@
|
|
|
28871
28952
|
// registerFactory(NODE_LIKE_FACTORY_BASE_TYPE, type, factory);
|
|
28872
28953
|
// }
|
|
28873
28954
|
|
|
28874
|
-
const FACTORY_META$
|
|
28955
|
+
const FACTORY_META$18 = {
|
|
28875
28956
|
base: NODE_LIKE_FACTORY_BASE_TYPE,
|
|
28876
28957
|
key: 'Node',
|
|
28877
28958
|
};
|
|
@@ -28905,6 +28986,7 @@
|
|
|
28905
28986
|
nodeMetaStore: components.nodeMetaStore,
|
|
28906
28987
|
transportListeners: components.transportListeners,
|
|
28907
28988
|
defaultServiceConfigs: serviceConfigs,
|
|
28989
|
+
connectionRetryPolicy: components.connectionRetryPolicy,
|
|
28908
28990
|
});
|
|
28909
28991
|
return node;
|
|
28910
28992
|
}
|
|
@@ -28912,7 +28994,7 @@
|
|
|
28912
28994
|
|
|
28913
28995
|
var nodeFactory = /*#__PURE__*/Object.freeze({
|
|
28914
28996
|
__proto__: null,
|
|
28915
|
-
FACTORY_META: FACTORY_META$
|
|
28997
|
+
FACTORY_META: FACTORY_META$18,
|
|
28916
28998
|
NodeFactory: NodeFactory,
|
|
28917
28999
|
default: NodeFactory
|
|
28918
29000
|
});
|
|
@@ -29446,7 +29528,7 @@
|
|
|
29446
29528
|
};
|
|
29447
29529
|
}
|
|
29448
29530
|
|
|
29449
|
-
const logger$
|
|
29531
|
+
const logger$Y = getLogger('naylence.fame.node.envelope_security_handler');
|
|
29450
29532
|
const ENCRYPTION_OPTION_ALIAS_PAIRS = [
|
|
29451
29533
|
['recipKid', 'recip_kid'],
|
|
29452
29534
|
['recipientKeyId', 'recipient_key_id'],
|
|
@@ -29495,7 +29577,7 @@
|
|
|
29495
29577
|
const shouldSign = this.securityPolicy
|
|
29496
29578
|
? await this.securityPolicy.shouldSignEnvelope(envelope, context, this.node)
|
|
29497
29579
|
: false;
|
|
29498
|
-
logger$
|
|
29580
|
+
logger$Y.debug('checking_signing', {
|
|
29499
29581
|
has_signer: Boolean(this.envelopeSigner),
|
|
29500
29582
|
should_sign: shouldSign,
|
|
29501
29583
|
envp_id: envelope.id,
|
|
@@ -29517,7 +29599,7 @@
|
|
|
29517
29599
|
const shouldEncrypt = this.securityPolicy
|
|
29518
29600
|
? await this.securityPolicy.shouldEncryptEnvelope(envelope, context, this.node)
|
|
29519
29601
|
: false;
|
|
29520
|
-
logger$
|
|
29602
|
+
logger$Y.debug('checking_encryption', {
|
|
29521
29603
|
has_encryption_manager: Boolean(this.encryptionManager),
|
|
29522
29604
|
should_encrypt: shouldEncrypt,
|
|
29523
29605
|
envp_id: envelope.id,
|
|
@@ -29525,7 +29607,7 @@
|
|
|
29525
29607
|
});
|
|
29526
29608
|
if (this.encryptionManager && this.securityPolicy) {
|
|
29527
29609
|
if (envelope.sec?.enc) {
|
|
29528
|
-
logger$
|
|
29610
|
+
logger$Y.debug('skipping_encryption_already_encrypted', {
|
|
29529
29611
|
envp_id: envelope.id,
|
|
29530
29612
|
destination: envelope.to ? String(envelope.to) : undefined,
|
|
29531
29613
|
});
|
|
@@ -29538,7 +29620,7 @@
|
|
|
29538
29620
|
CryptoLevel.PLAINTEXT;
|
|
29539
29621
|
desiredCryptoLevel =
|
|
29540
29622
|
await this.securityPolicy.decideResponseCryptoLevel(requestCryptoLevel, envelope, context);
|
|
29541
|
-
logger$
|
|
29623
|
+
logger$Y.debug('response_crypto_level_decided', {
|
|
29542
29624
|
envp_id: envelope.id,
|
|
29543
29625
|
crypto_level: desiredCryptoLevel,
|
|
29544
29626
|
destination: envelope.to ? String(envelope.to) : undefined,
|
|
@@ -29549,7 +29631,7 @@
|
|
|
29549
29631
|
else {
|
|
29550
29632
|
desiredCryptoLevel =
|
|
29551
29633
|
await this.securityPolicy.decideOutboundCryptoLevel(envelope, context, this.node);
|
|
29552
|
-
logger$
|
|
29634
|
+
logger$Y.debug('outbound_crypto_level_decided', {
|
|
29553
29635
|
envp_id: envelope.id,
|
|
29554
29636
|
frame_type: envelope.frame.type,
|
|
29555
29637
|
crypto_level: desiredCryptoLevel,
|
|
@@ -29557,11 +29639,11 @@
|
|
|
29557
29639
|
});
|
|
29558
29640
|
}
|
|
29559
29641
|
if (desiredCryptoLevel === CryptoLevel.SEALED) {
|
|
29560
|
-
logger$
|
|
29642
|
+
logger$Y.debug('applying_sealed_encryption', { envp_id: envelope.id });
|
|
29561
29643
|
return await this.handleSealedEncryption(envelope, context);
|
|
29562
29644
|
}
|
|
29563
29645
|
if (desiredCryptoLevel === CryptoLevel.CHANNEL) {
|
|
29564
|
-
logger$
|
|
29646
|
+
logger$Y.debug('applying_channel_encryption', { envp_id: envelope.id });
|
|
29565
29647
|
return await this.handleChannelEncryption(envelope, context);
|
|
29566
29648
|
}
|
|
29567
29649
|
}
|
|
@@ -29612,7 +29694,7 @@
|
|
|
29612
29694
|
frameType === 'KeyAnnounce' ||
|
|
29613
29695
|
frameType === 'SecureOpen' ||
|
|
29614
29696
|
frameType === 'SecureAccept') {
|
|
29615
|
-
logger$
|
|
29697
|
+
logger$Y.error('critical_frame_unsigned_rejected', {
|
|
29616
29698
|
envp_id: envelope.id,
|
|
29617
29699
|
frame_type: frameType,
|
|
29618
29700
|
reason: 'critical_frames_must_be_signed',
|
|
@@ -29620,7 +29702,7 @@
|
|
|
29620
29702
|
return [envelope, false];
|
|
29621
29703
|
}
|
|
29622
29704
|
const action = this.securityPolicy.getUnsignedViolationAction(envelope, context);
|
|
29623
|
-
logger$
|
|
29705
|
+
logger$Y.warning('unsigned_envelope_violation', {
|
|
29624
29706
|
envp_id: envelope.id,
|
|
29625
29707
|
frame_type: frameType,
|
|
29626
29708
|
action,
|
|
@@ -29632,26 +29714,26 @@
|
|
|
29632
29714
|
return [envelope, true];
|
|
29633
29715
|
}
|
|
29634
29716
|
async handleChannelHandshakeComplete(channelId, destination) {
|
|
29635
|
-
logger$
|
|
29717
|
+
logger$Y.debug('channel_handshake_completed', {
|
|
29636
29718
|
channel_id: channelId,
|
|
29637
29719
|
destination,
|
|
29638
29720
|
});
|
|
29639
29721
|
if (this.encryptionManager?.notifyChannelEstablished) {
|
|
29640
29722
|
await this.encryptionManager.notifyChannelEstablished(channelId);
|
|
29641
|
-
logger$
|
|
29723
|
+
logger$Y.debug('notified_encryption_manager_channel_ready', {
|
|
29642
29724
|
channel_id: channelId,
|
|
29643
29725
|
});
|
|
29644
29726
|
}
|
|
29645
29727
|
}
|
|
29646
29728
|
async handleChannelHandshakeFailed(channelId, destination, reason = 'handshake_failed') {
|
|
29647
|
-
logger$
|
|
29729
|
+
logger$Y.debug('channel_handshake_failed', {
|
|
29648
29730
|
channel_id: channelId,
|
|
29649
29731
|
destination,
|
|
29650
29732
|
reason,
|
|
29651
29733
|
});
|
|
29652
29734
|
if (this.encryptionManager?.notifyChannelFailed) {
|
|
29653
29735
|
await this.encryptionManager.notifyChannelFailed(channelId, reason);
|
|
29654
|
-
logger$
|
|
29736
|
+
logger$Y.debug('notified_encryption_manager_channel_failed', {
|
|
29655
29737
|
channel_id: channelId,
|
|
29656
29738
|
reason,
|
|
29657
29739
|
});
|
|
@@ -29698,7 +29780,7 @@
|
|
|
29698
29780
|
checkPayload: false,
|
|
29699
29781
|
});
|
|
29700
29782
|
if (verified) {
|
|
29701
|
-
logger$
|
|
29783
|
+
logger$Y.debug('envelope_verified', {
|
|
29702
29784
|
envp_id: envelope.id,
|
|
29703
29785
|
sid: envelope.sid,
|
|
29704
29786
|
kid,
|
|
@@ -29709,7 +29791,7 @@
|
|
|
29709
29791
|
}
|
|
29710
29792
|
this.keyManagementHandler.queuePendingSignedEnvelope(kid, envelope, context);
|
|
29711
29793
|
await this.keyManagementHandler.maybeRequestSigningKey(kid, context.originType, fromSystemId);
|
|
29712
|
-
logger$
|
|
29794
|
+
logger$Y.debug('queued_envelope_missing_signing_key', {
|
|
29713
29795
|
kid,
|
|
29714
29796
|
envp_id: envelope.id,
|
|
29715
29797
|
});
|
|
@@ -29717,7 +29799,7 @@
|
|
|
29717
29799
|
}
|
|
29718
29800
|
async handleSealedEncryption(envelope, context) {
|
|
29719
29801
|
if (!envelope.to) {
|
|
29720
|
-
logger$
|
|
29802
|
+
logger$Y.warning('sealed_encryption_requested_but_no_destination', {
|
|
29721
29803
|
envp_id: envelope.id,
|
|
29722
29804
|
});
|
|
29723
29805
|
return true;
|
|
@@ -29729,20 +29811,20 @@
|
|
|
29729
29811
|
: undefined;
|
|
29730
29812
|
if (options) {
|
|
29731
29813
|
if (options.encryptionType === 'channel') {
|
|
29732
|
-
logger$
|
|
29814
|
+
logger$Y.warning('policy_returned_channel_for_sealed_request', {
|
|
29733
29815
|
envp_id: envelope.id,
|
|
29734
29816
|
});
|
|
29735
29817
|
return await this.handleToBeEncryptedEnvelopeWithOptions(envelope, context, normalizeEncryptionOptions({
|
|
29736
29818
|
requestAddress: envelope.to,
|
|
29737
29819
|
}));
|
|
29738
29820
|
}
|
|
29739
|
-
logger$
|
|
29821
|
+
logger$Y.debug('using_sealed_encryption_options', {
|
|
29740
29822
|
envp_id: envelope.id,
|
|
29741
29823
|
options,
|
|
29742
29824
|
});
|
|
29743
29825
|
return await this.handleToBeEncryptedEnvelopeWithOptions(envelope, context, options);
|
|
29744
29826
|
}
|
|
29745
|
-
logger$
|
|
29827
|
+
logger$Y.debug('no_encryption_options_requesting_key', {
|
|
29746
29828
|
envp_id: envelope.id,
|
|
29747
29829
|
});
|
|
29748
29830
|
return await this.handleToBeEncryptedEnvelopeWithOptions(envelope, context, normalizeEncryptionOptions({
|
|
@@ -29750,7 +29832,7 @@
|
|
|
29750
29832
|
}));
|
|
29751
29833
|
}
|
|
29752
29834
|
catch (error) {
|
|
29753
|
-
logger$
|
|
29835
|
+
logger$Y.debug('sealed_key_lookup_failed_requesting', {
|
|
29754
29836
|
envp_id: envelope.id,
|
|
29755
29837
|
error: error instanceof Error ? error.message : String(error),
|
|
29756
29838
|
});
|
|
@@ -29761,7 +29843,7 @@
|
|
|
29761
29843
|
}
|
|
29762
29844
|
async handleChannelEncryption(envelope, context) {
|
|
29763
29845
|
if (!envelope.to) {
|
|
29764
|
-
logger$
|
|
29846
|
+
logger$Y.warning('channel_encryption_requested_but_no_destination', {
|
|
29765
29847
|
envp_id: envelope.id,
|
|
29766
29848
|
});
|
|
29767
29849
|
return true;
|
|
@@ -29776,13 +29858,13 @@
|
|
|
29776
29858
|
return true;
|
|
29777
29859
|
}
|
|
29778
29860
|
if (context.originType !== DeliveryOriginType.LOCAL) {
|
|
29779
|
-
logger$
|
|
29861
|
+
logger$Y.warning('envelope_encryption_rejected_non_local', {
|
|
29780
29862
|
origin: context.originType,
|
|
29781
29863
|
});
|
|
29782
29864
|
return true;
|
|
29783
29865
|
}
|
|
29784
29866
|
if (!isDataFrame$4(envelope.frame)) {
|
|
29785
|
-
logger$
|
|
29867
|
+
logger$Y.trace('skipping_encryption_non_dataframe', {
|
|
29786
29868
|
envp_id: envelope.id,
|
|
29787
29869
|
frame_type: envelope.frame.type,
|
|
29788
29870
|
});
|
|
@@ -29793,7 +29875,7 @@
|
|
|
29793
29875
|
? normalizeEncryptionOptions(rawOptions)
|
|
29794
29876
|
: undefined;
|
|
29795
29877
|
if (!options) {
|
|
29796
|
-
logger$
|
|
29878
|
+
logger$Y.warning('no_encryption_options_provided', {
|
|
29797
29879
|
envp_id: envelope.id,
|
|
29798
29880
|
});
|
|
29799
29881
|
return true;
|
|
@@ -29805,13 +29887,13 @@
|
|
|
29805
29887
|
return true;
|
|
29806
29888
|
}
|
|
29807
29889
|
if (context.originType !== DeliveryOriginType.LOCAL) {
|
|
29808
|
-
logger$
|
|
29890
|
+
logger$Y.warning('envelope_encryption_rejected_non_local', {
|
|
29809
29891
|
origin: context.originType,
|
|
29810
29892
|
});
|
|
29811
29893
|
return true;
|
|
29812
29894
|
}
|
|
29813
29895
|
if (!isDataFrame$4(envelope.frame)) {
|
|
29814
|
-
logger$
|
|
29896
|
+
logger$Y.trace('skipping_encryption_non_dataframe', {
|
|
29815
29897
|
envp_id: envelope.id,
|
|
29816
29898
|
frame_type: envelope.frame.type,
|
|
29817
29899
|
});
|
|
@@ -29828,7 +29910,7 @@
|
|
|
29828
29910
|
// Skip encryption if envelope is already encrypted
|
|
29829
29911
|
// This prevents re-queuing when replayed envelopes go through security again
|
|
29830
29912
|
if (envelope.sec?.enc) {
|
|
29831
|
-
logger$
|
|
29913
|
+
logger$Y.debug('skipping_encryption_already_encrypted', {
|
|
29832
29914
|
envp_id: envelope.id,
|
|
29833
29915
|
destination: envelope.to ? String(envelope.to) : undefined,
|
|
29834
29916
|
});
|
|
@@ -29837,14 +29919,14 @@
|
|
|
29837
29919
|
try {
|
|
29838
29920
|
const result = await this.encryptionManager.encryptEnvelope(envelope, normalizedOptions);
|
|
29839
29921
|
if (result.status === EncryptionStatus.QUEUED) {
|
|
29840
|
-
logger$
|
|
29922
|
+
logger$Y.debug('envelope_queued_for_encryption', {
|
|
29841
29923
|
envp_id: envelope.id,
|
|
29842
29924
|
});
|
|
29843
29925
|
await this.handleEncryptionQueueing(envelope, context, normalizedOptions);
|
|
29844
29926
|
return false;
|
|
29845
29927
|
}
|
|
29846
29928
|
if (result.status === EncryptionStatus.OK) {
|
|
29847
|
-
logger$
|
|
29929
|
+
logger$Y.debug('envelope_encrypted', { envp_id: envelope.id });
|
|
29848
29930
|
if (result.envelope) {
|
|
29849
29931
|
envelope.frame = result.envelope.frame;
|
|
29850
29932
|
envelope.sec = result.envelope.sec;
|
|
@@ -29852,17 +29934,17 @@
|
|
|
29852
29934
|
return true;
|
|
29853
29935
|
}
|
|
29854
29936
|
if (result.status === EncryptionStatus.SKIPPED) {
|
|
29855
|
-
logger$
|
|
29937
|
+
logger$Y.debug('envelope_encryption_skipped', { envp_id: envelope.id });
|
|
29856
29938
|
return true;
|
|
29857
29939
|
}
|
|
29858
|
-
logger$
|
|
29940
|
+
logger$Y.warning('unknown_encryption_status', {
|
|
29859
29941
|
envp_id: envelope.id,
|
|
29860
29942
|
status: result.status,
|
|
29861
29943
|
});
|
|
29862
29944
|
return true;
|
|
29863
29945
|
}
|
|
29864
29946
|
catch (error) {
|
|
29865
|
-
logger$
|
|
29947
|
+
logger$Y.error('encryption_failed', {
|
|
29866
29948
|
envp_id: envelope.id,
|
|
29867
29949
|
error: error instanceof Error ? error.message : String(error),
|
|
29868
29950
|
});
|
|
@@ -29901,7 +29983,7 @@
|
|
|
29901
29983
|
return;
|
|
29902
29984
|
}
|
|
29903
29985
|
if (normalizedOptions.encryptionType === 'channel') {
|
|
29904
|
-
logger$
|
|
29986
|
+
logger$Y.debug('channel_encryption_queueing_handled_internally', {
|
|
29905
29987
|
envp_id: envelope.id,
|
|
29906
29988
|
destination: normalizedOptions.destination
|
|
29907
29989
|
? String(normalizedOptions.destination)
|
|
@@ -29909,13 +29991,13 @@
|
|
|
29909
29991
|
});
|
|
29910
29992
|
return;
|
|
29911
29993
|
}
|
|
29912
|
-
logger$
|
|
29994
|
+
logger$Y.warning('unknown_encryption_queueing_options', {
|
|
29913
29995
|
envp_id: envelope.id,
|
|
29914
29996
|
options: normalizedOptions,
|
|
29915
29997
|
});
|
|
29916
29998
|
}
|
|
29917
29999
|
async handleFailedChannelEnvelopeCleanup(destination, reason) {
|
|
29918
|
-
logger$
|
|
30000
|
+
logger$Y.debug('channel_handshake_failure_cleanup_attempted', {
|
|
29919
30001
|
destination,
|
|
29920
30002
|
reason,
|
|
29921
30003
|
note: 'envelope_cleanup_handled_by_encryption_manager',
|
|
@@ -29926,7 +30008,7 @@
|
|
|
29926
30008
|
}
|
|
29927
30009
|
}
|
|
29928
30010
|
|
|
29929
|
-
const logger$
|
|
30011
|
+
const logger$X = getLogger('naylence.fame.node.secure_channel_frame_handler');
|
|
29930
30012
|
function isPlainRecord$1(value) {
|
|
29931
30013
|
if (typeof value !== 'object' || value === null) {
|
|
29932
30014
|
return false;
|
|
@@ -30016,7 +30098,7 @@
|
|
|
30016
30098
|
assertSecureChannelManager(this.secureChannelManager);
|
|
30017
30099
|
const frame = envelope.frame;
|
|
30018
30100
|
assertFrameType(frame, 'SecureOpen');
|
|
30019
|
-
logger$
|
|
30101
|
+
logger$X.debug('received_secure_open', {
|
|
30020
30102
|
cid: frame.cid,
|
|
30021
30103
|
algorithm: frame.alg,
|
|
30022
30104
|
});
|
|
@@ -30039,13 +30121,13 @@
|
|
|
30039
30121
|
stickySid: envelope.sid ?? undefined,
|
|
30040
30122
|
expectedResponseType: FameResponseType.NONE,
|
|
30041
30123
|
};
|
|
30042
|
-
logger$
|
|
30124
|
+
logger$X.debug('stickiness_requested_for_channel_encryption', {
|
|
30043
30125
|
cid: frame.cid,
|
|
30044
30126
|
reason: 'secure_channel_established',
|
|
30045
30127
|
});
|
|
30046
30128
|
}
|
|
30047
30129
|
await this.sendCallback(responseEnvelope, responseContext);
|
|
30048
|
-
logger$
|
|
30130
|
+
logger$X.debug('sent_secure_accept', { cid: frame.cid, ok: acceptFrame.ok });
|
|
30049
30131
|
if (acceptFrame.ok && this.envelopeSecurityHandler) {
|
|
30050
30132
|
const destination = extractDestinationFromChannelId(frame.cid);
|
|
30051
30133
|
if (destination) {
|
|
@@ -30057,13 +30139,13 @@
|
|
|
30057
30139
|
assertSecureChannelManager(this.secureChannelManager);
|
|
30058
30140
|
const frame = envelope.frame;
|
|
30059
30141
|
assertFrameType(frame, 'SecureAccept');
|
|
30060
|
-
logger$
|
|
30142
|
+
logger$X.debug('received_secure_accept', { cid: frame.cid, ok: frame.ok });
|
|
30061
30143
|
const success = await this.secureChannelManager.handleAcceptFrame(frame);
|
|
30062
30144
|
if (!success) {
|
|
30063
|
-
logger$
|
|
30145
|
+
logger$X.warning('failed_to_complete_channel', { cid: frame.cid });
|
|
30064
30146
|
}
|
|
30065
30147
|
else {
|
|
30066
|
-
logger$
|
|
30148
|
+
logger$X.debug('channel_established', { cid: frame.cid });
|
|
30067
30149
|
if (this.envelopeSecurityHandler) {
|
|
30068
30150
|
const destination = extractDestinationFromChannelId(frame.cid);
|
|
30069
30151
|
if (destination) {
|
|
@@ -30075,7 +30157,7 @@
|
|
|
30075
30157
|
const destination = extractDestinationFromChannelId(frame.cid);
|
|
30076
30158
|
if (destination) {
|
|
30077
30159
|
await this.envelopeSecurityHandler.handleChannelHandshakeFailed(frame.cid, destination, 'negative_secure_accept');
|
|
30078
|
-
logger$
|
|
30160
|
+
logger$X.debug('notified_handshake_failure', {
|
|
30079
30161
|
cid: frame.cid,
|
|
30080
30162
|
destination,
|
|
30081
30163
|
});
|
|
@@ -30086,7 +30168,7 @@
|
|
|
30086
30168
|
assertSecureChannelManager(this.secureChannelManager);
|
|
30087
30169
|
const frame = envelope.frame;
|
|
30088
30170
|
assertFrameType(frame, 'SecureClose');
|
|
30089
|
-
logger$
|
|
30171
|
+
logger$X.debug('received_secure_close', {
|
|
30090
30172
|
cid: frame.cid,
|
|
30091
30173
|
reason: frame.reason,
|
|
30092
30174
|
});
|
|
@@ -30110,7 +30192,7 @@
|
|
|
30110
30192
|
}).optional(),
|
|
30111
30193
|
});
|
|
30112
30194
|
|
|
30113
|
-
const FACTORY_META$
|
|
30195
|
+
const FACTORY_META$17 = {
|
|
30114
30196
|
base: NODE_IDENTITY_POLICY_FACTORY_BASE_TYPE,
|
|
30115
30197
|
key: 'DefaultNodeIdentityPolicy',
|
|
30116
30198
|
};
|
|
@@ -30128,11 +30210,11 @@
|
|
|
30128
30210
|
var defaultNodeIdentityPolicyFactory = /*#__PURE__*/Object.freeze({
|
|
30129
30211
|
__proto__: null,
|
|
30130
30212
|
DefaultNodeIdentityPolicyFactory: DefaultNodeIdentityPolicyFactory,
|
|
30131
|
-
FACTORY_META: FACTORY_META$
|
|
30213
|
+
FACTORY_META: FACTORY_META$17,
|
|
30132
30214
|
default: DefaultNodeIdentityPolicyFactory
|
|
30133
30215
|
});
|
|
30134
30216
|
|
|
30135
|
-
const logger$
|
|
30217
|
+
const logger$W = getLogger('naylence.fame.node.token_subject_node_identity_policy');
|
|
30136
30218
|
class TokenSubjectNodeIdentityPolicy {
|
|
30137
30219
|
async resolveInitialNodeId(context) {
|
|
30138
30220
|
if (context.configuredId) {
|
|
@@ -30144,7 +30226,7 @@
|
|
|
30144
30226
|
return generateIdAsync();
|
|
30145
30227
|
}
|
|
30146
30228
|
async resolveAdmissionNodeId(context) {
|
|
30147
|
-
logger$
|
|
30229
|
+
logger$W.debug('resolve_admission_node_id_start', {
|
|
30148
30230
|
grantsCount: context.grants?.length ?? 0,
|
|
30149
30231
|
currentNodeId: context.currentNodeId,
|
|
30150
30232
|
});
|
|
@@ -30153,31 +30235,31 @@
|
|
|
30153
30235
|
try {
|
|
30154
30236
|
const auth = grant.auth;
|
|
30155
30237
|
if (!auth) {
|
|
30156
|
-
logger$
|
|
30238
|
+
logger$W.debug('skipping_grant_no_auth', { grantType: grant.type });
|
|
30157
30239
|
continue;
|
|
30158
30240
|
}
|
|
30159
30241
|
const tokenProviderConfig = (auth.tokenProvider ??
|
|
30160
30242
|
auth.token_provider);
|
|
30161
30243
|
if (!tokenProviderConfig ||
|
|
30162
30244
|
typeof tokenProviderConfig.type !== 'string') {
|
|
30163
|
-
logger$
|
|
30245
|
+
logger$W.debug('skipping_grant_invalid_token_provider_config', {
|
|
30164
30246
|
grantType: grant.type,
|
|
30165
30247
|
config: tokenProviderConfig,
|
|
30166
30248
|
});
|
|
30167
30249
|
continue;
|
|
30168
30250
|
}
|
|
30169
|
-
logger$
|
|
30251
|
+
logger$W.debug('creating_token_provider', {
|
|
30170
30252
|
type: tokenProviderConfig.type,
|
|
30171
30253
|
});
|
|
30172
30254
|
const provider = await TokenProviderFactory.createTokenProvider(tokenProviderConfig);
|
|
30173
30255
|
const isExposing = isIdentityExposingTokenProvider(provider);
|
|
30174
|
-
logger$
|
|
30256
|
+
logger$W.debug('token_provider_created', {
|
|
30175
30257
|
type: tokenProviderConfig.type,
|
|
30176
30258
|
isIdentityExposing: isExposing,
|
|
30177
30259
|
});
|
|
30178
30260
|
if (isExposing) {
|
|
30179
30261
|
const identity = await provider.getIdentity();
|
|
30180
|
-
logger$
|
|
30262
|
+
logger$W.debug('retrieved_identity', { identity });
|
|
30181
30263
|
if (identity && identity.subject) {
|
|
30182
30264
|
const hashedSubject = await generateIdAsync({
|
|
30183
30265
|
mode: 'fingerprint',
|
|
@@ -30185,7 +30267,7 @@
|
|
|
30185
30267
|
length: 8,
|
|
30186
30268
|
});
|
|
30187
30269
|
const newNodeId = `${hashedSubject}-${context.currentNodeId}`;
|
|
30188
|
-
logger$
|
|
30270
|
+
logger$W.info('resolved_identity_from_token', {
|
|
30189
30271
|
subject: identity.subject,
|
|
30190
30272
|
hashedSubject,
|
|
30191
30273
|
newNodeId,
|
|
@@ -30193,17 +30275,17 @@
|
|
|
30193
30275
|
return newNodeId;
|
|
30194
30276
|
}
|
|
30195
30277
|
else {
|
|
30196
|
-
logger$
|
|
30278
|
+
logger$W.debug('identity_missing_subject', { identity });
|
|
30197
30279
|
}
|
|
30198
30280
|
}
|
|
30199
30281
|
}
|
|
30200
30282
|
catch (err) {
|
|
30201
|
-
logger$
|
|
30283
|
+
logger$W.warning('failed_to_extract_identity_from_grant', { error: err });
|
|
30202
30284
|
}
|
|
30203
30285
|
}
|
|
30204
30286
|
}
|
|
30205
30287
|
else {
|
|
30206
|
-
logger$
|
|
30288
|
+
logger$W.debug('no_grants_available');
|
|
30207
30289
|
}
|
|
30208
30290
|
return context.currentNodeId;
|
|
30209
30291
|
}
|
|
@@ -30214,7 +30296,7 @@
|
|
|
30214
30296
|
TokenSubjectNodeIdentityPolicy: TokenSubjectNodeIdentityPolicy
|
|
30215
30297
|
});
|
|
30216
30298
|
|
|
30217
|
-
const FACTORY_META$
|
|
30299
|
+
const FACTORY_META$16 = {
|
|
30218
30300
|
base: NODE_IDENTITY_POLICY_FACTORY_BASE_TYPE,
|
|
30219
30301
|
key: 'TokenSubjectNodeIdentityPolicy',
|
|
30220
30302
|
};
|
|
@@ -30233,12 +30315,12 @@
|
|
|
30233
30315
|
|
|
30234
30316
|
var tokenSubjectNodeIdentityPolicyFactory = /*#__PURE__*/Object.freeze({
|
|
30235
30317
|
__proto__: null,
|
|
30236
|
-
FACTORY_META: FACTORY_META$
|
|
30318
|
+
FACTORY_META: FACTORY_META$16,
|
|
30237
30319
|
TokenSubjectNodeIdentityPolicyFactory: TokenSubjectNodeIdentityPolicyFactory,
|
|
30238
30320
|
default: TokenSubjectNodeIdentityPolicyFactory
|
|
30239
30321
|
});
|
|
30240
30322
|
|
|
30241
|
-
const logger$
|
|
30323
|
+
const logger$V = getLogger('naylence.fame.node.node_identity_policy_profile_factory');
|
|
30242
30324
|
const PROFILE_NAME_DEFAULT = 'default';
|
|
30243
30325
|
const PROFILE_NAME_TOKEN_SUBJECT = 'token-subject';
|
|
30244
30326
|
const PROFILE_NAME_TOKEN_SUBJECT_ALIAS = 'token_subject';
|
|
@@ -30253,7 +30335,7 @@
|
|
|
30253
30335
|
[PROFILE_NAME_TOKEN_SUBJECT]: TOKEN_SUBJECT_PROFILE,
|
|
30254
30336
|
[PROFILE_NAME_TOKEN_SUBJECT_ALIAS]: TOKEN_SUBJECT_PROFILE,
|
|
30255
30337
|
};
|
|
30256
|
-
const FACTORY_META$
|
|
30338
|
+
const FACTORY_META$15 = {
|
|
30257
30339
|
base: NODE_IDENTITY_POLICY_FACTORY_BASE_TYPE,
|
|
30258
30340
|
key: 'NodeIdentityPolicyProfile',
|
|
30259
30341
|
};
|
|
@@ -30265,7 +30347,7 @@
|
|
|
30265
30347
|
async create(config) {
|
|
30266
30348
|
const normalized = normalizeConfig$t(config);
|
|
30267
30349
|
const profileConfig = resolveProfileConfig$4(normalized.profile);
|
|
30268
|
-
logger$
|
|
30350
|
+
logger$V.debug('enabling_node_identity_policy_profile', {
|
|
30269
30351
|
profile: normalized.profile,
|
|
30270
30352
|
});
|
|
30271
30353
|
return NodeIdentityPolicyFactory.createNodeIdentityPolicy(profileConfig);
|
|
@@ -30301,11 +30383,95 @@
|
|
|
30301
30383
|
|
|
30302
30384
|
var nodeIdentityPolicyProfileFactory = /*#__PURE__*/Object.freeze({
|
|
30303
30385
|
__proto__: null,
|
|
30304
|
-
FACTORY_META: FACTORY_META$
|
|
30386
|
+
FACTORY_META: FACTORY_META$15,
|
|
30305
30387
|
NodeIdentityPolicyProfileFactory: NodeIdentityPolicyProfileFactory,
|
|
30306
30388
|
default: NodeIdentityPolicyProfileFactory
|
|
30307
30389
|
});
|
|
30308
30390
|
|
|
30391
|
+
/**
|
|
30392
|
+
* Environment variable for overriding max initial attempts.
|
|
30393
|
+
*/
|
|
30394
|
+
const ENV_VAR_SESSION_MAX_INITIAL_ATTEMPTS = 'FAME_SESSION_MAX_INITIAL_ATTEMPTS';
|
|
30395
|
+
/**
|
|
30396
|
+
* Default implementation of connection retry policy.
|
|
30397
|
+
*
|
|
30398
|
+
* Before first successful attach:
|
|
30399
|
+
* - Respects maxInitialAttempts configuration
|
|
30400
|
+
* - Uses exponential backoff with jitter
|
|
30401
|
+
*
|
|
30402
|
+
* After first successful attach:
|
|
30403
|
+
* - Always retries (unlimited) to maintain connection
|
|
30404
|
+
* - Resets backoff if connection was stable for >10 seconds
|
|
30405
|
+
*/
|
|
30406
|
+
class DefaultConnectionRetryPolicy {
|
|
30407
|
+
constructor(options = {}) {
|
|
30408
|
+
// Check for environment variable override
|
|
30409
|
+
const envValue = typeof process !== 'undefined'
|
|
30410
|
+
? process.env?.[ENV_VAR_SESSION_MAX_INITIAL_ATTEMPTS]
|
|
30411
|
+
: undefined;
|
|
30412
|
+
if (envValue !== undefined && envValue !== '') {
|
|
30413
|
+
const parsed = parseInt(envValue, 10);
|
|
30414
|
+
this.maxInitialAttempts = isNaN(parsed) ? (options.maxInitialAttempts ?? 1) : parsed;
|
|
30415
|
+
}
|
|
30416
|
+
else {
|
|
30417
|
+
this.maxInitialAttempts = options.maxInitialAttempts ?? 1;
|
|
30418
|
+
}
|
|
30419
|
+
}
|
|
30420
|
+
shouldRetry(context) {
|
|
30421
|
+
// After first successful attach, always retry to maintain connection
|
|
30422
|
+
if (context.hadSuccessfulAttach) {
|
|
30423
|
+
return true;
|
|
30424
|
+
}
|
|
30425
|
+
// maxInitialAttempts = 0 means unlimited retries
|
|
30426
|
+
if (this.maxInitialAttempts === 0) {
|
|
30427
|
+
return true;
|
|
30428
|
+
}
|
|
30429
|
+
// Fail if we've exceeded the configured max attempts
|
|
30430
|
+
return context.attemptNumber < this.maxInitialAttempts;
|
|
30431
|
+
}
|
|
30432
|
+
calculateRetryDelay(_context, baseDelay) {
|
|
30433
|
+
// Add jitter to prevent thundering herd
|
|
30434
|
+
const jitter = Math.random() * baseDelay;
|
|
30435
|
+
return baseDelay + jitter;
|
|
30436
|
+
}
|
|
30437
|
+
}
|
|
30438
|
+
|
|
30439
|
+
const logger$U = getLogger('naylence.fame.node.default-connection-retry-policy-factory');
|
|
30440
|
+
const FACTORY_META$14 = {
|
|
30441
|
+
base: CONNECTION_RETRY_POLICY_FACTORY_BASE_TYPE,
|
|
30442
|
+
key: 'DefaultConnectionRetryPolicy',
|
|
30443
|
+
};
|
|
30444
|
+
class DefaultConnectionRetryPolicyFactory extends ConnectionRetryPolicyFactory {
|
|
30445
|
+
constructor() {
|
|
30446
|
+
super(...arguments);
|
|
30447
|
+
this.type = 'DefaultConnectionRetryPolicy';
|
|
30448
|
+
this.isDefault = true;
|
|
30449
|
+
}
|
|
30450
|
+
async create(config) {
|
|
30451
|
+
const options = {};
|
|
30452
|
+
if (config) {
|
|
30453
|
+
const rawMax = config.maxInitialAttempts ??
|
|
30454
|
+
config.max_initial_attempts;
|
|
30455
|
+
if (rawMax !== undefined && rawMax !== null) {
|
|
30456
|
+
options.maxInitialAttempts =
|
|
30457
|
+
typeof rawMax === 'string' ? parseInt(rawMax, 10) : Number(rawMax);
|
|
30458
|
+
}
|
|
30459
|
+
}
|
|
30460
|
+
const policy = new DefaultConnectionRetryPolicy(options);
|
|
30461
|
+
logger$U.debug('connection_retry_policy_created', {
|
|
30462
|
+
maxInitialAttempts: policy.maxInitialAttempts,
|
|
30463
|
+
});
|
|
30464
|
+
return policy;
|
|
30465
|
+
}
|
|
30466
|
+
}
|
|
30467
|
+
|
|
30468
|
+
var defaultConnectionRetryPolicyFactory = /*#__PURE__*/Object.freeze({
|
|
30469
|
+
__proto__: null,
|
|
30470
|
+
DefaultConnectionRetryPolicyFactory: DefaultConnectionRetryPolicyFactory,
|
|
30471
|
+
FACTORY_META: FACTORY_META$14,
|
|
30472
|
+
default: DefaultConnectionRetryPolicyFactory
|
|
30473
|
+
});
|
|
30474
|
+
|
|
30309
30475
|
const LOAD_BALANCER_STICKINESS_MANAGER_FACTORY_BASE_TYPE = 'LoadBalancerStickinessManagerFactory';
|
|
30310
30476
|
class LoadBalancerStickinessManagerFactory extends AbstractResourceFactory {
|
|
30311
30477
|
static async createLoadBalancerStickinessManager(config, options = {}) {
|
|
@@ -33377,6 +33543,7 @@
|
|
|
33377
33543
|
this.maxAttachTtlSec = opts.maxAttachTtlSec ?? null;
|
|
33378
33544
|
this.requestedLogicals = opts.requestedLogicals ?? [];
|
|
33379
33545
|
this.attachClient = opts.attachClient ?? null;
|
|
33546
|
+
this.connectionRetryPolicy = opts.connectionRetryPolicy ?? null;
|
|
33380
33547
|
this.nodeAttachFrameHandler = new NodeAttachFrameHandler({
|
|
33381
33548
|
routingNode: this,
|
|
33382
33549
|
routeManager: this.routeManager,
|
|
@@ -33926,6 +34093,7 @@
|
|
|
33926
34093
|
onAttach: (info, connector) => this.onNodeAttachToPeer(info, connector),
|
|
33927
34094
|
onEpochChange: (epoch) => this.onEpochChange(epoch),
|
|
33928
34095
|
onWelcome: async () => undefined,
|
|
34096
|
+
retryPolicy: this.connectionRetryPolicy,
|
|
33929
34097
|
});
|
|
33930
34098
|
await sessionManager.start();
|
|
33931
34099
|
const systemId = sessionManager.systemId;
|
|
@@ -55055,12 +55223,12 @@
|
|
|
55055
55223
|
});
|
|
55056
55224
|
|
|
55057
55225
|
// This file is auto-generated during build - do not edit manually
|
|
55058
|
-
// Generated from package.json version: 0.3.
|
|
55226
|
+
// Generated from package.json version: 0.3.13
|
|
55059
55227
|
/**
|
|
55060
55228
|
* The package version, injected at build time.
|
|
55061
55229
|
* @internal
|
|
55062
55230
|
*/
|
|
55063
|
-
const VERSION$1 = '0.3.
|
|
55231
|
+
const VERSION$1 = '0.3.13';
|
|
55064
55232
|
|
|
55065
55233
|
let initialized = false;
|
|
55066
55234
|
const agentSdkPlugin = {
|
|
@@ -55434,6 +55602,20 @@
|
|
|
55434
55602
|
return registeredAgentProxyCtor;
|
|
55435
55603
|
}
|
|
55436
55604
|
|
|
55605
|
+
/**
|
|
55606
|
+
* Agent module providing the abstract {@link Agent} class.
|
|
55607
|
+
*
|
|
55608
|
+
* An Agent is a self-contained unit of work that can receive tasks, process them,
|
|
55609
|
+
* and return results. Agents communicate over the Fame fabric using a standard
|
|
55610
|
+
* task-based protocol.
|
|
55611
|
+
*
|
|
55612
|
+
* @remarks
|
|
55613
|
+
* For concrete implementations:
|
|
55614
|
+
* - Use {@link BaseAgent} when you need full control over task handling and state.
|
|
55615
|
+
* - Use {@link BackgroundTaskAgent} for long-running or async background work.
|
|
55616
|
+
*
|
|
55617
|
+
* @module
|
|
55618
|
+
*/
|
|
55437
55619
|
const logger$2 = getLogger('naylence.agent.agent');
|
|
55438
55620
|
let registeredBaseAgentCtor = null;
|
|
55439
55621
|
function requireBaseAgentCtor() {
|
|
@@ -55446,7 +55628,9 @@
|
|
|
55446
55628
|
function registerBaseAgentConstructor(ctor) {
|
|
55447
55629
|
registeredBaseAgentCtor = ctor;
|
|
55448
55630
|
}
|
|
55631
|
+
/** @internal */
|
|
55449
55632
|
const isNodeRuntime = () => typeof process !== 'undefined' && process.release?.name === 'node';
|
|
55633
|
+
/** @internal */
|
|
55450
55634
|
const LOG_LEVEL_KEYWORDS = {
|
|
55451
55635
|
critical: LogLevel.CRITICAL,
|
|
55452
55636
|
error: LogLevel.ERROR,
|
|
@@ -55456,6 +55640,7 @@
|
|
|
55456
55640
|
debug: LogLevel.DEBUG,
|
|
55457
55641
|
trace: LogLevel.TRACE,
|
|
55458
55642
|
};
|
|
55643
|
+
/** @internal */
|
|
55459
55644
|
function normalizeLogLevel(level) {
|
|
55460
55645
|
if (typeof level === 'number') {
|
|
55461
55646
|
if (Object.values(LogLevel).includes(level)) {
|
|
@@ -55473,6 +55658,7 @@
|
|
|
55473
55658
|
}
|
|
55474
55659
|
return level;
|
|
55475
55660
|
}
|
|
55661
|
+
/** @internal */
|
|
55476
55662
|
class Deferred {
|
|
55477
55663
|
constructor() {
|
|
55478
55664
|
this.settled = false;
|
|
@@ -55494,6 +55680,7 @@
|
|
|
55494
55680
|
this.internalReject(reason);
|
|
55495
55681
|
}
|
|
55496
55682
|
}
|
|
55683
|
+
/** @internal */
|
|
55497
55684
|
async function setupSignalHandlers(stop) {
|
|
55498
55685
|
if (!isNodeRuntime()) {
|
|
55499
55686
|
return () => { };
|
|
@@ -55518,6 +55705,7 @@
|
|
|
55518
55705
|
}
|
|
55519
55706
|
};
|
|
55520
55707
|
}
|
|
55708
|
+
/** @internal */
|
|
55521
55709
|
async function acquireFabric(options) {
|
|
55522
55710
|
const manageContext = fabricStack.length === 0;
|
|
55523
55711
|
const fabric = await FameFabric.getOrCreate(options ?? {});
|
|
@@ -55539,19 +55727,68 @@
|
|
|
55539
55727
|
},
|
|
55540
55728
|
};
|
|
55541
55729
|
}
|
|
55730
|
+
/** @internal */
|
|
55542
55731
|
function toFameAddress$1(value) {
|
|
55543
55732
|
return value instanceof FameAddress ? value : new FameAddress(String(value));
|
|
55544
55733
|
}
|
|
55734
|
+
/** @internal */
|
|
55545
55735
|
function invokeProxyRunTask(proxy, payload, taskId) {
|
|
55546
55736
|
if (typeof proxy.runTask === 'function') {
|
|
55547
55737
|
return proxy.runTask(payload, taskId);
|
|
55548
55738
|
}
|
|
55549
55739
|
throw new Error('AgentProxy must implement runTask');
|
|
55550
55740
|
}
|
|
55741
|
+
/**
|
|
55742
|
+
* Abstract base class for all agents.
|
|
55743
|
+
*
|
|
55744
|
+
* Agents are addressable services that handle tasks over the Fame fabric.
|
|
55745
|
+
* This class defines the core protocol methods every agent must implement.
|
|
55746
|
+
*
|
|
55747
|
+
* @remarks
|
|
55748
|
+
* Do not extend Agent directly. Instead:
|
|
55749
|
+
* - Extend {@link BaseAgent} for standard request-response agents.
|
|
55750
|
+
* - Extend {@link BackgroundTaskAgent} for long-running background work.
|
|
55751
|
+
*
|
|
55752
|
+
* Use {@link Agent.remote} or {@link Agent.remoteByAddress} to create proxies
|
|
55753
|
+
* for communicating with remote agents.
|
|
55754
|
+
*
|
|
55755
|
+
* @example
|
|
55756
|
+
* ```typescript
|
|
55757
|
+
* import { BaseAgent, Payload } from '@naylence/agent-sdk';
|
|
55758
|
+
*
|
|
55759
|
+
* class EchoAgent extends BaseAgent {
|
|
55760
|
+
* async runTask(payload: Payload): Promise<Payload> {
|
|
55761
|
+
* return payload;
|
|
55762
|
+
* }
|
|
55763
|
+
* }
|
|
55764
|
+
*
|
|
55765
|
+
* const agent = new EchoAgent('echo');
|
|
55766
|
+
* await agent.serve('fame://echo');
|
|
55767
|
+
* ```
|
|
55768
|
+
*/
|
|
55551
55769
|
class Agent extends RpcMixin {
|
|
55770
|
+
/**
|
|
55771
|
+
* Capabilities advertised by this agent for discovery.
|
|
55772
|
+
*/
|
|
55552
55773
|
get capabilities() {
|
|
55553
55774
|
return undefined;
|
|
55554
55775
|
}
|
|
55776
|
+
/**
|
|
55777
|
+
* Creates a proxy for communicating with a remote agent.
|
|
55778
|
+
*
|
|
55779
|
+
* @remarks
|
|
55780
|
+
* Provide exactly one of `address` or `capabilities` in the options.
|
|
55781
|
+
*
|
|
55782
|
+
* @example
|
|
55783
|
+
* ```typescript
|
|
55784
|
+
* const proxy = Agent.remote<EchoAgent>({ address: 'fame://echo' });
|
|
55785
|
+
* const result = await proxy.runTask('hello');
|
|
55786
|
+
* ```
|
|
55787
|
+
*
|
|
55788
|
+
* @param options - Remote agent options.
|
|
55789
|
+
* @returns A proxy for the remote agent.
|
|
55790
|
+
* @throws Error if both or neither of address/capabilities are provided.
|
|
55791
|
+
*/
|
|
55555
55792
|
static remote(options) {
|
|
55556
55793
|
const { address, capabilities, fabric } = options;
|
|
55557
55794
|
const selected = Number(address != null) + Number(capabilities != null);
|
|
@@ -55568,6 +55805,13 @@
|
|
|
55568
55805
|
fabric: resolvedFabric,
|
|
55569
55806
|
});
|
|
55570
55807
|
}
|
|
55808
|
+
/**
|
|
55809
|
+
* Creates a proxy for a remote agent by its address.
|
|
55810
|
+
*
|
|
55811
|
+
* @param address - The target agent's address.
|
|
55812
|
+
* @param options - Optional fabric configuration.
|
|
55813
|
+
* @returns A proxy for the remote agent.
|
|
55814
|
+
*/
|
|
55571
55815
|
static remoteByAddress(address, options = {}) {
|
|
55572
55816
|
const remoteOptions = { address };
|
|
55573
55817
|
if (options.fabric !== undefined) {
|
|
@@ -55575,6 +55819,13 @@
|
|
|
55575
55819
|
}
|
|
55576
55820
|
return this.remote(remoteOptions);
|
|
55577
55821
|
}
|
|
55822
|
+
/**
|
|
55823
|
+
* Creates a proxy for a remote agent by required capabilities.
|
|
55824
|
+
*
|
|
55825
|
+
* @param capabilities - Required capabilities for discovery.
|
|
55826
|
+
* @param options - Optional fabric configuration.
|
|
55827
|
+
* @returns A proxy for a matching remote agent.
|
|
55828
|
+
*/
|
|
55578
55829
|
static remoteByCapabilities(capabilities, options = {}) {
|
|
55579
55830
|
const remoteOptions = { capabilities };
|
|
55580
55831
|
if (options.fabric !== undefined) {
|
|
@@ -55582,6 +55833,15 @@
|
|
|
55582
55833
|
}
|
|
55583
55834
|
return this.remote(remoteOptions);
|
|
55584
55835
|
}
|
|
55836
|
+
/**
|
|
55837
|
+
* Creates an agent from a simple handler function.
|
|
55838
|
+
*
|
|
55839
|
+
* @remarks
|
|
55840
|
+
* Useful for quick prototyping without defining a full agent class.
|
|
55841
|
+
*
|
|
55842
|
+
* @param handler - Function that processes task payloads.
|
|
55843
|
+
* @returns A new agent instance wrapping the handler.
|
|
55844
|
+
*/
|
|
55585
55845
|
static async fromHandler(handler) {
|
|
55586
55846
|
if (!registeredBaseAgentCtor) {
|
|
55587
55847
|
await Promise.resolve().then(function () { return baseAgent; });
|
|
@@ -55598,10 +55858,25 @@
|
|
|
55598
55858
|
}
|
|
55599
55859
|
return new HandlerAgent();
|
|
55600
55860
|
}
|
|
55861
|
+
/**
|
|
55862
|
+
* Sends the same payload to multiple agents.
|
|
55863
|
+
*
|
|
55864
|
+
* @param addresses - List of agent addresses.
|
|
55865
|
+
* @param payload - Payload to send to all agents.
|
|
55866
|
+
* @param options - Execution options.
|
|
55867
|
+
* @returns Array of [address, result|error] tuples.
|
|
55868
|
+
*/
|
|
55601
55869
|
static async broadcast(addresses, payload = null, options = {}) {
|
|
55602
55870
|
const targets = addresses.map((address) => [address, payload]);
|
|
55603
55871
|
return this.runMany(targets, options);
|
|
55604
55872
|
}
|
|
55873
|
+
/**
|
|
55874
|
+
* Runs tasks on multiple agents with individual payloads.
|
|
55875
|
+
*
|
|
55876
|
+
* @param targets - Iterable of [address, payload] pairs.
|
|
55877
|
+
* @param options - Execution options.
|
|
55878
|
+
* @returns Array of [address, result|error] tuples.
|
|
55879
|
+
*/
|
|
55605
55880
|
static async runMany(targets, options = {}) {
|
|
55606
55881
|
const { fabric, gatherExceptions = true } = options;
|
|
55607
55882
|
const resolvedFabric = fabric ?? FameFabric.current();
|
|
@@ -55637,6 +55912,16 @@
|
|
|
55637
55912
|
return [addressKey, result.reason];
|
|
55638
55913
|
});
|
|
55639
55914
|
}
|
|
55915
|
+
/**
|
|
55916
|
+
* Starts serving this agent at the given address.
|
|
55917
|
+
*
|
|
55918
|
+
* @remarks
|
|
55919
|
+
* In Node.js, the agent listens for SIGINT/SIGTERM to shut down gracefully.
|
|
55920
|
+
* The method returns when the agent stops serving.
|
|
55921
|
+
*
|
|
55922
|
+
* @param address - The address to serve at (e.g., 'fame://my-agent').
|
|
55923
|
+
* @param options - Serve options including log level and fabric config.
|
|
55924
|
+
*/
|
|
55640
55925
|
async aserve(address, options = {}) {
|
|
55641
55926
|
// Extract logLevel, pass everything else to fabric
|
|
55642
55927
|
const { logLevel = null, ...fabricOptions } = options;
|
|
@@ -55665,6 +55950,12 @@
|
|
|
55665
55950
|
await release();
|
|
55666
55951
|
}
|
|
55667
55952
|
}
|
|
55953
|
+
/**
|
|
55954
|
+
* Alias for {@link Agent.aserve}.
|
|
55955
|
+
*
|
|
55956
|
+
* @param address - The address to serve at.
|
|
55957
|
+
* @param options - Serve options.
|
|
55958
|
+
*/
|
|
55668
55959
|
serve(address, options = {}) {
|
|
55669
55960
|
return this.aserve(address, options);
|
|
55670
55961
|
}
|
|
@@ -56098,6 +56389,7 @@
|
|
|
56098
56389
|
|
|
56099
56390
|
var _BaseAgent_instances, _BaseAgent_createTaskFromPayloadResponse;
|
|
56100
56391
|
const logger$1 = getLogger('naylence.agent.base_agent');
|
|
56392
|
+
/** @internal */
|
|
56101
56393
|
class StateContext {
|
|
56102
56394
|
constructor(acquireLock, loadState, saveState) {
|
|
56103
56395
|
this.acquireLock = acquireLock;
|
|
@@ -56329,17 +56621,20 @@
|
|
|
56329
56621
|
* ```
|
|
56330
56622
|
*/
|
|
56331
56623
|
BaseAgentState.schema = object({});
|
|
56624
|
+
/** @internal */
|
|
56332
56625
|
function camelToSnakeCase(name) {
|
|
56333
56626
|
return name
|
|
56334
56627
|
.replace(/([a-z0-9])([A-Z])/g, '$1_$2')
|
|
56335
56628
|
.replace(/([A-Z])([A-Z][a-z])/g, '$1_$2')
|
|
56336
56629
|
.toLowerCase();
|
|
56337
56630
|
}
|
|
56631
|
+
/** @internal */
|
|
56338
56632
|
function sanitizeNamespace(ns) {
|
|
56339
56633
|
const replaced = ns.replace(/[^A-Za-z0-9._-]+/g, '_').replace(/^[._-]+|[._-]+$/g, '');
|
|
56340
56634
|
const safe = replaced.length > 0 ? replaced : 'ns';
|
|
56341
56635
|
return safe.slice(0, 120);
|
|
56342
56636
|
}
|
|
56637
|
+
/** @internal */
|
|
56343
56638
|
async function delay$1(ms) {
|
|
56344
56639
|
await new Promise((resolve) => {
|
|
56345
56640
|
const timeout = globalThis.setTimeout;
|
|
@@ -56349,19 +56644,71 @@
|
|
|
56349
56644
|
timeout(resolve, ms);
|
|
56350
56645
|
});
|
|
56351
56646
|
}
|
|
56647
|
+
/** @internal */
|
|
56352
56648
|
function resolveRpcParams(params) {
|
|
56353
56649
|
if (params && typeof params === 'object') {
|
|
56354
56650
|
return params;
|
|
56355
56651
|
}
|
|
56356
56652
|
return {};
|
|
56357
56653
|
}
|
|
56654
|
+
/** @internal */
|
|
56358
56655
|
function resolveReplyTarget(explicit, params) {
|
|
56359
56656
|
const fromParams = params['reply_to'] ??
|
|
56360
56657
|
params['replyTo'];
|
|
56361
56658
|
const resolved = explicit ?? fromParams ?? null;
|
|
56362
56659
|
return resolved === undefined ? null : resolved;
|
|
56363
56660
|
}
|
|
56661
|
+
/**
|
|
56662
|
+
* Standard implementation of the {@link Agent} protocol.
|
|
56663
|
+
*
|
|
56664
|
+
* Provides built-in state management, message handling, and task lifecycle support.
|
|
56665
|
+
* Extend this class and override {@link BaseAgent.runTask} to implement your agent logic.
|
|
56666
|
+
*
|
|
56667
|
+
* @remarks
|
|
56668
|
+
* BaseAgent handles:
|
|
56669
|
+
* - JSON-RPC message routing
|
|
56670
|
+
* - State persistence with optional Zod validation
|
|
56671
|
+
* - Task creation from runTask results
|
|
56672
|
+
* - Graceful shutdown via SIGINT/SIGTERM
|
|
56673
|
+
*
|
|
56674
|
+
* For background/async task execution, use {@link BackgroundTaskAgent} instead.
|
|
56675
|
+
*
|
|
56676
|
+
* @example
|
|
56677
|
+
* ```typescript
|
|
56678
|
+
* import { BaseAgent, Payload, BaseAgentState } from '@naylence/agent-sdk';
|
|
56679
|
+
* import { z } from 'zod';
|
|
56680
|
+
*
|
|
56681
|
+
* const CounterSchema = z.object({ count: z.number() });
|
|
56682
|
+
*
|
|
56683
|
+
* class CounterState extends BaseAgentState {
|
|
56684
|
+
* static readonly schema = CounterSchema;
|
|
56685
|
+
* count = 0;
|
|
56686
|
+
* }
|
|
56687
|
+
*
|
|
56688
|
+
* class CounterAgent extends BaseAgent<CounterState> {
|
|
56689
|
+
* static STATE_MODEL = CounterState;
|
|
56690
|
+
*
|
|
56691
|
+
* async runTask(payload: Payload): Promise<number> {
|
|
56692
|
+
* return await this.withState(async (state) => {
|
|
56693
|
+
* state.count += 1;
|
|
56694
|
+
* return state.count;
|
|
56695
|
+
* });
|
|
56696
|
+
* }
|
|
56697
|
+
* }
|
|
56698
|
+
*
|
|
56699
|
+
* const agent = new CounterAgent('counter');
|
|
56700
|
+
* await agent.serve('fame://counter');
|
|
56701
|
+
* ```
|
|
56702
|
+
*
|
|
56703
|
+
* @typeParam StateT - The state model type, defaults to {@link BaseAgentState}.
|
|
56704
|
+
*/
|
|
56364
56705
|
class BaseAgent extends Agent {
|
|
56706
|
+
/**
|
|
56707
|
+
* Creates a new BaseAgent.
|
|
56708
|
+
*
|
|
56709
|
+
* @param name - Agent name. Defaults to snake_case of the class name.
|
|
56710
|
+
* @param options - Configuration options for state and storage.
|
|
56711
|
+
*/
|
|
56365
56712
|
constructor(name = null, options = {}) {
|
|
56366
56713
|
super();
|
|
56367
56714
|
_BaseAgent_instances.add(this);
|
|
@@ -56382,9 +56729,14 @@
|
|
|
56382
56729
|
this._stateKey = options.stateKey ?? 'state';
|
|
56383
56730
|
this._stateFactory = options.stateFactory ?? null;
|
|
56384
56731
|
}
|
|
56732
|
+
/**
|
|
56733
|
+
* Capabilities advertised by this agent.
|
|
56734
|
+
* Includes the standard agent capability by default.
|
|
56735
|
+
*/
|
|
56385
56736
|
get capabilities() {
|
|
56386
56737
|
return [...this._capabilities];
|
|
56387
56738
|
}
|
|
56739
|
+
/** The agent's name. */
|
|
56388
56740
|
get name() {
|
|
56389
56741
|
return this._name;
|
|
56390
56742
|
}
|
|
@@ -56393,12 +56745,18 @@
|
|
|
56393
56745
|
address: this._address?.toString() ?? null,
|
|
56394
56746
|
};
|
|
56395
56747
|
}
|
|
56748
|
+
/** The address this agent is registered at. */
|
|
56396
56749
|
get address() {
|
|
56397
56750
|
return this._address;
|
|
56398
56751
|
}
|
|
56752
|
+
/** @internal */
|
|
56399
56753
|
set address(value) {
|
|
56400
56754
|
this._address = value;
|
|
56401
56755
|
}
|
|
56756
|
+
/**
|
|
56757
|
+
* Storage provider for state persistence.
|
|
56758
|
+
* @throws Error if no storage provider is available.
|
|
56759
|
+
*/
|
|
56402
56760
|
get storageProvider() {
|
|
56403
56761
|
if (!this._storageProvider) {
|
|
56404
56762
|
if (this._node) {
|
|
@@ -56423,6 +56781,7 @@
|
|
|
56423
56781
|
// Look up the fabric from the registry (set by InProcessFameFabric.start())
|
|
56424
56782
|
this._fabric = getFabricForNode(node) ?? null;
|
|
56425
56783
|
}
|
|
56784
|
+
/** @internal */
|
|
56426
56785
|
async acquireStateLock() {
|
|
56427
56786
|
let acquiredResolve;
|
|
56428
56787
|
const acquired = new Promise((resolve) => {
|
|
@@ -56449,12 +56808,14 @@
|
|
|
56449
56808
|
});
|
|
56450
56809
|
};
|
|
56451
56810
|
}
|
|
56811
|
+
/** @internal */
|
|
56452
56812
|
ensureStateModel() {
|
|
56453
56813
|
if (this._stateModel) {
|
|
56454
56814
|
return this._stateModel;
|
|
56455
56815
|
}
|
|
56456
56816
|
throw new Error("No state model configured. Provide via Generic, STATE_MODEL, constructor 'stateModel', or 'stateFactory'.");
|
|
56457
56817
|
}
|
|
56818
|
+
/** @internal */
|
|
56458
56819
|
async ensureStateStore(modelType) {
|
|
56459
56820
|
if (this._stateStore) {
|
|
56460
56821
|
return;
|
|
@@ -56467,12 +56828,14 @@
|
|
|
56467
56828
|
const namespace = sanitizeNamespace(namespaceRaw);
|
|
56468
56829
|
this._stateStore = await provider.getKeyValueStore(modelType, namespace);
|
|
56469
56830
|
}
|
|
56831
|
+
/** @internal */
|
|
56470
56832
|
defaultStateNamespace() {
|
|
56471
56833
|
if (!this._name) {
|
|
56472
56834
|
throw new Error("Cannot derive default state namespace without agent name. Set 'name' or provide 'stateNamespace'.");
|
|
56473
56835
|
}
|
|
56474
56836
|
return `__agent_${this._name}`;
|
|
56475
56837
|
}
|
|
56838
|
+
/** @internal */
|
|
56476
56839
|
async loadStateInternal() {
|
|
56477
56840
|
if (this._stateCache) {
|
|
56478
56841
|
return this._stateCache;
|
|
@@ -56502,6 +56865,7 @@
|
|
|
56502
56865
|
this._stateCache = state;
|
|
56503
56866
|
return state;
|
|
56504
56867
|
}
|
|
56868
|
+
/** @internal */
|
|
56505
56869
|
async saveStateInternal(state) {
|
|
56506
56870
|
const modelType = this.ensureStateModel();
|
|
56507
56871
|
await this.ensureStateStore(modelType);
|
|
@@ -56513,15 +56877,45 @@
|
|
|
56513
56877
|
await this._stateStore.set(this._stateKey, state);
|
|
56514
56878
|
this._stateCache = state;
|
|
56515
56879
|
}
|
|
56880
|
+
/**
|
|
56881
|
+
* State context for lock-protected state access.
|
|
56882
|
+
*
|
|
56883
|
+
* @remarks
|
|
56884
|
+
* Prefer using {@link BaseAgent.withState} for simpler access patterns.
|
|
56885
|
+
*
|
|
56886
|
+
* @throws Error if no state model is configured.
|
|
56887
|
+
*/
|
|
56516
56888
|
get state() {
|
|
56517
56889
|
if (!this._stateModel && !this._stateFactory) {
|
|
56518
56890
|
throw new Error('No state model configured');
|
|
56519
56891
|
}
|
|
56520
56892
|
return new StateContext(() => this.acquireStateLock(), () => this.loadStateInternal(), (state) => this.saveStateInternal(state));
|
|
56521
56893
|
}
|
|
56894
|
+
/**
|
|
56895
|
+
* Executes a callback with exclusive access to the agent's state.
|
|
56896
|
+
*
|
|
56897
|
+
* State changes are automatically persisted after the callback completes.
|
|
56898
|
+
*
|
|
56899
|
+
* @param callback - Function receiving the current state.
|
|
56900
|
+
* @returns The callback's return value.
|
|
56901
|
+
*
|
|
56902
|
+
* @example
|
|
56903
|
+
* ```typescript
|
|
56904
|
+
* const count = await this.withState(async (state) => {
|
|
56905
|
+
* state.count += 1;
|
|
56906
|
+
* return state.count;
|
|
56907
|
+
* });
|
|
56908
|
+
* ```
|
|
56909
|
+
*/
|
|
56522
56910
|
async withState(callback) {
|
|
56523
56911
|
return await this.state.use(callback);
|
|
56524
56912
|
}
|
|
56913
|
+
/**
|
|
56914
|
+
* Retrieves a snapshot of the current state.
|
|
56915
|
+
*
|
|
56916
|
+
* @remarks
|
|
56917
|
+
* Returns a point-in-time copy. For modifications, use {@link BaseAgent.withState}.
|
|
56918
|
+
*/
|
|
56525
56919
|
async getState() {
|
|
56526
56920
|
const release = await this.acquireStateLock();
|
|
56527
56921
|
try {
|
|
@@ -56531,6 +56925,9 @@
|
|
|
56531
56925
|
release();
|
|
56532
56926
|
}
|
|
56533
56927
|
}
|
|
56928
|
+
/**
|
|
56929
|
+
* Deletes all persisted state for this agent.
|
|
56930
|
+
*/
|
|
56534
56931
|
async clearState() {
|
|
56535
56932
|
const release = await this.acquireStateLock();
|
|
56536
56933
|
try {
|
|
@@ -56543,6 +56940,7 @@
|
|
|
56543
56940
|
release();
|
|
56544
56941
|
}
|
|
56545
56942
|
}
|
|
56943
|
+
/** @internal */
|
|
56546
56944
|
static isRpcRequest(payload) {
|
|
56547
56945
|
if (!payload || typeof payload !== 'object') {
|
|
56548
56946
|
return false;
|
|
@@ -56557,6 +56955,7 @@
|
|
|
56557
56955
|
}
|
|
56558
56956
|
return true;
|
|
56559
56957
|
}
|
|
56958
|
+
/** @internal */
|
|
56560
56959
|
async handleMessage(envelope, _context) {
|
|
56561
56960
|
const frame = envelope.frame;
|
|
56562
56961
|
if (frame.type === 'DeliveryAck') {
|
|
@@ -56579,10 +56978,20 @@
|
|
|
56579
56978
|
}
|
|
56580
56979
|
return await this.handleRpcMessage(decoded, envelope);
|
|
56581
56980
|
}
|
|
56981
|
+
/**
|
|
56982
|
+
* Override to handle non-RPC messages.
|
|
56983
|
+
*
|
|
56984
|
+
* Called when the agent receives a message that is not a JSON-RPC request.
|
|
56985
|
+
* The default implementation logs a warning and returns null.
|
|
56986
|
+
*
|
|
56987
|
+
* @param message - The decoded message payload.
|
|
56988
|
+
* @returns Optional response to send back.
|
|
56989
|
+
*/
|
|
56582
56990
|
async onMessage(message) {
|
|
56583
56991
|
logger$1.warning('unhandled_inbound_message', { message });
|
|
56584
56992
|
return null;
|
|
56585
56993
|
}
|
|
56994
|
+
/** @internal */
|
|
56586
56995
|
async handleRpcMessage(rpcRequest, envelope) {
|
|
56587
56996
|
if (rpcRequest.method === 'tasks/sendSubscribe') {
|
|
56588
56997
|
this.startSubscriptionTask(rpcRequest, envelope.replyTo ?? null);
|
|
@@ -56619,6 +57028,7 @@
|
|
|
56619
57028
|
}.bind(this);
|
|
56620
57029
|
return generator();
|
|
56621
57030
|
}
|
|
57031
|
+
/** @internal */
|
|
56622
57032
|
startSubscriptionTask(rpcRequest, replyTo) {
|
|
56623
57033
|
const id = rpcRequest.id != null ? String(rpcRequest.id) : null;
|
|
56624
57034
|
if (!id) {
|
|
@@ -56643,6 +57053,7 @@
|
|
|
56643
57053
|
});
|
|
56644
57054
|
}
|
|
56645
57055
|
}
|
|
57056
|
+
/** @internal */
|
|
56646
57057
|
async streamSendSubscribe(rpcRequest, replyTo, signal) {
|
|
56647
57058
|
try {
|
|
56648
57059
|
const params = resolveRpcParams(rpcRequest.params);
|
|
@@ -56728,9 +57139,40 @@
|
|
|
56728
57139
|
async getTaskStatus(_params) {
|
|
56729
57140
|
throw new UnsupportedOperationException(`Agent ${this.constructor.name} does not support operation 'getTaskStatus'`);
|
|
56730
57141
|
}
|
|
57142
|
+
/**
|
|
57143
|
+
* Override to implement task execution logic.
|
|
57144
|
+
*
|
|
57145
|
+
* This is the primary extension point for agent behavior. Return the task result
|
|
57146
|
+
* or throw an error to fail the task.
|
|
57147
|
+
*
|
|
57148
|
+
* @param _payload - The task payload.
|
|
57149
|
+
* @param _id - Optional task identifier.
|
|
57150
|
+
* @returns The task result.
|
|
57151
|
+
* @throws UnsupportedOperationException if not overridden.
|
|
57152
|
+
*
|
|
57153
|
+
* @example
|
|
57154
|
+
* ```typescript
|
|
57155
|
+
* async runTask(payload: Payload): Promise<string> {
|
|
57156
|
+
* const input = typeof payload === 'string' ? payload : '';
|
|
57157
|
+
* return `Hello, ${input}!`;
|
|
57158
|
+
* }
|
|
57159
|
+
* ```
|
|
57160
|
+
*/
|
|
56731
57161
|
async runTask(_payload, _id) {
|
|
56732
57162
|
throw new UnsupportedOperationException(`Agent ${this.constructor.name} does not support operation 'runTask'`);
|
|
56733
57163
|
}
|
|
57164
|
+
/**
|
|
57165
|
+
* Initiates a task and returns its status.
|
|
57166
|
+
*
|
|
57167
|
+
* @remarks
|
|
57168
|
+
* If you override {@link BaseAgent.runTask}, this method automatically
|
|
57169
|
+
* creates a Task from the result. Override this method for custom
|
|
57170
|
+
* task lifecycle management.
|
|
57171
|
+
*
|
|
57172
|
+
* @param params - Task parameters including message and metadata.
|
|
57173
|
+
* @returns The completed task with result.
|
|
57174
|
+
* @throws Error if neither startTask nor runTask is implemented.
|
|
57175
|
+
*/
|
|
56734
57176
|
async startTask(params) {
|
|
56735
57177
|
const ctor = this.constructor;
|
|
56736
57178
|
const parts = params.message?.parts ?? [];
|
|
@@ -56758,7 +57200,9 @@
|
|
|
56758
57200
|
await super.aserve(address, options);
|
|
56759
57201
|
}
|
|
56760
57202
|
}
|
|
56761
|
-
_BaseAgent_instances = new WeakSet(), _BaseAgent_createTaskFromPayloadResponse =
|
|
57203
|
+
_BaseAgent_instances = new WeakSet(), _BaseAgent_createTaskFromPayloadResponse =
|
|
57204
|
+
/** @internal */
|
|
57205
|
+
async function _BaseAgent_createTaskFromPayloadResponse(params, payload, runner) {
|
|
56762
57206
|
const responsePayload = await runner(payload, params.id ?? null);
|
|
56763
57207
|
let sanitizedPayload = null;
|
|
56764
57208
|
if (typeof responsePayload === 'string') {
|
|
@@ -56774,6 +57218,10 @@
|
|
|
56774
57218
|
sessionId: params.sessionId ?? null,
|
|
56775
57219
|
});
|
|
56776
57220
|
};
|
|
57221
|
+
/**
|
|
57222
|
+
* Default state model class. Override in subclasses to set state type.
|
|
57223
|
+
* @internal
|
|
57224
|
+
*/
|
|
56777
57225
|
BaseAgent.STATE_MODEL = null;
|
|
56778
57226
|
registerBaseAgentConstructor(BaseAgent);
|
|
56779
57227
|
|
|
@@ -56784,8 +57232,27 @@
|
|
|
56784
57232
|
TERMINAL_TASK_STATES: TERMINAL_TASK_STATES
|
|
56785
57233
|
});
|
|
56786
57234
|
|
|
57235
|
+
/**
|
|
57236
|
+
* Agent base for running background work (polling/cron-like).
|
|
57237
|
+
*
|
|
57238
|
+
* {@link BackgroundTaskAgent} extends {@link BaseAgent} with infrastructure for
|
|
57239
|
+
* long-running, asynchronous task execution. Tasks run in the background after
|
|
57240
|
+
* being started, with status updates streamed to subscribers.
|
|
57241
|
+
*
|
|
57242
|
+
* @remarks
|
|
57243
|
+
* Use BackgroundTaskAgent when:
|
|
57244
|
+
* - Task execution takes significant time (seconds to minutes)
|
|
57245
|
+
* - You need to report progress updates during execution
|
|
57246
|
+
* - Clients should not block waiting for completion
|
|
57247
|
+
*
|
|
57248
|
+
* For simple request-response patterns, use {@link BaseAgent} instead.
|
|
57249
|
+
*
|
|
57250
|
+
* @module
|
|
57251
|
+
*/
|
|
56787
57252
|
const logger = getLogger('naylence.agent.background_task_agent');
|
|
57253
|
+
/** @internal */
|
|
56788
57254
|
const DEFAULT_EVENT_QUEUE_SIZE = 1000;
|
|
57255
|
+
/** @internal */
|
|
56789
57256
|
const END_OF_STREAM_SENTINEL = Object.freeze({
|
|
56790
57257
|
id: '__sentinel__',
|
|
56791
57258
|
status: {
|
|
@@ -56796,13 +57263,16 @@
|
|
|
56796
57263
|
final: false,
|
|
56797
57264
|
metadata: null,
|
|
56798
57265
|
});
|
|
57266
|
+
/** @internal */
|
|
56799
57267
|
const TIMEOUT_SYMBOL = Symbol('background-task-queue-timeout');
|
|
57268
|
+
/** @internal */
|
|
56800
57269
|
function monotonicSeconds() {
|
|
56801
57270
|
if (typeof performance !== 'undefined' && typeof performance.now === 'function') {
|
|
56802
57271
|
return performance.now() / 1000;
|
|
56803
57272
|
}
|
|
56804
57273
|
return Date.now() / 1000;
|
|
56805
57274
|
}
|
|
57275
|
+
/** @internal */
|
|
56806
57276
|
async function delay(ms) {
|
|
56807
57277
|
await new Promise((resolve) => {
|
|
56808
57278
|
const timeout = globalThis.setTimeout;
|
|
@@ -56812,6 +57282,7 @@
|
|
|
56812
57282
|
timeout(resolve, ms);
|
|
56813
57283
|
});
|
|
56814
57284
|
}
|
|
57285
|
+
/** @internal */
|
|
56815
57286
|
class AsyncEventQueue {
|
|
56816
57287
|
constructor(maxSize) {
|
|
56817
57288
|
this.maxSize = maxSize;
|
|
@@ -56854,6 +57325,7 @@
|
|
|
56854
57325
|
}
|
|
56855
57326
|
}
|
|
56856
57327
|
}
|
|
57328
|
+
/** @internal */
|
|
56857
57329
|
function createTaskFromStatus(id, status) {
|
|
56858
57330
|
return {
|
|
56859
57331
|
id,
|
|
@@ -56864,6 +57336,7 @@
|
|
|
56864
57336
|
metadata: null,
|
|
56865
57337
|
};
|
|
56866
57338
|
}
|
|
57339
|
+
/** @internal */
|
|
56867
57340
|
function errorToString(error) {
|
|
56868
57341
|
if (error instanceof Error) {
|
|
56869
57342
|
return error.message || error.toString();
|
|
@@ -56878,19 +57351,75 @@
|
|
|
56878
57351
|
return String(error);
|
|
56879
57352
|
}
|
|
56880
57353
|
}
|
|
57354
|
+
/**
|
|
57355
|
+
* Base class for agents that execute long-running background tasks.
|
|
57356
|
+
*
|
|
57357
|
+
* Unlike {@link BaseAgent} which runs tasks synchronously in startTask,
|
|
57358
|
+
* BackgroundTaskAgent starts tasks in the background and streams status
|
|
57359
|
+
* updates to subscribers. This is ideal for work that takes significant time.
|
|
57360
|
+
*
|
|
57361
|
+
* @remarks
|
|
57362
|
+
* Lifecycle:
|
|
57363
|
+
* 1. Client calls startTask, which returns immediately with WORKING status
|
|
57364
|
+
* 2. runBackgroundTask executes asynchronously
|
|
57365
|
+
* 3. Status updates are queued and delivered to subscribers
|
|
57366
|
+
* 4. Task completes with COMPLETED, FAILED, or CANCELED status
|
|
57367
|
+
*
|
|
57368
|
+
* Completed tasks are cached briefly for late subscribers to retrieve final status.
|
|
57369
|
+
*
|
|
57370
|
+
* @example
|
|
57371
|
+
* ```typescript
|
|
57372
|
+
* import {
|
|
57373
|
+
* BackgroundTaskAgent,
|
|
57374
|
+
* TaskSendParams,
|
|
57375
|
+
* TaskState,
|
|
57376
|
+
* } from '@naylence/agent-sdk';
|
|
57377
|
+
*
|
|
57378
|
+
* class SlowAgent extends BackgroundTaskAgent {
|
|
57379
|
+
* protected async runBackgroundTask(params: TaskSendParams): Promise<string> {
|
|
57380
|
+
* // Report progress
|
|
57381
|
+
* await this.updateTaskState(params.id, TaskState.WORKING);
|
|
57382
|
+
*
|
|
57383
|
+
* // Do expensive work
|
|
57384
|
+
* await someSlowOperation();
|
|
57385
|
+
*
|
|
57386
|
+
* // Return value becomes the task result
|
|
57387
|
+
* return 'done';
|
|
57388
|
+
* }
|
|
57389
|
+
* }
|
|
57390
|
+
*
|
|
57391
|
+
* const agent = new SlowAgent('slow-worker', {
|
|
57392
|
+
* maxTaskLifetimeMs: 60_000, // 1 minute timeout
|
|
57393
|
+
* });
|
|
57394
|
+
* await agent.serve('fame://slow-worker');
|
|
57395
|
+
* ```
|
|
57396
|
+
*
|
|
57397
|
+
* @typeParam StateT - The state model type, defaults to {@link BaseAgentState}.
|
|
57398
|
+
*/
|
|
56881
57399
|
class BackgroundTaskAgent extends BaseAgent {
|
|
57400
|
+
/**
|
|
57401
|
+
* Creates a new BackgroundTaskAgent.
|
|
57402
|
+
*
|
|
57403
|
+
* @param name - Agent name. Defaults to snake_case of the class name.
|
|
57404
|
+
* @param options - Configuration options for task execution and caching.
|
|
57405
|
+
*/
|
|
56882
57406
|
constructor(name = null, options = {}) {
|
|
56883
57407
|
const { maxQueueSize = DEFAULT_EVENT_QUEUE_SIZE, maxTaskLifetimeMs = null, completedCacheSize = 100, completedCacheTtlSec = 300, ...baseOptions } = options;
|
|
56884
57408
|
super(name, baseOptions);
|
|
57409
|
+
/** @internal */
|
|
56885
57410
|
this.taskStatuses = new Map();
|
|
57411
|
+
/** @internal */
|
|
56886
57412
|
this.taskEventQueues = new Map();
|
|
57413
|
+
/** @internal */
|
|
56887
57414
|
this.completed = new Map();
|
|
57415
|
+
/** @internal */
|
|
56888
57416
|
this.statusLock = new AsyncLock();
|
|
56889
57417
|
this.maxQueueSize = maxQueueSize;
|
|
56890
57418
|
this.maxTaskLifetimeMs = maxTaskLifetimeMs;
|
|
56891
57419
|
this.completedCacheSize = completedCacheSize;
|
|
56892
57420
|
this.completedCacheTtlSec = completedCacheTtlSec;
|
|
56893
57421
|
}
|
|
57422
|
+
/** @internal */
|
|
56894
57423
|
isTerminalTaskState(taskId) {
|
|
56895
57424
|
const status = this.taskStatuses.get(taskId);
|
|
56896
57425
|
if (status && TERMINAL_TASK_STATES.has(status.state)) {
|
|
@@ -56898,6 +57427,15 @@
|
|
|
56898
57427
|
}
|
|
56899
57428
|
return this.completed.has(taskId);
|
|
56900
57429
|
}
|
|
57430
|
+
/**
|
|
57431
|
+
* Starts a background task.
|
|
57432
|
+
*
|
|
57433
|
+
* Returns immediately with WORKING status. The task executes asynchronously
|
|
57434
|
+
* via {@link BackgroundTaskAgent.runBackgroundTask}.
|
|
57435
|
+
*
|
|
57436
|
+
* @param params - Task parameters.
|
|
57437
|
+
* @returns The task with initial WORKING status.
|
|
57438
|
+
*/
|
|
56901
57439
|
async startTask(params) {
|
|
56902
57440
|
this.taskEventQueues.set(params.id, new AsyncEventQueue(this.maxQueueSize));
|
|
56903
57441
|
await this.updateTaskState(params.id, exports.TaskState.WORKING);
|
|
@@ -56907,6 +57445,7 @@
|
|
|
56907
57445
|
}
|
|
56908
57446
|
return await this.getTaskStatus({ id: params.id });
|
|
56909
57447
|
}
|
|
57448
|
+
/** @internal */
|
|
56910
57449
|
async enforceMaxLifetime(taskId) {
|
|
56911
57450
|
if (this.maxTaskLifetimeMs === null) {
|
|
56912
57451
|
return;
|
|
@@ -56920,6 +57459,7 @@
|
|
|
56920
57459
|
await queue.put(END_OF_STREAM_SENTINEL);
|
|
56921
57460
|
}
|
|
56922
57461
|
}
|
|
57462
|
+
/** @internal */
|
|
56923
57463
|
async runBackgroundTaskInternal(params) {
|
|
56924
57464
|
try {
|
|
56925
57465
|
const result = await this.runBackgroundTask(params);
|
|
@@ -56942,6 +57482,12 @@
|
|
|
56942
57482
|
}
|
|
56943
57483
|
}
|
|
56944
57484
|
}
|
|
57485
|
+
/**
|
|
57486
|
+
* Gets the current state of a task.
|
|
57487
|
+
*
|
|
57488
|
+
* @param taskId - The task identifier.
|
|
57489
|
+
* @returns The current task state, or UNKNOWN if not found.
|
|
57490
|
+
*/
|
|
56945
57491
|
async getTaskState(taskId) {
|
|
56946
57492
|
try {
|
|
56947
57493
|
const task = await this.getTaskStatus({ id: taskId });
|
|
@@ -56951,6 +57497,13 @@
|
|
|
56951
57497
|
return exports.TaskState.UNKNOWN;
|
|
56952
57498
|
}
|
|
56953
57499
|
}
|
|
57500
|
+
/**
|
|
57501
|
+
* Retrieves the full status of a task.
|
|
57502
|
+
*
|
|
57503
|
+
* @param params - Query parameters including the task ID.
|
|
57504
|
+
* @returns The task with current status.
|
|
57505
|
+
* @throws Error if the task is unknown or expired.
|
|
57506
|
+
*/
|
|
56954
57507
|
async getTaskStatus(params) {
|
|
56955
57508
|
return await this.statusLock.runExclusive(async () => {
|
|
56956
57509
|
const status = this.taskStatuses.get(params.id);
|
|
@@ -56967,6 +57520,17 @@
|
|
|
56967
57520
|
throw new Error(`Unknown or expired task ${params.id}`);
|
|
56968
57521
|
});
|
|
56969
57522
|
}
|
|
57523
|
+
/**
|
|
57524
|
+
* Updates the state of a running task.
|
|
57525
|
+
*
|
|
57526
|
+
* Call this from {@link BackgroundTaskAgent.runBackgroundTask} to report progress.
|
|
57527
|
+
* Status updates are delivered to subscribers.
|
|
57528
|
+
*
|
|
57529
|
+
* @param taskId - The task identifier.
|
|
57530
|
+
* @param state - The new task state.
|
|
57531
|
+
* @param message - Optional message with details.
|
|
57532
|
+
* @returns True if the update was applied, false if the task is already terminal.
|
|
57533
|
+
*/
|
|
56970
57534
|
async updateTaskState(taskId, state, message) {
|
|
56971
57535
|
return await this.statusLock.runExclusive(async () => {
|
|
56972
57536
|
if (this.isTerminalTaskState(taskId)) {
|
|
@@ -56998,6 +57562,7 @@
|
|
|
56998
57562
|
return true;
|
|
56999
57563
|
});
|
|
57000
57564
|
}
|
|
57565
|
+
/** @internal */
|
|
57001
57566
|
addToCompleted(taskId, status) {
|
|
57002
57567
|
if (this.completedCacheSize <= 0) {
|
|
57003
57568
|
return;
|
|
@@ -57017,6 +57582,14 @@
|
|
|
57017
57582
|
timestamp: monotonicSeconds(),
|
|
57018
57583
|
});
|
|
57019
57584
|
}
|
|
57585
|
+
/**
|
|
57586
|
+
* Emits an artifact for a running task.
|
|
57587
|
+
*
|
|
57588
|
+
* Artifacts are delivered to subscribers as TaskArtifactUpdateEvents.
|
|
57589
|
+
*
|
|
57590
|
+
* @param taskId - The task identifier.
|
|
57591
|
+
* @param artifact - The artifact to emit.
|
|
57592
|
+
*/
|
|
57020
57593
|
async updateTaskArtifact(taskId, artifact) {
|
|
57021
57594
|
const queue = this.taskEventQueues.get(taskId);
|
|
57022
57595
|
if (!queue) {
|
|
@@ -57030,6 +57603,15 @@
|
|
|
57030
57603
|
};
|
|
57031
57604
|
await queue.put(event);
|
|
57032
57605
|
}
|
|
57606
|
+
/**
|
|
57607
|
+
* Subscribes to updates for a task.
|
|
57608
|
+
*
|
|
57609
|
+
* Returns an async iterable that yields status and artifact events.
|
|
57610
|
+
* For completed tasks, yields the cached final status if still available.
|
|
57611
|
+
*
|
|
57612
|
+
* @param params - Task parameters including the task ID.
|
|
57613
|
+
* @returns Async iterable of task events.
|
|
57614
|
+
*/
|
|
57033
57615
|
subscribeToTaskUpdates(params) {
|
|
57034
57616
|
const queue = this.taskEventQueues.get(params.id);
|
|
57035
57617
|
const self = this;
|
|
@@ -57073,6 +57655,11 @@
|
|
|
57073
57655
|
};
|
|
57074
57656
|
return stream();
|
|
57075
57657
|
}
|
|
57658
|
+
/**
|
|
57659
|
+
* Cancels a task subscription.
|
|
57660
|
+
*
|
|
57661
|
+
* @param params - Parameters including the task ID.
|
|
57662
|
+
*/
|
|
57076
57663
|
async unsubscribeTask(params) {
|
|
57077
57664
|
const queue = this.taskEventQueues.get(params.id);
|
|
57078
57665
|
if (queue) {
|
|
@@ -57080,15 +57667,26 @@
|
|
|
57080
57667
|
await queue.put(END_OF_STREAM_SENTINEL);
|
|
57081
57668
|
}
|
|
57082
57669
|
}
|
|
57670
|
+
/**
|
|
57671
|
+
* Cancels a running task.
|
|
57672
|
+
*
|
|
57673
|
+
* Sets the task state to CANCELED. Does not interrupt runBackgroundTask,
|
|
57674
|
+
* but prevents further state updates.
|
|
57675
|
+
*
|
|
57676
|
+
* @param params - Parameters including the task ID.
|
|
57677
|
+
* @returns The task with CANCELED status.
|
|
57678
|
+
*/
|
|
57083
57679
|
async cancelTask(params) {
|
|
57084
57680
|
await this.updateTaskState(params.id, exports.TaskState.CANCELED);
|
|
57085
57681
|
return await this.getTaskStatus({ id: params.id });
|
|
57086
57682
|
}
|
|
57683
|
+
/** @internal */
|
|
57087
57684
|
async purgeCompletedAfterTtl(taskId) {
|
|
57088
57685
|
await delay(this.completedCacheTtlSec * 1000);
|
|
57089
57686
|
this.completed.delete(taskId);
|
|
57090
57687
|
this.taskEventQueues.delete(taskId);
|
|
57091
57688
|
}
|
|
57689
|
+
/** @internal */
|
|
57092
57690
|
normalizeResultPayload(result) {
|
|
57093
57691
|
if (result === null || result === undefined) {
|
|
57094
57692
|
return null;
|
|
@@ -57103,15 +57701,31 @@
|
|
|
57103
57701
|
}
|
|
57104
57702
|
}
|
|
57105
57703
|
|
|
57704
|
+
/**
|
|
57705
|
+
* Agent proxy module for remote agent communication.
|
|
57706
|
+
*
|
|
57707
|
+
* An {@link AgentProxy} is a client-side handle for invoking methods on a remote
|
|
57708
|
+
* agent. Use it when you need to call an agent that lives in another process,
|
|
57709
|
+
* container, or network location.
|
|
57710
|
+
*
|
|
57711
|
+
* @remarks
|
|
57712
|
+
* Create proxies via {@link Agent.remote}, {@link Agent.remoteByAddress}, or
|
|
57713
|
+
* {@link Agent.remoteByCapabilities} rather than instantiating AgentProxy directly.
|
|
57714
|
+
*
|
|
57715
|
+
* @module
|
|
57716
|
+
*/
|
|
57717
|
+
/** @internal */
|
|
57106
57718
|
function toRecord(value) {
|
|
57107
57719
|
if (!value || typeof value !== 'object') {
|
|
57108
57720
|
return {};
|
|
57109
57721
|
}
|
|
57110
57722
|
return value;
|
|
57111
57723
|
}
|
|
57724
|
+
/** @internal */
|
|
57112
57725
|
function toFameAddress(address) {
|
|
57113
57726
|
return address instanceof FameAddress ? address : new FameAddress(String(address));
|
|
57114
57727
|
}
|
|
57728
|
+
/** @internal */
|
|
57115
57729
|
function wrapAgentProxy(proxy) {
|
|
57116
57730
|
// Create RPC proxy options - only include address or capabilities, not both
|
|
57117
57731
|
const proxyOptions = {
|
|
@@ -57140,6 +57754,7 @@
|
|
|
57140
57754
|
},
|
|
57141
57755
|
});
|
|
57142
57756
|
}
|
|
57757
|
+
/** @internal */
|
|
57143
57758
|
async function nextWithTimeout(iterator, timeoutMs) {
|
|
57144
57759
|
if (timeoutMs == null) {
|
|
57145
57760
|
return await iterator.next();
|
|
@@ -57157,7 +57772,44 @@
|
|
|
57157
57772
|
}
|
|
57158
57773
|
}
|
|
57159
57774
|
}
|
|
57775
|
+
/**
|
|
57776
|
+
* Client-side proxy for communicating with remote agents.
|
|
57777
|
+
*
|
|
57778
|
+
* AgentProxy implements the {@link Agent} interface, allowing you to call
|
|
57779
|
+
* remote agents as if they were local objects. Method calls are serialized
|
|
57780
|
+
* and sent over the Fame fabric.
|
|
57781
|
+
*
|
|
57782
|
+
* @remarks
|
|
57783
|
+
* Do not instantiate AgentProxy directly. Use the factory methods on
|
|
57784
|
+
* {@link Agent} to create proxies:
|
|
57785
|
+
* - {@link Agent.remote} for flexible options
|
|
57786
|
+
* - {@link Agent.remoteByAddress} for direct addressing
|
|
57787
|
+
* - {@link Agent.remoteByCapabilities} for capability-based discovery
|
|
57788
|
+
*
|
|
57789
|
+
* The proxy also supports arbitrary RPC method calls. Any method not defined
|
|
57790
|
+
* on the proxy class is forwarded as an RPC call to the remote agent.
|
|
57791
|
+
*
|
|
57792
|
+
* @example
|
|
57793
|
+
* ```typescript
|
|
57794
|
+
* import { Agent } from '@naylence/agent-sdk';
|
|
57795
|
+
*
|
|
57796
|
+
* // Create a proxy to a remote agent
|
|
57797
|
+
* const proxy = Agent.remoteByAddress('fame://calculator');
|
|
57798
|
+
*
|
|
57799
|
+
* // Run a task synchronously
|
|
57800
|
+
* const result = await proxy.runTask({ a: 1, b: 2 });
|
|
57801
|
+
*
|
|
57802
|
+
* // Or start a task and poll for completion
|
|
57803
|
+
* const task = await proxy.startTask({
|
|
57804
|
+
* id: 'task-1',
|
|
57805
|
+
* message: { role: 'user', parts: [{ type: 'text', text: 'compute' }] },
|
|
57806
|
+
* });
|
|
57807
|
+
* ```
|
|
57808
|
+
*
|
|
57809
|
+
* @typeParam TAgent - The type of the remote agent for result typing.
|
|
57810
|
+
*/
|
|
57160
57811
|
class AgentProxy extends Agent {
|
|
57812
|
+
/** @internal */
|
|
57161
57813
|
constructor(options) {
|
|
57162
57814
|
const { address = null, capabilities = null, intentNl = null, fabric } = options;
|
|
57163
57815
|
const provided = Number(address != null) + Number(capabilities != null) + Number(intentNl != null);
|
|
@@ -57173,9 +57825,11 @@
|
|
|
57173
57825
|
this.intentNl = intentNl;
|
|
57174
57826
|
this.fabric = fabric;
|
|
57175
57827
|
}
|
|
57828
|
+
/** Returns null as proxies do not have a local name. */
|
|
57176
57829
|
get name() {
|
|
57177
57830
|
return null;
|
|
57178
57831
|
}
|
|
57832
|
+
/** Returns the proxy's targeting specification. */
|
|
57179
57833
|
get spec() {
|
|
57180
57834
|
const spec = {
|
|
57181
57835
|
address: this.targetAddress ? this.targetAddress.toString() : null,
|
|
@@ -57188,15 +57842,22 @@
|
|
|
57188
57842
|
}
|
|
57189
57843
|
return spec;
|
|
57190
57844
|
}
|
|
57845
|
+
/**
|
|
57846
|
+
* The target agent's address, if specified.
|
|
57847
|
+
* @deprecated Use {@link AgentProxy.address} instead.
|
|
57848
|
+
*/
|
|
57191
57849
|
get addressRef() {
|
|
57192
57850
|
return this.targetAddress;
|
|
57193
57851
|
}
|
|
57852
|
+
/** The target agent's address, if specified. */
|
|
57194
57853
|
get address() {
|
|
57195
57854
|
return this.targetAddress;
|
|
57196
57855
|
}
|
|
57856
|
+
/** The required capabilities for discovery, if specified. */
|
|
57197
57857
|
get capabilities() {
|
|
57198
57858
|
return this.targetCapabilities ?? undefined;
|
|
57199
57859
|
}
|
|
57860
|
+
/** The fabric this proxy uses for communication. */
|
|
57200
57861
|
get proxyFabric() {
|
|
57201
57862
|
return this.fabric;
|
|
57202
57863
|
}
|
|
@@ -57206,6 +57867,24 @@
|
|
|
57206
57867
|
authenticate(_credentials) {
|
|
57207
57868
|
throw new Error('Proxy authentication is not supported');
|
|
57208
57869
|
}
|
|
57870
|
+
/**
|
|
57871
|
+
* Executes a task on the remote agent and waits for completion.
|
|
57872
|
+
*
|
|
57873
|
+
* Starts the task, subscribes to updates, and returns when the task reaches
|
|
57874
|
+
* a terminal state (completed, failed, or canceled).
|
|
57875
|
+
*
|
|
57876
|
+
* @param payload - The task payload to send.
|
|
57877
|
+
* @param id - Optional task identifier. Generated if not provided.
|
|
57878
|
+
* @returns The task result extracted from the final status message.
|
|
57879
|
+
* @throws Error if the task fails.
|
|
57880
|
+
*
|
|
57881
|
+
* @example
|
|
57882
|
+
* ```typescript
|
|
57883
|
+
* const proxy = Agent.remoteByAddress('fame://echo');
|
|
57884
|
+
* const result = await proxy.runTask('hello');
|
|
57885
|
+
* console.log(result); // 'hello'
|
|
57886
|
+
* ```
|
|
57887
|
+
*/
|
|
57209
57888
|
async runTask(payload = null, id = null) {
|
|
57210
57889
|
const taskId = id ?? generateId();
|
|
57211
57890
|
const params = makeTaskParams({ id: taskId, payload });
|
|
@@ -57279,16 +57958,38 @@
|
|
|
57279
57958
|
const result = await this._invokeTarget('tasks/send', params);
|
|
57280
57959
|
return TaskSchema.parse(result);
|
|
57281
57960
|
}
|
|
57961
|
+
/**
|
|
57962
|
+
* Retrieves the current status of a task.
|
|
57963
|
+
*
|
|
57964
|
+
* @param params - Query parameters including the task ID.
|
|
57965
|
+
* @returns The task with current status.
|
|
57966
|
+
*/
|
|
57282
57967
|
async getTaskStatus(params) {
|
|
57283
57968
|
const payload = TaskQueryParamsSchema.parse(params);
|
|
57284
57969
|
const result = await this._invokeTarget('tasks/get', payload);
|
|
57285
57970
|
return TaskSchema.parse(result);
|
|
57286
57971
|
}
|
|
57972
|
+
/**
|
|
57973
|
+
* Requests cancellation of a running task.
|
|
57974
|
+
*
|
|
57975
|
+
* @param params - Parameters including the task ID.
|
|
57976
|
+
* @returns The task with updated status.
|
|
57977
|
+
*/
|
|
57287
57978
|
async cancelTask(params) {
|
|
57288
57979
|
const payload = TaskIdParamsSchema.parse(params);
|
|
57289
57980
|
const result = await this._invokeTarget('tasks/cancel', payload);
|
|
57290
57981
|
return TaskSchema.parse(result);
|
|
57291
57982
|
}
|
|
57983
|
+
/**
|
|
57984
|
+
* Subscribes to real-time updates for a task.
|
|
57985
|
+
*
|
|
57986
|
+
* Returns an async iterable that yields status and artifact events
|
|
57987
|
+
* until the task reaches a terminal state or the stream is closed.
|
|
57988
|
+
*
|
|
57989
|
+
* @param params - Task parameters.
|
|
57990
|
+
* @param options - Optional timeout and item limit settings.
|
|
57991
|
+
* @returns Async iterable of task events.
|
|
57992
|
+
*/
|
|
57292
57993
|
subscribeToTaskUpdates(params, options = {}) {
|
|
57293
57994
|
const payload = TaskSendParamsSchema.parse(params);
|
|
57294
57995
|
return this._streamRpc('tasks/sendSubscribe', payload, (frame) => {
|
|
@@ -57298,20 +57999,38 @@
|
|
|
57298
57999
|
return TaskStatusUpdateEventSchema.parse(frame);
|
|
57299
58000
|
}, 'tasks/sendUnsubscribe', TaskIdParamsSchema.parse({ id: payload.id }), options);
|
|
57300
58001
|
}
|
|
58002
|
+
/**
|
|
58003
|
+
* Cancels a task subscription.
|
|
58004
|
+
*
|
|
58005
|
+
* @param params - Parameters including the task ID.
|
|
58006
|
+
*/
|
|
57301
58007
|
async unsubscribeTask(params) {
|
|
57302
58008
|
const payload = TaskIdParamsSchema.parse(params);
|
|
57303
58009
|
return await this._invokeTarget('tasks/sendUnsubscribe', payload);
|
|
57304
58010
|
}
|
|
58011
|
+
/**
|
|
58012
|
+
* Registers a push notification endpoint for task updates.
|
|
58013
|
+
*
|
|
58014
|
+
* @param config - Push notification configuration.
|
|
58015
|
+
* @returns The registered configuration.
|
|
58016
|
+
*/
|
|
57305
58017
|
async registerPushEndpoint(config) {
|
|
57306
58018
|
const payload = TaskPushNotificationConfigSchema.parse(config);
|
|
57307
58019
|
const result = await this._invokeTarget('tasks/pushNotification/set', payload);
|
|
57308
58020
|
return TaskPushNotificationConfigSchema.parse(result ?? payload);
|
|
57309
58021
|
}
|
|
58022
|
+
/**
|
|
58023
|
+
* Retrieves the push notification config for a task.
|
|
58024
|
+
*
|
|
58025
|
+
* @param params - Parameters including the task ID.
|
|
58026
|
+
* @returns The push notification configuration.
|
|
58027
|
+
*/
|
|
57310
58028
|
async getPushNotificationConfig(params) {
|
|
57311
58029
|
const payload = TaskIdParamsSchema.parse(params);
|
|
57312
58030
|
const result = await this._invokeTarget('tasks/pushNotification/get', payload);
|
|
57313
58031
|
return TaskPushNotificationConfigSchema.parse(result ?? payload);
|
|
57314
58032
|
}
|
|
58033
|
+
/** @internal */
|
|
57315
58034
|
_streamRpc(method, params, parseFrame, unsubscribeMethod, unsubscribeParams, options) {
|
|
57316
58035
|
const self = this;
|
|
57317
58036
|
return {
|
|
@@ -57380,6 +58099,7 @@
|
|
|
57380
58099
|
},
|
|
57381
58100
|
};
|
|
57382
58101
|
}
|
|
58102
|
+
/** @internal */
|
|
57383
58103
|
async _invokeTarget(method, params, options = {}) {
|
|
57384
58104
|
if (this.intentNl) {
|
|
57385
58105
|
throw new Error('Intent-based routing not yet supported');
|
|
@@ -57399,10 +58119,18 @@
|
|
|
57399
58119
|
}
|
|
57400
58120
|
throw new Error('Proxy has no routing target');
|
|
57401
58121
|
}
|
|
58122
|
+
/**
|
|
58123
|
+
* Creates a proxy for a remote agent by address.
|
|
58124
|
+
* @internal Use {@link Agent.remoteByAddress} instead.
|
|
58125
|
+
*/
|
|
57402
58126
|
static remoteByAddress(address, options) {
|
|
57403
58127
|
const proxy = new AgentProxy({ address, fabric: options.fabric });
|
|
57404
58128
|
return wrapAgentProxy(proxy);
|
|
57405
58129
|
}
|
|
58130
|
+
/**
|
|
58131
|
+
* Creates a proxy for a remote agent by capabilities.
|
|
58132
|
+
* @internal Use {@link Agent.remoteByCapabilities} instead.
|
|
58133
|
+
*/
|
|
57406
58134
|
static remoteByCapabilities(capabilities, options) {
|
|
57407
58135
|
const proxy = new AgentProxy({ capabilities, fabric: options.fabric });
|
|
57408
58136
|
return wrapAgentProxy(proxy);
|