@zlink-systems/framework 0.28.0 → 0.29.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.tsbuildinfo +1 -1
- package/dist/contracts/Configuration/Builders.d.ts +2 -0
- package/dist/contracts/Configuration/InternalDefaults.d.ts +3 -0
- package/dist/contracts/Configuration/InternalDefaults.js +4 -1
- package/dist/contracts/Configuration/RegistrationBuilders.js +9 -0
- package/dist/contracts/Configuration/RegistrationNormalizers.d.ts +1 -0
- package/dist/contracts/Configuration/RegistrationNormalizers.js +16 -0
- package/dist/contracts/Configuration/RegistrationTypes.d.ts +3 -0
- package/dist/runtime/actors/actor-mailbox.d.ts +2 -2
- package/dist/runtime/actors/actor-mailbox.js +2 -2
- package/dist/runtime/actors/actor-runtime-contracts.d.ts +1 -0
- package/dist/runtime/actors/index.d.ts +2 -0
- package/dist/runtime/actors/index.js +21 -6
- package/dist/runtime/backend/node/node-raw-mesh-backend.js +1 -3
- package/dist/runtime/execution/serial-execution-queue.d.ts +12 -3
- package/dist/runtime/execution/serial-execution-queue.js +116 -28
- package/dist/runtime/foundation/operation-registry.d.ts +3 -2
- package/dist/runtime/foundation/operation-registry.js +5 -1
- package/dist/runtime/foundation/service-authority-payload-codec.d.ts +0 -2
- package/dist/runtime/foundation/service-authority-payload-codec.js +0 -43
- package/dist/runtime/foundation/service-stateful-registry.d.ts +4 -3
- package/dist/runtime/foundation/service-stateful-registry.js +5 -2
- package/dist/runtime/foundation/service-stateful-runtime.d.ts +1 -8
- package/dist/runtime/foundation/service-stateful-runtime.js +105 -145
- package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +0 -11
- package/dist/runtime/foundation/service-stateful-wire-codec.js +1 -23
- package/dist/runtime/foundation/service-topology-registry.d.ts +5 -0
- package/dist/runtime/foundation/service-topology-registry.js +16 -17
- package/dist/runtime/handlers/handler-instance-scope.js +1 -1
- package/dist/runtime/host/actor-placement-coordinator.d.ts +2 -1
- package/dist/runtime/host/actor-placement-coordinator.js +2 -1
- package/dist/runtime/host/actor-runtime-options-factory.d.ts +2 -1
- package/dist/runtime/host/actor-runtime-options-factory.js +1 -0
- package/dist/runtime/host/index.d.ts +1 -1
- package/dist/runtime/host/index.js +3 -2
- package/dist/runtime/host/instance-activation-authority.d.ts +0 -1
- package/dist/runtime/host/instance-activation-authority.js +46 -97
- package/dist/runtime/host/spot-address-transport.js +1 -1
- package/dist/runtime/host/stateful-authority-route-runtime.d.ts +1 -0
- package/dist/runtime/host/stateful-authority-route-runtime.js +17 -9
- package/dist/runtime/locations/domain-store-contract.d.ts +3 -1
- package/dist/runtime/locations/in-memory-authority-store.d.ts +3 -0
- package/dist/runtime/locations/in-memory-authority-store.js +47 -12
- package/dist/runtime/locations/in-memory-location-store.d.ts +2 -1
- package/dist/runtime/locations/in-memory-location-store.js +15 -10
- package/dist/runtime/locations/internal-location-contracts.d.ts +5 -0
- package/dist/runtime/locations/internal-store-contracts.d.ts +1 -1
- package/dist/runtime/locations/location-store-repository.d.ts +2 -0
- package/dist/runtime/locations/location-store-repository.js +130 -54
- package/dist/runtime/spots/spot-entry-activation.d.ts +1 -0
- package/dist/runtime/spots/spot-entry-activation.js +3 -0
- package/dist/runtime/spots/spot-node-runtime-manager.d.ts +1 -0
- package/dist/runtime/spots/spot-node-runtime-manager.js +6 -0
- package/dist/runtime/spots/spot-serial-executor.d.ts +1 -0
- package/dist/runtime/spots/spot-serial-executor.js +14 -2
- package/dist/runtime/spots/spot-serial-turn-executor.d.ts +3 -0
- package/dist/runtime/spots/spot-serial-turn-executor.js +5 -0
- package/dist/runtime/streams/index.d.ts +0 -1
- package/dist/runtime/streams/index.js +4 -3
- package/dist/runtime/streams/protocol.js +0 -9
- package/dist/runtime/streams/session-context.d.ts +0 -4
- package/dist/runtime/streams/session-context.js +0 -26
- package/dist/runtime/streams/session-serial-executor.d.ts +0 -1
- package/dist/runtime/streams/session-serial-executor.js +0 -3
- package/dist/runtime/streams/stream-message-utils.d.ts +0 -1
- package/dist/runtime/streams/stream-message-utils.js +0 -20
- package/dist/runtime/streams/stream-session-runtime.d.ts +6 -3
- package/dist/runtime/streams/stream-session-runtime.js +40 -85
- package/package.json +3 -3
- package/src/contracts/Configuration/Builders.ts +2 -0
- package/src/contracts/Configuration/InternalDefaults.ts +4 -0
- package/src/contracts/Configuration/RegistrationBuilders.ts +13 -0
- package/src/contracts/Configuration/RegistrationNormalizers.ts +25 -0
- package/src/contracts/Configuration/RegistrationTypes.ts +3 -0
- package/src/runtime/actors/actor-mailbox.ts +7 -2
- package/src/runtime/actors/actor-runtime-contracts.ts +4 -0
- package/src/runtime/actors/index.ts +77 -42
- package/src/runtime/backend/node/node-raw-mesh-backend.ts +1 -7
- package/src/runtime/execution/serial-execution-queue.ts +117 -29
- package/src/runtime/foundation/operation-registry.ts +16 -9
- package/src/runtime/foundation/service-authority-payload-codec.ts +0 -46
- package/src/runtime/foundation/service-stateful-registry.ts +10 -5
- package/src/runtime/foundation/service-stateful-runtime.ts +152 -224
- package/src/runtime/foundation/service-stateful-wire-codec.ts +0 -25
- package/src/runtime/foundation/service-topology-registry.ts +30 -20
- package/src/runtime/handlers/handler-instance-scope.ts +2 -1
- package/src/runtime/host/actor-placement-coordinator.ts +8 -2
- package/src/runtime/host/actor-runtime-options-factory.ts +6 -0
- package/src/runtime/host/index.ts +6 -2
- package/src/runtime/host/instance-activation-authority.ts +58 -125
- package/src/runtime/host/spot-address-transport.ts +1 -1
- package/src/runtime/host/stateful-authority-route-runtime.ts +22 -9
- package/src/runtime/locations/domain-store-contract.ts +6 -1
- package/src/runtime/locations/in-memory-authority-store.ts +83 -12
- package/src/runtime/locations/in-memory-location-store.ts +22 -10
- package/src/runtime/locations/internal-location-contracts.ts +6 -0
- package/src/runtime/locations/internal-store-contracts.ts +1 -0
- package/src/runtime/locations/location-store-repository.ts +182 -69
- package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +1 -1
- package/src/runtime/spots/spot-entry-activation.ts +4 -0
- package/src/runtime/spots/spot-node-runtime-manager.ts +7 -0
- package/src/runtime/spots/spot-serial-executor.ts +14 -5
- package/src/runtime/spots/spot-serial-turn-executor.ts +10 -0
- package/src/runtime/streams/index.ts +3 -1
- package/src/runtime/streams/protocol.ts +0 -13
- package/src/runtime/streams/session-context.ts +0 -32
- package/src/runtime/streams/session-serial-executor.ts +0 -8
- package/src/runtime/streams/stream-message-utils.ts +1 -27
- package/src/runtime/streams/stream-session-runtime.ts +54 -97
- package/dist/runtime/streams/session-requests.d.ts +0 -25
- package/dist/runtime/streams/session-requests.js +0 -101
- package/src/runtime/streams/session-requests.ts +0 -110
|
@@ -27,19 +27,19 @@ class ZLinkInMemoryLocationStore {
|
|
|
27
27
|
authority;
|
|
28
28
|
constructor(now = () => new Date()) {
|
|
29
29
|
this.now = now;
|
|
30
|
+
const isOwnerLive = (owner) => this.liveOwnerLease(owner.ownerId, this.now())?.token.leaseGeneration ===
|
|
31
|
+
owner.leaseGeneration;
|
|
30
32
|
this.authority = new in_memory_authority_store_1.ZLinkInMemoryAuthorityStore({
|
|
33
|
+
isOwnerLive,
|
|
31
34
|
isTargetLive: (key, lifecycleGeneration, owner) => {
|
|
32
35
|
const descriptor = this.meshNodes.rows.get(meshNodeKey(key.meshName, key.rid));
|
|
33
|
-
const lease = this.leases.get(owner.ownerId);
|
|
34
36
|
return (descriptor !== undefined &&
|
|
35
37
|
descriptor.lifecycleGeneration === lifecycleGeneration &&
|
|
36
38
|
descriptor.ownerId === owner.ownerId &&
|
|
37
39
|
descriptor.leaseGeneration === owner.leaseGeneration &&
|
|
38
40
|
descriptor.objectRole === internal_location_contracts_1.ZLinkObjectRole.Server &&
|
|
39
41
|
descriptor.state === internal_location_contracts_1.ZLinkFrameworkRuntimeState.Serving &&
|
|
40
|
-
|
|
41
|
-
lease.token.leaseGeneration === owner.leaseGeneration &&
|
|
42
|
-
lease.leaseExpiresAt.getTime() > this.now().getTime());
|
|
42
|
+
isOwnerLive(owner));
|
|
43
43
|
},
|
|
44
44
|
placementCapacityAvailable: (key, requested, reserved, active) => {
|
|
45
45
|
const descriptor = this.meshNodes.rows.get(meshNodeKey(key.meshName, key.rid));
|
|
@@ -86,6 +86,9 @@ class ZLinkInMemoryLocationStore {
|
|
|
86
86
|
async readCreationTerminal(operation, signal) {
|
|
87
87
|
return this.authority.readCreationTerminal(operation, signal);
|
|
88
88
|
}
|
|
89
|
+
async releaseEndedReservation(key, expectedStoreVersion, signal) {
|
|
90
|
+
return this.authority.releaseEndedReservation(key, expectedStoreVersion, signal);
|
|
91
|
+
}
|
|
89
92
|
async abort(request, signal) {
|
|
90
93
|
return this.authority.abort(request, signal);
|
|
91
94
|
}
|
|
@@ -313,7 +316,7 @@ class ZLinkInMemoryLocationStore {
|
|
|
313
316
|
async listFanoutPublishers(channelName, page = {}, signal) {
|
|
314
317
|
signal?.throwIfAborted();
|
|
315
318
|
const storeNow = this.now();
|
|
316
|
-
return pageRows(this.fanoutPublishers, (row) => row.channelName === channelName && this.
|
|
319
|
+
return pageRows(this.fanoutPublishers, (row) => row.channelName === channelName && this.liveOwnerLease(row.ownerId, storeNow) !== undefined, page);
|
|
317
320
|
}
|
|
318
321
|
async updatePeer(peer, intent) {
|
|
319
322
|
return this.write(this.peers, key_codec_1.ZLinkLocationKeyCodec.encodePeerKey({
|
|
@@ -339,7 +342,7 @@ class ZLinkInMemoryLocationStore {
|
|
|
339
342
|
const current = this.spots.rows.get(key);
|
|
340
343
|
if (intent === internal_location_contracts_1.ZLinkLocationWriteIntent.NewClaim &&
|
|
341
344
|
current !== undefined &&
|
|
342
|
-
this.
|
|
345
|
+
this.liveOwnerLease(current.ownerId, updatedAt) !== undefined) {
|
|
343
346
|
return rejectedConflict();
|
|
344
347
|
}
|
|
345
348
|
if (intent === internal_location_contracts_1.ZLinkLocationWriteIntent.Renew) {
|
|
@@ -388,7 +391,7 @@ class ZLinkInMemoryLocationStore {
|
|
|
388
391
|
const current = this.actors.rows.get(key);
|
|
389
392
|
if (intent === internal_location_contracts_1.ZLinkLocationWriteIntent.NewClaim &&
|
|
390
393
|
current !== undefined &&
|
|
391
|
-
this.
|
|
394
|
+
this.liveOwnerLease(current.ownerId, updatedAt) !== undefined) {
|
|
392
395
|
return rejectedConflict();
|
|
393
396
|
}
|
|
394
397
|
if (intent === internal_location_contracts_1.ZLinkLocationWriteIntent.Renew) {
|
|
@@ -648,7 +651,7 @@ class ZLinkInMemoryLocationStore {
|
|
|
648
651
|
const current = table.rows.get(key);
|
|
649
652
|
if (intent === internal_location_contracts_1.ZLinkLocationWriteIntent.NewClaim &&
|
|
650
653
|
current !== undefined &&
|
|
651
|
-
this.
|
|
654
|
+
this.liveOwnerLease(ownerOf(current), updatedAt) !== undefined) {
|
|
652
655
|
return rejectedConflict();
|
|
653
656
|
}
|
|
654
657
|
if (intent === internal_location_contracts_1.ZLinkLocationWriteIntent.NewClaim ||
|
|
@@ -711,9 +714,11 @@ class ZLinkInMemoryLocationStore {
|
|
|
711
714
|
}
|
|
712
715
|
return removed;
|
|
713
716
|
}
|
|
714
|
-
|
|
717
|
+
liveOwnerLease(ownerId, now) {
|
|
715
718
|
const lease = this.leases.get(ownerId);
|
|
716
|
-
return lease !== undefined && lease.leaseExpiresAt.getTime() > now.getTime()
|
|
719
|
+
return lease !== undefined && lease.leaseExpiresAt.getTime() > now.getTime()
|
|
720
|
+
? lease
|
|
721
|
+
: undefined;
|
|
717
722
|
}
|
|
718
723
|
bump(kind, meshName) {
|
|
719
724
|
this.bumpScope({ kind, meshName });
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
export * from '../../contracts/Locations';
|
|
2
|
+
import type { ZLinkObjectReserveRequest as ReserveRequest } from '../../contracts/Locations/Authority';
|
|
3
|
+
import type { ZLinkRelocationConfiguration } from '../../contracts/Configuration/RegistrationTypes';
|
|
4
|
+
export interface ZLinkObjectReserveRequest extends ReserveRequest {
|
|
5
|
+
readonly actorRelocationPolicy?: ZLinkRelocationConfiguration<unknown>['kind'];
|
|
6
|
+
}
|
|
2
7
|
export type * from '../../contracts/Locations/Authority';
|
|
3
8
|
export type { ZLinkActorLocation, ZLinkPeerLocation, ZLinkRouteLocation, ZLinkSpotLocation } from '../../contracts/Locations/Rows';
|
|
4
9
|
export type { ZLinkActorLocationFilter, ZLinkActorLocationKey, ZLinkLocationKey, ZLinkPeerLocationFilter, ZLinkPeerLocationKey, ZLinkRouteLocationFilter, ZLinkRouteLocationKey, ZLinkSpotLocationFilter, ZLinkSpotLocationKey } from '../../contracts/Locations/Keys';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ZLinkActorLocation, ZLinkActorLocationFilter, ZLinkActorLocationKey, ZLinkLocationOwnerToken, ZLinkLocationPage, ZLinkLocationWriteIntent, ZLinkLocationWriteResult, ZLinkLocationWriteStatus, ZLinkPageRequest, ZLinkPeerLocation, ZLinkPeerLocationFilter, ZLinkPeerLocationKey, ZLinkRouteLocation, ZLinkRouteLocationFilter, ZLinkRouteLocationKey, ZLinkSpotLocation, ZLinkSpotLocationFilter, ZLinkSpotLocationKey } from './internal-location-contracts';
|
|
2
2
|
import type { ZLinkDomainLocationStore } from './domain-store-contract';
|
|
3
3
|
export type ZLinkAuthorityStore = Pick<ZLinkDomainLocationStore, 'readAuthority' | 'compareExchangeAuthority' | 'listAuthorities'>;
|
|
4
|
-
export type ZLinkObjectCreationStore = Pick<ZLinkDomainLocationStore, 'readCreationTerminal' | 'reserve' | 'commit' | 'completeCreation' | 'abort' | 'prepareAggregate' | 'commitAggregate' | 'abortAggregate'>;
|
|
4
|
+
export type ZLinkObjectCreationStore = Pick<ZLinkDomainLocationStore, 'readCreationTerminal' | 'reserve' | 'commit' | 'completeCreation' | 'abort' | 'releaseEndedReservation' | 'prepareAggregate' | 'commitAggregate' | 'abortAggregate'>;
|
|
5
5
|
export type ZLinkOwnerLeaseStore = Pick<ZLinkDomainLocationStore, 'claimOwnerLease' | 'readOwnerLease' | 'renewOwnerLease' | 'releaseOwnerLease'>;
|
|
6
6
|
export type ZLinkMeshNodeLocationStore = Pick<ZLinkDomainLocationStore, 'updateMeshNode' | 'removeMeshNode' | 'listMeshNodes'>;
|
|
7
7
|
export type ZLinkClientServerLocationStore = Pick<ZLinkDomainLocationStore, 'updateClientServer' | 'removeClientServer' | 'listClientServers'>;
|
|
@@ -20,6 +20,8 @@ export declare class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationS
|
|
|
20
20
|
commitAggregate(fence: ZLinkAggregateFence, signal?: AbortSignal): Promise<ZLinkAggregateCommitResult>;
|
|
21
21
|
private commitAggregateCore;
|
|
22
22
|
abortAggregate(fence: ZLinkAggregateFence, signal?: AbortSignal): Promise<ZLinkAggregateAbortResult>;
|
|
23
|
+
releaseEndedReservation(key: ZLinkAuthorityKey, expectedStoreVersion: string, signal?: AbortSignal): Promise<boolean>;
|
|
24
|
+
private tryReleaseEndedReservation;
|
|
23
25
|
reserve(request: ZLinkObjectReserveRequest, signal?: AbortSignal, deadlineUnixMs?: bigint): Promise<ZLinkObjectReserveResult>;
|
|
24
26
|
commit(request: ZLinkObjectCommitRequest, signal?: AbortSignal, deadlineUnixMs?: bigint): Promise<ZLinkObjectCommitResult>;
|
|
25
27
|
abort(request: ZLinkObjectAbortRequest, signal?: AbortSignal, deadlineUnixMs?: bigint): Promise<ZLinkObjectAbortResult>;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ZLinkLocationStoreRepository = void 0;
|
|
4
|
+
const service_relocation_runtime_1 = require("../foundation/service-relocation-runtime");
|
|
4
5
|
const stream_wire_1 = require("@zlink-systems/stream-wire");
|
|
5
6
|
const node_crypto_1 = require("node:crypto");
|
|
6
7
|
const Options_1 = require("../../contracts/Locations/Options");
|
|
@@ -46,7 +47,33 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
46
47
|
constructor(provider, nowProvider = () => new Date()) {
|
|
47
48
|
super(nowProvider);
|
|
48
49
|
this.nowProvider = nowProvider;
|
|
49
|
-
|
|
50
|
+
// Classify only failures of the opaque SPI, before interpreting its records.
|
|
51
|
+
this.provider = {
|
|
52
|
+
async read(key, signal) {
|
|
53
|
+
try {
|
|
54
|
+
return await provider.read(key, signal);
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
throw locationStoreProviderFailure(error, signal);
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
async write(request, signal) {
|
|
61
|
+
try {
|
|
62
|
+
return await provider.write(request, signal);
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
throw locationStoreProviderFailure(error, signal);
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
async scan(request, signal) {
|
|
69
|
+
try {
|
|
70
|
+
return await provider.scan(request, signal);
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
throw locationStoreProviderFailure(error, signal);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
};
|
|
50
77
|
this.aggregateInventory = new aggregate_inventory_store_1.ZLinkAggregateInventoryStore(this.provider);
|
|
51
78
|
}
|
|
52
79
|
async readAuthority(key, signal) {
|
|
@@ -787,9 +814,88 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
787
814
|
return { kind: 'aborted' };
|
|
788
815
|
}
|
|
789
816
|
}
|
|
817
|
+
async releaseEndedReservation(key, expectedStoreVersion, signal) {
|
|
818
|
+
return ((await this.tryReleaseEndedReservation(key, expectedStoreVersion, signal)) === 'reclaimed');
|
|
819
|
+
}
|
|
820
|
+
async tryReleaseEndedReservation(key, expectedStoreVersion, signal, request) {
|
|
821
|
+
const rowKey = authorityKey(key.value);
|
|
822
|
+
const current = await this.provider.read(rowKey, signal);
|
|
823
|
+
if (current.kind === 'missing' || current.value.version.value !== expectedStoreVersion)
|
|
824
|
+
return 'conflict';
|
|
825
|
+
const record = decodeAuthorityRecord(current.value.bytes);
|
|
826
|
+
const snapshot = record.snapshot;
|
|
827
|
+
if ((snapshot.allocation.state === 'active'
|
|
828
|
+
? request?.key.kind !== 'actor'
|
|
829
|
+
: snapshot.pendingCreation === undefined) ||
|
|
830
|
+
record.aggregate !== undefined ||
|
|
831
|
+
hasRelocationAuthority(snapshot.payload))
|
|
832
|
+
return 'notReclaimable';
|
|
833
|
+
const leaseKey = ownerKey(snapshot.ownerId);
|
|
834
|
+
const descriptorKey = meshKey(snapshot.allocation.descriptor.meshName, snapshot.allocation.descriptor.rid);
|
|
835
|
+
const capacityRowKey = capacityKey(snapshot.allocation.descriptor.meshName, String(snapshot.allocation.descriptor.rid));
|
|
836
|
+
const [lease, descriptor, capacity] = await Promise.all([
|
|
837
|
+
this.provider.read(leaseKey, signal),
|
|
838
|
+
this.provider.read(descriptorKey, signal),
|
|
839
|
+
this.provider.read(capacityRowKey, signal)
|
|
840
|
+
]);
|
|
841
|
+
if (lease.kind === 'found' && lease.value.expiresAt === undefined)
|
|
842
|
+
throw new Error('Location Store owner lease record is invalid.');
|
|
843
|
+
const ownerLive = sameLiveOwner(lease, snapshot);
|
|
844
|
+
if (snapshot.allocation.state === 'active') {
|
|
845
|
+
if (ownerLive)
|
|
846
|
+
return 'notReclaimable';
|
|
847
|
+
if (request?.actorRelocationPolicy !== 'disabled')
|
|
848
|
+
throw new contracts_1.ZLinkFrameworkException(contracts_1.ZLinkFrameworkErrorKind.Unavailable, 'Actor owner lease is unavailable.');
|
|
849
|
+
}
|
|
850
|
+
else if (ownerLive &&
|
|
851
|
+
descriptor.kind === 'found' &&
|
|
852
|
+
reviveMeshDescriptor(decodeCanonicalDescriptorRecord(descriptor.value.bytes).descriptor).lifecycleGeneration === snapshot.allocation.descriptorLifecycleGeneration)
|
|
853
|
+
return 'notReclaimable';
|
|
854
|
+
const mutations = [
|
|
855
|
+
{ kind: 'delete', key: rowKey }
|
|
856
|
+
];
|
|
857
|
+
if (capacity.kind === 'found') {
|
|
858
|
+
const stored = decodeJson(capacity.value.bytes);
|
|
859
|
+
try {
|
|
860
|
+
mutations.push({
|
|
861
|
+
kind: 'put',
|
|
862
|
+
key: capacityRowKey,
|
|
863
|
+
bytes: encodeJson({
|
|
864
|
+
active: snapshot.allocation.state === 'active'
|
|
865
|
+
? subtractCapacity(stored.active, snapshot.allocation.capacity)
|
|
866
|
+
: stored.active,
|
|
867
|
+
pending: snapshot.allocation.state === 'reserved'
|
|
868
|
+
? subtractCapacity(stored.pending, snapshot.allocation.capacity)
|
|
869
|
+
: stored.pending
|
|
870
|
+
})
|
|
871
|
+
});
|
|
872
|
+
}
|
|
873
|
+
catch (error) {
|
|
874
|
+
if (!(error instanceof contracts_1.ZLinkFrameworkException) ||
|
|
875
|
+
error.kind !== contracts_1.ZLinkFrameworkErrorKind.DataLost)
|
|
876
|
+
throw error;
|
|
877
|
+
const observed = await this.provider.read(rowKey, signal);
|
|
878
|
+
if (observed.kind === 'missing' ||
|
|
879
|
+
observed.value.version.value !== current.value.version.value)
|
|
880
|
+
return 'conflict';
|
|
881
|
+
throw error;
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
const result = await this.provider.write({
|
|
885
|
+
conditions: [
|
|
886
|
+
{ kind: 'version', key: rowKey, expected: current.value.version },
|
|
887
|
+
conditionFor(leaseKey, lease),
|
|
888
|
+
conditionFor(descriptorKey, descriptor),
|
|
889
|
+
conditionFor(capacityRowKey, capacity)
|
|
890
|
+
],
|
|
891
|
+
mutations
|
|
892
|
+
}, signal);
|
|
893
|
+
return result.kind === 'applied' ? 'reclaimed' : 'conflict';
|
|
894
|
+
}
|
|
790
895
|
async reserve(request, signal, deadlineUnixMs) {
|
|
791
896
|
const encodedAuthorityKey = (0, authority_key_codec_1.encodeAuthorityKey)(request.key.kind, request.key.globalId);
|
|
792
897
|
const reservationId = (0, node_crypto_1.randomUUID)();
|
|
898
|
+
let reclaimVersion;
|
|
793
899
|
for (;;) {
|
|
794
900
|
throwIfOperationExpired(signal, deadlineUnixMs);
|
|
795
901
|
const rowKey = authorityKey(encodedAuthorityKey.value);
|
|
@@ -804,56 +910,18 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
804
910
|
snapshot.allocation.stableType !== request.intent.stableType) {
|
|
805
911
|
return { kind: 'typeMismatch', current: snapshot };
|
|
806
912
|
}
|
|
807
|
-
if (snapshot.
|
|
808
|
-
return { kind: 'alreadyExists', current: snapshot };
|
|
809
|
-
}
|
|
810
|
-
if (record.aggregate !== undefined ||
|
|
811
|
-
isCanonicalAuthorityPayload(record.snapshot.payload)) {
|
|
812
|
-
// A relocation record carries its own recovery protocol. Reserve
|
|
813
|
-
// may reclaim only an unfinished plain creation.
|
|
913
|
+
if (reclaimVersion !== undefined && snapshot.storeVersion.value !== reclaimVersion)
|
|
814
914
|
return { kind: 'conflict', current: snapshot };
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
const [staleOwnerRead, staleCapacityRead] = await Promise.all([
|
|
822
|
-
this.provider.read(staleOwnerKey, signal),
|
|
823
|
-
this.provider.read(staleCapacityKey, signal)
|
|
824
|
-
]);
|
|
825
|
-
if (staleOwnerRead.kind === 'found' && staleOwnerRead.value.expiresAt === undefined) {
|
|
826
|
-
// A lease is always written with a positive TTL, so a missing
|
|
827
|
-
// expiry is a corrupt record. Reclaiming deletes authority state,
|
|
828
|
-
// so refuse rather than read the absence as expiry.
|
|
829
|
-
throw new Error('Location Store owner lease record is invalid.');
|
|
830
|
-
}
|
|
831
|
-
if (sameLiveOwner(staleOwnerRead, record.snapshot)) {
|
|
832
|
-
return { kind: 'conflict', current: snapshot };
|
|
833
|
-
}
|
|
834
|
-
const staleCapacity = staleCapacityRead.kind === 'missing'
|
|
835
|
-
? emptyCapacityRecord()
|
|
836
|
-
: decodeJson(staleCapacityRead.value.bytes);
|
|
837
|
-
await this.provider.write({
|
|
838
|
-
conditions: [
|
|
839
|
-
{ kind: 'version', key: rowKey, expected: current.value.version },
|
|
840
|
-
versionCondition(staleOwnerKey, staleOwnerRead),
|
|
841
|
-
conditionFor(staleCapacityKey, staleCapacityRead)
|
|
842
|
-
],
|
|
843
|
-
mutations: [
|
|
844
|
-
{ kind: 'delete', key: rowKey },
|
|
845
|
-
{
|
|
846
|
-
kind: 'put',
|
|
847
|
-
key: staleCapacityKey,
|
|
848
|
-
bytes: encodeJson({
|
|
849
|
-
active: staleCapacity.active,
|
|
850
|
-
pending: subtractCapacity(staleCapacity.pending, record.snapshot.allocation.capacity)
|
|
851
|
-
})
|
|
852
|
-
}
|
|
853
|
-
]
|
|
854
|
-
}, signal);
|
|
915
|
+
const reclaim = await this.tryReleaseEndedReservation(encodedAuthorityKey, current.value.version.value, signal, request);
|
|
916
|
+
if (reclaim === 'notReclaimable')
|
|
917
|
+
return snapshot.allocation.state === 'active'
|
|
918
|
+
? { kind: 'alreadyExists', current: snapshot }
|
|
919
|
+
: { kind: 'conflict', current: snapshot };
|
|
920
|
+
reclaimVersion = reclaim === 'conflict' ? snapshot.storeVersion.value : undefined;
|
|
855
921
|
continue;
|
|
856
922
|
}
|
|
923
|
+
if (reclaimVersion !== undefined)
|
|
924
|
+
return { kind: 'conflict', current: { kind: 'missing', storeNow: current.storeNow } };
|
|
857
925
|
const [descriptorRead, leaseRead] = await Promise.all([
|
|
858
926
|
this.provider.read(descriptorKey, signal),
|
|
859
927
|
this.provider.read(leaseKey, signal)
|
|
@@ -2906,7 +2974,7 @@ function adjustCapacity(usage, delta, direction) {
|
|
|
2906
2974
|
const key = capacityTypeKey(delta.spotType);
|
|
2907
2975
|
const next = (spotTypes[key] ?? 0) + direction * delta.spotType.count;
|
|
2908
2976
|
if (next < 0)
|
|
2909
|
-
throw new
|
|
2977
|
+
throw new contracts_1.ZLinkFrameworkException(contracts_1.ZLinkFrameworkErrorKind.DataLost, 'Provider capacity counter underflow.');
|
|
2910
2978
|
if (next === 0)
|
|
2911
2979
|
delete spotTypes[key];
|
|
2912
2980
|
else
|
|
@@ -2915,7 +2983,7 @@ function adjustCapacity(usage, delta, direction) {
|
|
|
2915
2983
|
const actors = usage.actors + direction * delta.actors;
|
|
2916
2984
|
const spots = usage.spots + direction * delta.spots;
|
|
2917
2985
|
if (actors < 0 || spots < 0)
|
|
2918
|
-
throw new
|
|
2986
|
+
throw new contracts_1.ZLinkFrameworkException(contracts_1.ZLinkFrameworkErrorKind.DataLost, 'Provider capacity counter underflow.');
|
|
2919
2987
|
return { actors, spots, spotTypes };
|
|
2920
2988
|
}
|
|
2921
2989
|
function capacityTypeKey(value) {
|
|
@@ -2942,10 +3010,9 @@ function sameCreationTarget(snapshot, target) {
|
|
|
2942
3010
|
snapshot.ownerId === target.owner.ownerId &&
|
|
2943
3011
|
snapshot.ownerLeaseGeneration === target.owner.leaseGeneration);
|
|
2944
3012
|
}
|
|
2945
|
-
const
|
|
2946
|
-
function
|
|
2947
|
-
return (payload
|
|
2948
|
-
Buffer.from(payload.buffer, payload.byteOffset, CANONICAL_AUTHORITY_MAGIC.byteLength).equals(CANONICAL_AUTHORITY_MAGIC));
|
|
3013
|
+
const relocationAuthorityCodec = new service_relocation_runtime_1.ServiceRelocationAuthorityPayloadCodec();
|
|
3014
|
+
function hasRelocationAuthority(payload) {
|
|
3015
|
+
return relocationAuthorityCodec.read(payload) !== undefined;
|
|
2949
3016
|
}
|
|
2950
3017
|
function sameLiveOwner(lease, snapshot) {
|
|
2951
3018
|
if (lease.kind === 'missing')
|
|
@@ -3239,3 +3306,12 @@ function throwIfOperationExpired(signal, deadlineUnixMs) {
|
|
|
3239
3306
|
throw new DOMException('Operation deadline exceeded.', 'TimeoutError');
|
|
3240
3307
|
}
|
|
3241
3308
|
}
|
|
3309
|
+
// Store SPI §6: preserve caller failures and classify provider failures once.
|
|
3310
|
+
function locationStoreProviderFailure(error, signal) {
|
|
3311
|
+
if (error instanceof contracts_1.ZLinkFrameworkException ||
|
|
3312
|
+
error instanceof TypeError ||
|
|
3313
|
+
error instanceof RangeError ||
|
|
3314
|
+
signal?.aborted === true)
|
|
3315
|
+
return error;
|
|
3316
|
+
return new contracts_1.ZLinkFrameworkException(contracts_1.ZLinkFrameworkErrorKind.Unavailable, 'Location Store provider is unavailable.', error);
|
|
3317
|
+
}
|
|
@@ -89,6 +89,7 @@ export declare class ZLinkEntrySpotActivation {
|
|
|
89
89
|
*/
|
|
90
90
|
commitServiceActorJoin(actor: ZLinkActor, handoffBacklog?: readonly ZLinkActorHandoffPacket[], signal?: AbortSignal): Promise<void>;
|
|
91
91
|
executeActor<T>(actorId: string, operation: () => Promise<T>): Promise<T>;
|
|
92
|
+
terminateActor(actorId: string, terminal: () => Promise<void>): Promise<void>;
|
|
92
93
|
/**
|
|
93
94
|
* Entry Spot membership does not have an application admission callback.
|
|
94
95
|
* The shared core round-trip therefore accepts a valid returning Actor and
|
|
@@ -220,6 +220,9 @@ class ZLinkEntrySpotActivation {
|
|
|
220
220
|
executeActor(actorId, operation) {
|
|
221
221
|
return this.spotSerialExecutor.executeActor(actorId, operation);
|
|
222
222
|
}
|
|
223
|
+
terminateActor(actorId, terminal) {
|
|
224
|
+
return this.spotSerialExecutor.terminateActor(actorId, terminal);
|
|
225
|
+
}
|
|
223
226
|
/**
|
|
224
227
|
* Entry Spot membership does not have an application admission callback.
|
|
225
228
|
* The shared core round-trip therefore accepts a valid returning Actor and
|
|
@@ -104,6 +104,7 @@ export declare class ZLinkSpotNodeRuntimeManager {
|
|
|
104
104
|
get primaryMeshCompletions(): ZLinkMeshCompletionTable | undefined;
|
|
105
105
|
notifyEntrySpotActorCreated(nodeRid: RoutingId, actor: ZLinkActor, createRequest: ZLinkMessage, signal?: AbortSignal): Promise<import('../../contracts').ZLinkActorCreateResponse | undefined>;
|
|
106
106
|
notifyPrimaryEntrySpotActorJoined(actor: ZLinkActor, signal?: AbortSignal): Promise<void>;
|
|
107
|
+
terminateActorActivation(actor: ZLinkActor, terminal: () => Promise<void>): Promise<void>;
|
|
107
108
|
notifyPrimaryEntrySpotActorLeft(actor: ZLinkActor, signal?: AbortSignal, actorRef?: ActorRef, membershipEpoch?: bigint): Promise<void>;
|
|
108
109
|
notifyPrimaryEntrySpotActorDisconnected(actor: ZLinkActor, signal?: AbortSignal): Promise<void>;
|
|
109
110
|
notifyEntrySpotActorDisconnected(meshName: string, actor: ZLinkActor, signal?: AbortSignal): Promise<void>;
|
|
@@ -542,6 +542,12 @@ class ZLinkSpotNodeRuntimeManager {
|
|
|
542
542
|
const activation = this.primaryEntryActivation();
|
|
543
543
|
return activation?.notifyJoinActor(actor, signal) ?? Promise.resolve();
|
|
544
544
|
}
|
|
545
|
+
terminateActorActivation(actor, terminal) {
|
|
546
|
+
const activation = this.entryActivations.get(actor.context.meshName);
|
|
547
|
+
return activation === undefined
|
|
548
|
+
? terminal()
|
|
549
|
+
: activation.terminateActor(actor.context.actorId, terminal);
|
|
550
|
+
}
|
|
545
551
|
notifyPrimaryEntrySpotActorLeft(actor, signal, actorRef, membershipEpoch) {
|
|
546
552
|
const activation = this.primaryEntryActivation();
|
|
547
553
|
return (activation?.notifyLeaveActor(actor, signal, actorRef, membershipEpoch) ?? Promise.resolve());
|
|
@@ -26,6 +26,7 @@ export declare class ZLinkSpotSerialExecutor {
|
|
|
26
26
|
executeTimer<T>(timerName: string, operation: () => Promise<T> | T, workOptions?: ZLinkSerialWorkOptions): Promise<T>;
|
|
27
27
|
isTimerExecuting(timerName: string): boolean;
|
|
28
28
|
executeLifecycle<T>(operation: () => Promise<T> | T, workOptions?: ZLinkSerialWorkOptions): Promise<T>;
|
|
29
|
+
terminateActor(actorId: string, terminal: () => Promise<void>): Promise<void>;
|
|
29
30
|
/**
|
|
30
31
|
* Makes all child queues unreachable and completes them in one synchronous
|
|
31
32
|
* ownership turn. Already accepted work remains drainable.
|
|
@@ -42,7 +42,8 @@ class ZLinkSpotSerialExecutor {
|
|
|
42
42
|
return this.spotSerial.execute(operation, workOptions);
|
|
43
43
|
}
|
|
44
44
|
executeActor(actorId, operation, workOptions) {
|
|
45
|
-
|
|
45
|
+
const serial = this.actorSerial(actorId);
|
|
46
|
+
return this.actorExecutor(actorId).execute(() => operation(serial), workOptions);
|
|
46
47
|
}
|
|
47
48
|
/** @internal Restores a durable Actor FIFO prefix without starting it. */
|
|
48
49
|
admitActorDurablePrefix(actorId, records) {
|
|
@@ -65,6 +66,14 @@ class ZLinkSpotSerialExecutor {
|
|
|
65
66
|
executeLifecycle(operation, workOptions) {
|
|
66
67
|
return this.spotSerial.execute(operation, { ...workOptions, lane: 'lifecycle' });
|
|
67
68
|
}
|
|
69
|
+
async terminateActor(actorId, terminal) {
|
|
70
|
+
const executor = this.actorExecutor(actorId);
|
|
71
|
+
await executor.close();
|
|
72
|
+
await terminal();
|
|
73
|
+
if (this.actorExecutors.get(actorId) === executor)
|
|
74
|
+
this.actorExecutors.delete(actorId);
|
|
75
|
+
this.actorSerials.delete(actorId);
|
|
76
|
+
}
|
|
68
77
|
/**
|
|
69
78
|
* Makes all child queues unreachable and completes them in one synchronous
|
|
70
79
|
* ownership turn. Already accepted work remains drainable.
|
|
@@ -96,7 +105,10 @@ class ZLinkSpotSerialExecutor {
|
|
|
96
105
|
this.throwIfClosing();
|
|
97
106
|
let executor = this.actorExecutors.get(actorId);
|
|
98
107
|
if (executor === undefined) {
|
|
99
|
-
executor =
|
|
108
|
+
executor =
|
|
109
|
+
this.executionMode === contracts_1.ZLinkUserSpotExecutionMode.SpotWide
|
|
110
|
+
? this.spotSerial.createActorExecutor(actorId, this.sourceSpotId, this.actorOptions)
|
|
111
|
+
: new actors_1.ZLinkActorSerialExecutor(actorId, this.sourceSpotId, this.actorOptions);
|
|
100
112
|
this.actorExecutors.set(actorId, executor);
|
|
101
113
|
}
|
|
102
114
|
return executor;
|
|
@@ -3,6 +3,7 @@ import type { SpotId } from '../../contracts';
|
|
|
3
3
|
import type { ZLinkFrameworkException } from '../../contracts/Errors/ZLinkFrameworkException';
|
|
4
4
|
import { type ZLinkSerialSchedulerOptions, type ZLinkSerialWorkOptions, type ZLinkSerialWorkRecord } from '../execution/serial-execution-queue';
|
|
5
5
|
import type { ZLinkSerialLifecycleContext } from '../execution/serial-execution-queue';
|
|
6
|
+
import { ZLinkActorSerialExecutor } from '../actors/actor-mailbox';
|
|
6
7
|
export type ZLinkSpotApplicationTurnContext = ZLinkExecutionBarrierClaim & {
|
|
7
8
|
readonly replay?: (failure?: unknown) => Promise<unknown> | unknown;
|
|
8
9
|
};
|
|
@@ -19,6 +20,8 @@ export declare class ZLinkSpotSerialTurnExecutor {
|
|
|
19
20
|
activeTurnId: number;
|
|
20
21
|
constructor(yieldAllowed?: boolean, sourceSpotId?: SpotId | undefined, schedulerOptions?: ZLinkSerialSchedulerOptions);
|
|
21
22
|
get isExecuting(): boolean;
|
|
23
|
+
/** Creates a passive Actor mailbox consumed by this Spot's scheduler. */
|
|
24
|
+
createActorExecutor(actorId: string, sourceSpotId: unknown, options?: ZLinkSerialSchedulerOptions): ZLinkActorSerialExecutor;
|
|
22
25
|
get isCurrentTurn(): boolean;
|
|
23
26
|
get hasPendingWork(): boolean;
|
|
24
27
|
get lastActivityAt(): number;
|
|
@@ -4,6 +4,7 @@ exports.ZLinkSpotSerialTurnExecutor = void 0;
|
|
|
4
4
|
const execution_1 = require("../execution");
|
|
5
5
|
const framework_errors_internal_1 = require("../framework-errors-internal");
|
|
6
6
|
const serial_execution_queue_1 = require("../execution/serial-execution-queue");
|
|
7
|
+
const actor_mailbox_1 = require("../actors/actor-mailbox");
|
|
7
8
|
const application_job_queue_scope_1 = require("../application-jobs/application-job-queue-scope");
|
|
8
9
|
class ZLinkSpotSerialTurnExecutor {
|
|
9
10
|
yieldAllowed;
|
|
@@ -24,6 +25,10 @@ class ZLinkSpotSerialTurnExecutor {
|
|
|
24
25
|
get isExecuting() {
|
|
25
26
|
return this.depth > 0;
|
|
26
27
|
}
|
|
28
|
+
/** Creates a passive Actor mailbox consumed by this Spot's scheduler. */
|
|
29
|
+
createActorExecutor(actorId, sourceSpotId, options) {
|
|
30
|
+
return new actor_mailbox_1.ZLinkActorSerialExecutor(actorId, sourceSpotId, options, this.scheduler);
|
|
31
|
+
}
|
|
27
32
|
get isCurrentTurn() {
|
|
28
33
|
return this.depth > 0 && (0, execution_1.isCurrentZLinkSpotSerialTurn)(this);
|
|
29
34
|
}
|
|
@@ -16,7 +16,6 @@ import { ZLinkStreamCodec, ZLinkStreamMessageKind, type ZLinkStreamFrameHeader,
|
|
|
16
16
|
import { DefaultZLinkSessionActor, DefaultZLinkSessionContext } from './session-context';
|
|
17
17
|
import type { ZLinkActorRouteCommitOptions, ZLinkSessionBindingConfirmationOptions, ZLinkSessionBindingIdentity } from './stream-binding-runtime-ports';
|
|
18
18
|
import { ZLinkStreamSessionNodeRuntime as ZLinkStreamSessionNodeRuntimeCore, ZLinkStreamSessionRuntime as ZLinkStreamSessionRuntimeCore, type ZLinkStreamSessionNodeRuntimeOptions as ZLinkStreamSessionNodeRuntimeCoreOptions, type ZLinkStreamSessionRuntimeOptions as ZLinkStreamSessionRuntimeCoreOptions } from './stream-session-runtime';
|
|
19
|
-
export { ZLinkPendingSessionRequest } from './session-requests';
|
|
20
19
|
export { ZLinkActorSessionLifecycleCoordinator } from './actor-session-lifecycle-coordinator';
|
|
21
20
|
export { ZLinkActorSessionBindingRegistry } from './actor-session-binding-registry';
|
|
22
21
|
export { zlinkStreamLz4CompressionCodec } from './stream-frame-factory';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ZLinkStreamBindingRuntime = exports.ZLinkStreamSessionNodeRuntime = exports.ZLinkStreamSessionRuntime = exports.ZLinkStreamRuntimeManager = exports.DefaultZLinkSessionContext = exports.DefaultZLinkSessionActor = exports.DefaultZLinkBoundSessionFactory = exports.DefaultZLinkBoundSession = exports.ZLinkManagedStream = exports.zlinkStreamLz4CompressionCodec = exports.ZLinkActorSessionBindingRegistry = exports.ZLinkActorSessionLifecycleCoordinator =
|
|
3
|
+
exports.ZLinkStreamBindingRuntime = exports.ZLinkStreamSessionNodeRuntime = exports.ZLinkStreamSessionRuntime = exports.ZLinkStreamRuntimeManager = exports.DefaultZLinkSessionContext = exports.DefaultZLinkSessionActor = exports.DefaultZLinkBoundSessionFactory = exports.DefaultZLinkBoundSession = exports.ZLinkManagedStream = exports.zlinkStreamLz4CompressionCodec = exports.ZLinkActorSessionBindingRegistry = exports.ZLinkActorSessionLifecycleCoordinator = void 0;
|
|
4
4
|
const InternalDefaults_1 = require("../../contracts/Configuration/InternalDefaults");
|
|
5
5
|
const Options_1 = require("../../contracts/Locations/Options");
|
|
6
6
|
const configuration_1 = require("../configuration");
|
|
@@ -20,8 +20,6 @@ const stream_frame_factory_1 = require("./stream-frame-factory");
|
|
|
20
20
|
const stream_message_utils_1 = require("./stream-message-utils");
|
|
21
21
|
const stream_session_runtime_1 = require("./stream-session-runtime");
|
|
22
22
|
const DEFAULT_STREAM_SERVICE_SHUTDOWN_TIMEOUT_MS = 1000;
|
|
23
|
-
var session_requests_1 = require("./session-requests");
|
|
24
|
-
Object.defineProperty(exports, "ZLinkPendingSessionRequest", { enumerable: true, get: function () { return session_requests_1.ZLinkPendingSessionRequest; } });
|
|
25
23
|
var actor_session_lifecycle_coordinator_2 = require("./actor-session-lifecycle-coordinator");
|
|
26
24
|
Object.defineProperty(exports, "ZLinkActorSessionLifecycleCoordinator", { enumerable: true, get: function () { return actor_session_lifecycle_coordinator_2.ZLinkActorSessionLifecycleCoordinator; } });
|
|
27
25
|
var actor_session_binding_registry_2 = require("./actor-session-binding-registry");
|
|
@@ -116,6 +114,9 @@ class ZLinkStreamRuntimeManager {
|
|
|
116
114
|
const readablePoller = streamAdapter.createReadablePoller(socket);
|
|
117
115
|
const runtime = new stream_session_runtime_1.ZLinkStreamSessionNodeRuntime({
|
|
118
116
|
nodeName,
|
|
117
|
+
heartbeatIntervalMs: streamNode.heartbeatIntervalMs,
|
|
118
|
+
heartbeatTimeoutMs: streamNode.heartbeatTimeoutMs,
|
|
119
|
+
idleTimeoutMs: streamNode.idleTimeoutMs,
|
|
119
120
|
socket,
|
|
120
121
|
createPacket: () => streamAdapter.createStreamPacket(),
|
|
121
122
|
readablePoller,
|
|
@@ -118,15 +118,6 @@ function decodeStreamHeader(header, flowEnabled = true) {
|
|
|
118
118
|
const decoded = (0, stream_wire_1.decodeStreamWireHeader)(header, undefined, flowEnabled);
|
|
119
119
|
const kind = decoded.kind;
|
|
120
120
|
const flags = decoded.flags;
|
|
121
|
-
const hasRequestSeq = (flags & stream_wire_1.ZlinkStreamHeaderFlags.HasRequestSeq) !== 0;
|
|
122
|
-
const hasMetadata = (flags & stream_wire_1.ZlinkStreamHeaderFlags.HasMetadata) !== 0;
|
|
123
|
-
const hasCorrelation = (flags & stream_wire_1.ZlinkStreamHeaderFlags.HasCorrelationId) !== 0;
|
|
124
|
-
const hasFlow = (flags & stream_wire_1.ZlinkStreamHeaderFlags.HasFlowId) !== 0;
|
|
125
|
-
const hasActorSlot = (flags & stream_wire_1.ZlinkStreamHeaderFlags.HasActorSlot) !== 0;
|
|
126
|
-
if (kind === stream_wire_1.ZlinkStreamMessageKind.Control &&
|
|
127
|
-
(hasCorrelation || hasRequestSeq || hasMetadata || hasFlow || hasActorSlot)) {
|
|
128
|
-
throw new Error('Control packet must not contain a request sequence, metadata, correlation id, or flow id.');
|
|
129
|
-
}
|
|
130
121
|
const metadata = publicStreamMetadata(decoded.metadata);
|
|
131
122
|
return {
|
|
132
123
|
kind,
|
|
@@ -6,7 +6,6 @@ import type { ServiceRetiredBoundSessionRouteFence } from '../foundation/service
|
|
|
6
6
|
import { type ZLinkSubmitResult } from '../messaging/submission-result';
|
|
7
7
|
import { ZLinkStreamMessageKind, type ZLinkStreamFrameHeader, type ZLinkStreamReplyMessageKind } from './protocol';
|
|
8
8
|
import { DefaultZLinkBoundSessionSendCall } from './session-calls';
|
|
9
|
-
import { type ZLinkPendingSessionRequest } from './session-requests';
|
|
10
9
|
export interface ZLinkSessionContextStream extends ZLinkStream {
|
|
11
10
|
writeRaw(payload: Message, flags?: number): boolean;
|
|
12
11
|
submitRaw(payload: Message): Promise<ZLinkSubmitResult>;
|
|
@@ -42,7 +41,6 @@ export declare class DefaultZLinkSessionContext implements ZLinkSessionContext {
|
|
|
42
41
|
private readonly handlerRegistry;
|
|
43
42
|
readonly handlers: ZLinkSessionHandlerRegistry;
|
|
44
43
|
private readonly localActors;
|
|
45
|
-
private readonly requests;
|
|
46
44
|
private currentDispatchHeader;
|
|
47
45
|
private currentReplyClaimed;
|
|
48
46
|
private actorBindingReplacementHandler?;
|
|
@@ -73,8 +71,6 @@ export declare class DefaultZLinkSessionContext implements ZLinkSessionContext {
|
|
|
73
71
|
/** True while the current request dispatch has already submitted its reply. */
|
|
74
72
|
get replyClaimed(): boolean;
|
|
75
73
|
claimReply(requestHeader: ZLinkStreamFrameHeader): void;
|
|
76
|
-
startRequest(timeoutMs?: number): ZLinkPendingSessionRequest;
|
|
77
|
-
tryCompleteResponse(header: ZLinkStreamFrameHeader, payload: Message): boolean;
|
|
78
74
|
payloadForHeader(header: ZLinkStreamFrameHeader, payload: Message): Message;
|
|
79
75
|
get boundActors(): readonly DefaultZLinkSessionActor[];
|
|
80
76
|
findBoundActor(actorId: string): DefaultZLinkSessionActor | undefined;
|
|
@@ -12,7 +12,6 @@ const submission_result_1 = require("../messaging/submission-result");
|
|
|
12
12
|
const protocol_1 = require("./protocol");
|
|
13
13
|
const session_calls_1 = require("./session-calls");
|
|
14
14
|
const session_local_actors_1 = require("./session-local-actors");
|
|
15
|
-
const session_requests_1 = require("./session-requests");
|
|
16
15
|
class DefaultZLinkSessionContext {
|
|
17
16
|
runtime;
|
|
18
17
|
stream;
|
|
@@ -22,7 +21,6 @@ class DefaultZLinkSessionContext {
|
|
|
22
21
|
handlerRegistry;
|
|
23
22
|
handlers;
|
|
24
23
|
localActors = new session_local_actors_1.ZLinkSessionLocalActorBindings();
|
|
25
|
-
requests = new session_requests_1.ZLinkSessionRequestTracker();
|
|
26
24
|
currentDispatchHeader;
|
|
27
25
|
currentReplyClaimed = false;
|
|
28
26
|
actorBindingReplacementHandler;
|
|
@@ -137,21 +135,6 @@ class DefaultZLinkSessionContext {
|
|
|
137
135
|
}
|
|
138
136
|
this.currentReplyClaimed = true;
|
|
139
137
|
}
|
|
140
|
-
startRequest(timeoutMs) {
|
|
141
|
-
return this.requests.start(timeoutMs);
|
|
142
|
-
}
|
|
143
|
-
tryCompleteResponse(header, payload) {
|
|
144
|
-
if (header.requestSeq === undefined) {
|
|
145
|
-
return false;
|
|
146
|
-
}
|
|
147
|
-
if (header.kind === protocol_1.ZLinkStreamMessageKind.Response) {
|
|
148
|
-
return this.requests.complete(header.requestSeq, payload);
|
|
149
|
-
}
|
|
150
|
-
if (header.kind === protocol_1.ZLinkStreamMessageKind.Error) {
|
|
151
|
-
return this.requests.fail(header.requestSeq, decodeStreamErrorPayload(payload));
|
|
152
|
-
}
|
|
153
|
-
return false;
|
|
154
|
-
}
|
|
155
138
|
payloadForHeader(header, payload) {
|
|
156
139
|
if ((header.flags & protocol_1.ZLinkStreamHeaderFlags.PayloadCompressed) === 0) {
|
|
157
140
|
return payload;
|
|
@@ -374,15 +357,6 @@ class DefaultZLinkBoundSessionFactory {
|
|
|
374
357
|
}
|
|
375
358
|
}
|
|
376
359
|
exports.DefaultZLinkBoundSessionFactory = DefaultZLinkBoundSessionFactory;
|
|
377
|
-
function decodeStreamErrorPayload(payload) {
|
|
378
|
-
try {
|
|
379
|
-
const value = JSON.parse(Buffer.from((0, protocol_1.messageToBytes)(payload)).toString());
|
|
380
|
-
return new Error(typeof value.message === 'string' ? value.message : 'Stream request failed.');
|
|
381
|
-
}
|
|
382
|
-
catch {
|
|
383
|
-
return new Error('Stream request failed.');
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
360
|
function sameRetiredSession(left, right) {
|
|
387
361
|
return (left.sessionOwnerNodeRid === right.sessionOwnerNodeRid &&
|
|
388
362
|
left.sessionOwnerNodeGeneration === right.sessionOwnerNodeGeneration &&
|
|
@@ -4,7 +4,6 @@ export declare class ZLinkSessionSerialExecutor {
|
|
|
4
4
|
private closed;
|
|
5
5
|
executeApplication(work: () => Promise<void>, options?: Omit<ZLinkSerialWorkOptions, 'lane'>, onRejected?: (error?: unknown) => void): boolean;
|
|
6
6
|
executeControl(work: () => Promise<void>, options?: Omit<ZLinkSerialWorkOptions, 'lane'>, onRejected?: (error?: unknown) => void): boolean;
|
|
7
|
-
executeInfrastructure(work: () => Promise<void>, options?: Omit<ZLinkSerialWorkOptions, 'lane'>, onRejected?: (error?: unknown) => void): boolean;
|
|
8
7
|
executeFinal(work: () => Promise<void>): Promise<void>;
|
|
9
8
|
private submit;
|
|
10
9
|
dispose(): Promise<void>;
|
|
@@ -13,9 +13,6 @@ class ZLinkSessionSerialExecutor {
|
|
|
13
13
|
executeControl(work, options = {}, onRejected) {
|
|
14
14
|
return this.submit(work, 'lifecycle', options, onRejected);
|
|
15
15
|
}
|
|
16
|
-
executeInfrastructure(work, options = {}, onRejected) {
|
|
17
|
-
return this.submit(work, 'lifecycle', options, onRejected);
|
|
18
|
-
}
|
|
19
16
|
executeFinal(work) {
|
|
20
17
|
if (this.closed) {
|
|
21
18
|
return Promise.reject((0, framework_errors_internal_1.createInternalFrameworkException)(framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.RuntimeShutdown, 'Session execution queue is closed.'));
|