@zlink-systems/framework 0.29.0 → 0.30.0
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 +1 -2
- package/dist/contracts/Configuration/Configs.d.ts +0 -5
- package/dist/contracts/Configuration/RegistrationBuilders.js +6 -4
- package/dist/contracts/Configuration/RegistrationTypes.d.ts +1 -6
- package/dist/contracts/Configuration/RegistrationValidators.js +4 -4
- package/dist/contracts/Configuration/index.d.ts +1 -1
- package/dist/internal.d.ts +1 -0
- package/dist/internal.js +3 -1
- package/dist/runtime/actors/actor-handoff.d.ts +3 -2
- package/dist/runtime/actors/actor-handoff.js +9 -4
- 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/application-jobs/application-ingress-record-owner.d.ts +3 -1
- package/dist/runtime/application-jobs/application-ingress-record-owner.js +6 -1
- package/dist/runtime/application-jobs/application-job-queue-scope.d.ts +3 -1
- package/dist/runtime/application-jobs/application-job-queue-scope.js +5 -0
- package/dist/runtime/application-jobs/contracts.d.ts +5 -1
- package/dist/runtime/backend/contracts/index.d.ts +10 -19
- package/dist/runtime/backend/mesh-completion-table.d.ts +6 -4
- package/dist/runtime/backend/mesh-completion-table.js +28 -18
- package/dist/runtime/backend/mesh-dispatch-pump.js +21 -25
- package/dist/runtime/backend/node/node-backend-adapter-factory.js +6 -1
- package/dist/runtime/backend/node/node-backend-adapter-support.d.ts +3 -3
- package/dist/runtime/backend/node/node-backend-adapter-support.js +24 -29
- package/dist/runtime/backend/node/node-mesh-backend-adapter.d.ts +1 -9
- package/dist/runtime/backend/node/node-mesh-backend-adapter.js +1 -1
- package/dist/runtime/backend/node/node-raw-binding-port.js +11 -6
- package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +10 -12
- package/dist/runtime/backend/node/node-raw-mesh-backend.js +64 -98
- package/dist/runtime/backend/node/node-socket-backend-adapter.js +10 -5
- package/dist/runtime/backend/raw-binding-port.d.ts +9 -2
- package/dist/runtime/channels/channel-receive-loops.js +3 -3
- package/dist/runtime/channels/channel-runtime-lifecycle.js +2 -1
- package/dist/runtime/channels/channel-socket-registry.d.ts +10 -3
- package/dist/runtime/channels/channel-socket-registry.js +59 -82
- package/dist/runtime/diagnostics/message-flow.d.ts +1 -0
- package/dist/runtime/diagnostics/message-flow.js +3 -3
- package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +15 -1
- package/dist/runtime/foundation/raw-service-mesh-runtime.js +193 -64
- package/dist/runtime/foundation/service-liveness-registry.d.ts +20 -8
- package/dist/runtime/foundation/service-liveness-registry.js +57 -44
- package/dist/runtime/foundation/service-mailbox.d.ts +3 -0
- package/dist/runtime/foundation/service-mailbox.js +2 -1
- package/dist/runtime/foundation/service-stateful-runtime.d.ts +7 -6
- package/dist/runtime/foundation/service-stateful-runtime.js +60 -41
- package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +5 -2
- package/dist/runtime/foundation/service-stateful-wire-codec.js +43 -61
- package/dist/runtime/foundation/service-topology-registry.d.ts +5 -3
- package/dist/runtime/foundation/service-topology-registry.js +9 -4
- package/dist/runtime/handlers/handler-instance-scope.js +1 -1
- package/dist/runtime/host/actor-packet-relay.js +7 -7
- 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 +2 -1
- package/dist/runtime/host/application-job-queue.d.ts +11 -4
- package/dist/runtime/host/application-job-queue.js +66 -10
- package/dist/runtime/host/entry-actor-runtime.js +1 -1
- package/dist/runtime/host/index.d.ts +1 -1
- package/dist/runtime/host/index.js +18 -13
- package/dist/runtime/host/instance-activation-authority.d.ts +2 -1
- package/dist/runtime/host/instance-activation-authority.js +89 -25
- package/dist/runtime/host/service-relocation-host-runtime.js +2 -2
- package/dist/runtime/host/spot-address-transport.d.ts +1 -0
- package/dist/runtime/host/spot-address-transport.js +25 -12
- package/dist/runtime/host/spot-runtime-options-factory.js +2 -2
- package/dist/runtime/host/user-spot-creation-coordinator.d.ts +1 -0
- package/dist/runtime/host/user-spot-creation-coordinator.js +1 -0
- package/dist/runtime/locations/domain-store-contract.d.ts +3 -2
- package/dist/runtime/locations/in-memory-authority-store.d.ts +5 -2
- package/dist/runtime/locations/in-memory-authority-store.js +107 -14
- package/dist/runtime/locations/in-memory-location-store.d.ts +3 -3
- package/dist/runtime/locations/in-memory-location-store.js +31 -13
- package/dist/runtime/locations/internal-location-contracts.d.ts +8 -0
- package/dist/runtime/locations/location-store-repository.d.ts +4 -2
- package/dist/runtime/locations/location-store-repository.js +209 -33
- package/dist/runtime/locations/resolvers.d.ts +2 -1
- package/dist/runtime/locations/resolvers.js +10 -1
- package/dist/runtime/messaging/submission-result.d.ts +1 -1
- package/dist/runtime/messaging/submission-result.js +2 -2
- package/dist/runtime/spots/formal-remote-actor-admission-registry.d.ts +2 -0
- package/dist/runtime/spots/index.d.ts +4 -3
- package/dist/runtime/spots/index.js +14 -14
- package/dist/runtime/spots/spot-activation.d.ts +2 -1
- package/dist/runtime/spots/spot-activation.js +4 -4
- package/dist/runtime/spots/spot-actor-admission-coordinator.d.ts +2 -1
- package/dist/runtime/spots/spot-actor-admission-coordinator.js +11 -10
- package/dist/runtime/spots/spot-actor-packet-dispatch.d.ts +4 -1
- package/dist/runtime/spots/spot-actor-packet-dispatch.js +7 -5
- package/dist/runtime/spots/spot-actor-packet-drain.js +2 -0
- package/dist/runtime/spots/spot-actor-packet-relay-dispatch.js +1 -0
- package/dist/runtime/spots/spot-entry-activation.d.ts +1 -0
- package/dist/runtime/spots/spot-entry-activation.js +6 -1
- package/dist/runtime/spots/spot-node-runtime-manager.d.ts +3 -1
- package/dist/runtime/spots/spot-node-runtime-manager.js +10 -11
- package/dist/runtime/spots/spot-routing-internal.d.ts +6 -0
- package/dist/runtime/spots/spot-runtime-ports.d.ts +2 -1
- package/dist/runtime/spots/spot-serial-executor.d.ts +1 -0
- package/dist/runtime/spots/spot-serial-executor.js +10 -1
- package/dist/runtime/streams/stream-session-runtime.js +1 -1
- package/package.json +3 -3
- package/src/contracts/Configuration/Builders.ts +1 -2
- package/src/contracts/Configuration/Configs.ts +0 -6
- package/src/contracts/Configuration/RegistrationBuilders.ts +8 -12
- package/src/contracts/Configuration/RegistrationTypes.ts +1 -6
- package/src/contracts/Configuration/RegistrationValidators.ts +9 -10
- package/src/contracts/Configuration/index.ts +1 -6
- package/src/internal.ts +1 -0
- package/src/runtime/actors/actor-handoff.ts +13 -4
- package/src/runtime/actors/actor-runtime-contracts.ts +4 -0
- package/src/runtime/actors/index.ts +77 -42
- package/src/runtime/application-jobs/application-ingress-record-owner.ts +12 -2
- package/src/runtime/application-jobs/application-job-queue-scope.ts +6 -1
- package/src/runtime/application-jobs/contracts.ts +14 -1
- package/src/runtime/backend/contracts/index.ts +10 -18
- package/src/runtime/backend/mesh-completion-table.ts +36 -19
- package/src/runtime/backend/mesh-dispatch-pump.ts +19 -22
- package/src/runtime/backend/node/node-backend-adapter-factory.ts +12 -5
- package/src/runtime/backend/node/node-backend-adapter-support.ts +31 -29
- package/src/runtime/backend/node/node-mesh-backend-adapter.ts +3 -10
- package/src/runtime/backend/node/node-raw-binding-port.ts +19 -10
- package/src/runtime/backend/node/node-raw-mesh-backend.ts +81 -111
- package/src/runtime/backend/node/node-socket-backend-adapter.ts +12 -8
- package/src/runtime/backend/raw-binding-port.ts +12 -2
- package/src/runtime/channels/channel-receive-loops.ts +3 -3
- package/src/runtime/channels/channel-runtime-lifecycle.ts +7 -1
- package/src/runtime/channels/channel-socket-registry.ts +84 -130
- package/src/runtime/diagnostics/message-flow.ts +1 -1
- package/src/runtime/foundation/raw-service-mesh-runtime.ts +268 -70
- package/src/runtime/foundation/service-liveness-registry.ts +68 -59
- package/src/runtime/foundation/service-mailbox.ts +7 -1
- package/src/runtime/foundation/service-stateful-runtime.ts +109 -77
- package/src/runtime/foundation/service-stateful-wire-codec.ts +55 -79
- package/src/runtime/foundation/service-topology-registry.ts +13 -7
- package/src/runtime/handlers/handler-instance-scope.ts +2 -1
- package/src/runtime/host/actor-packet-relay.ts +7 -0
- package/src/runtime/host/actor-placement-coordinator.ts +8 -2
- package/src/runtime/host/actor-runtime-options-factory.ts +7 -0
- package/src/runtime/host/application-job-queue.ts +77 -10
- package/src/runtime/host/entry-actor-runtime.ts +1 -0
- package/src/runtime/host/index.ts +30 -7
- package/src/runtime/host/instance-activation-authority.ts +132 -27
- package/src/runtime/host/service-relocation-host-runtime.ts +2 -0
- package/src/runtime/host/spot-address-transport.ts +45 -22
- package/src/runtime/host/spot-runtime-options-factory.ts +2 -0
- package/src/runtime/host/user-spot-creation-coordinator.ts +8 -0
- package/src/runtime/locations/domain-store-contract.ts +6 -2
- package/src/runtime/locations/in-memory-authority-store.ts +153 -12
- package/src/runtime/locations/in-memory-location-store.ts +39 -13
- package/src/runtime/locations/internal-location-contracts.ts +10 -0
- package/src/runtime/locations/location-store-repository.ts +295 -36
- package/src/runtime/locations/resolvers.ts +25 -2
- package/src/runtime/messaging/submission-result.ts +2 -2
- package/src/runtime/spots/formal-remote-actor-admission-registry.ts +2 -0
- package/src/runtime/spots/index.ts +16 -0
- package/src/runtime/spots/spot-activation.ts +5 -0
- package/src/runtime/spots/spot-actor-admission-coordinator.ts +13 -0
- package/src/runtime/spots/spot-actor-packet-dispatch.ts +10 -0
- package/src/runtime/spots/spot-actor-packet-drain.ts +2 -0
- package/src/runtime/spots/spot-actor-packet-relay-dispatch.ts +1 -0
- package/src/runtime/spots/spot-entry-activation.ts +7 -0
- package/src/runtime/spots/spot-node-runtime-manager.ts +14 -12
- package/src/runtime/spots/spot-routing-internal.ts +14 -0
- package/src/runtime/spots/spot-runtime-ports.ts +2 -0
- package/src/runtime/spots/spot-serial-executor.ts +10 -4
- package/src/runtime/streams/stream-session-runtime.ts +1 -1
|
@@ -2,10 +2,13 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ZLinkLocationStoreRepository = void 0;
|
|
4
4
|
const service_relocation_runtime_1 = require("../foundation/service-relocation-runtime");
|
|
5
|
+
const service_authority_payload_codec_1 = require("../foundation/service-authority-payload-codec");
|
|
6
|
+
const actor_authority_payload_codec_1 = require("../actors/actor-authority-payload-codec");
|
|
7
|
+
const contracts_1 = require("../../contracts");
|
|
5
8
|
const stream_wire_1 = require("@zlink-systems/stream-wire");
|
|
6
9
|
const node_crypto_1 = require("node:crypto");
|
|
7
10
|
const Options_1 = require("../../contracts/Locations/Options");
|
|
8
|
-
const
|
|
11
|
+
const contracts_2 = require("../../contracts");
|
|
9
12
|
const CoreTypes_1 = require("../../contracts/Common/CoreTypes");
|
|
10
13
|
const InternalDefaults_1 = require("../../contracts/Configuration/InternalDefaults");
|
|
11
14
|
const RegistrationBuilderPolicy_1 = require("../../contracts/Configuration/RegistrationBuilderPolicy");
|
|
@@ -215,9 +218,27 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
215
218
|
payload: Buffer.from(mutation.payload)
|
|
216
219
|
}
|
|
217
220
|
};
|
|
221
|
+
const actor = mutation.kind !== 'delete' && record.snapshot.allocation.objectKind === 'actor'
|
|
222
|
+
? (0, actor_authority_payload_codec_1.decodeActorAuthorityPayload)((0, service_relocation_runtime_1.serviceRelocationAuthorityApplicationPayload)(mutation.payload))
|
|
223
|
+
: undefined;
|
|
224
|
+
const previousActor = actor === undefined
|
|
225
|
+
? undefined
|
|
226
|
+
: (0, actor_authority_payload_codec_1.decodeActorAuthorityPayload)((0, service_relocation_runtime_1.serviceRelocationAuthorityApplicationPayload)(record.snapshot.payload));
|
|
227
|
+
const membershipConditions = actor?.currentSpotKind === contracts_1.ZLinkSpotKind.User &&
|
|
228
|
+
(previousActor?.currentSpotKind !== contracts_1.ZLinkSpotKind.User ||
|
|
229
|
+
previousActor.currentSpotId !== actor.currentSpotId ||
|
|
230
|
+
previousActor.currentSpotGeneration !== actor.currentSpotGeneration)
|
|
231
|
+
? await this.userSpotMembershipConditions(actor.currentSpotId, actor.currentSpotGeneration, signal, {
|
|
232
|
+
ownerId: record.snapshot.ownerId,
|
|
233
|
+
leaseGeneration: record.snapshot.ownerLeaseGeneration
|
|
234
|
+
})
|
|
235
|
+
: [];
|
|
236
|
+
if (membershipConditions === undefined)
|
|
237
|
+
return { kind: 'conflict', current: snapshot };
|
|
218
238
|
const result = await this.provider.write({
|
|
219
239
|
conditions: [
|
|
220
240
|
{ kind: 'version', key: rowKey, expected: current.value.version },
|
|
241
|
+
...membershipConditions,
|
|
221
242
|
...(mutation.kind === 'restore'
|
|
222
243
|
? []
|
|
223
244
|
: [
|
|
@@ -654,7 +675,7 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
654
675
|
sha256Hex(membership) !== entry.membershipMutationSha256) {
|
|
655
676
|
throw new Error('Aggregate participant staging checksum does not match inventory.');
|
|
656
677
|
}
|
|
657
|
-
authorityRows.push({ key: rowKeyForParticipant, current, record, entry });
|
|
678
|
+
authorityRows.push({ key: rowKeyForParticipant, current, record, entry, payload });
|
|
658
679
|
}
|
|
659
680
|
const targetDescriptorKey = meshKey(aggregate.targetDescriptor.meshName, aggregate.targetDescriptor.rid);
|
|
660
681
|
const targetLeaseKey = ownerKey(aggregate.targetOwner.ownerId);
|
|
@@ -717,11 +738,34 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
717
738
|
bytes: encodeJson(capacity)
|
|
718
739
|
});
|
|
719
740
|
}
|
|
741
|
+
const membershipConditions = [];
|
|
742
|
+
for (const row of authorityRows) {
|
|
743
|
+
if (row.record.snapshot.allocation.objectKind !== 'actor')
|
|
744
|
+
continue;
|
|
745
|
+
const actor = (0, actor_authority_payload_codec_1.decodeActorAuthorityPayload)((0, service_relocation_runtime_1.serviceRelocationAuthorityApplicationPayload)(row.payload));
|
|
746
|
+
if (actor?.currentSpotKind !== contracts_1.ZLinkSpotKind.User)
|
|
747
|
+
continue;
|
|
748
|
+
const spotKey = (0, authority_key_codec_1.encodeAuthorityKey)('user_spot', actor.currentSpotId);
|
|
749
|
+
const participantSpot = authorityRows.find((candidate) => candidate.entry.authorityKey === spotKey.value);
|
|
750
|
+
if (participantSpot !== undefined) {
|
|
751
|
+
if (participantSpot.record.snapshot.allocation.objectKind !== 'user_spot' ||
|
|
752
|
+
participantSpot.record.snapshot.objectGeneration !== actor.currentSpotGeneration)
|
|
753
|
+
return { kind: 'stale' };
|
|
754
|
+
continue;
|
|
755
|
+
}
|
|
756
|
+
if (membershipConditions.some((condition) => condition.key.value === authorityKey(spotKey.value).value))
|
|
757
|
+
continue;
|
|
758
|
+
const conditions = await this.userSpotMembershipConditions(actor.currentSpotId, actor.currentSpotGeneration, signal, aggregate.targetOwner);
|
|
759
|
+
if (conditions === undefined)
|
|
760
|
+
return { kind: 'stale' };
|
|
761
|
+
membershipConditions.push(...conditions.filter((condition) => !membershipConditions.some((existing) => existing.key.value === condition.key.value)));
|
|
762
|
+
}
|
|
720
763
|
const published = await this.provider.write({
|
|
721
764
|
conditions: [
|
|
722
765
|
{ kind: 'version', key: rowKey, expected: aggregateRead.value.version },
|
|
723
766
|
versionCondition(targetDescriptorKey, descriptorRead),
|
|
724
767
|
leaseValueCondition(targetLeaseKey, aggregate.targetOwner),
|
|
768
|
+
...membershipConditions,
|
|
725
769
|
...[...capacityReads.entries()].map(([value, read]) => ({
|
|
726
770
|
kind: 'version',
|
|
727
771
|
key: capacityKeys.get(value),
|
|
@@ -814,18 +858,21 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
814
858
|
return { kind: 'aborted' };
|
|
815
859
|
}
|
|
816
860
|
}
|
|
817
|
-
async releaseEndedReservation(key, expectedStoreVersion, signal) {
|
|
861
|
+
async releaseEndedReservation(key, expectedStoreVersion, signal, request) {
|
|
862
|
+
return ((await this.tryReleaseEndedReservation(key, expectedStoreVersion, signal, request)) ===
|
|
863
|
+
'reclaimed');
|
|
864
|
+
}
|
|
865
|
+
async tryReleaseEndedReservation(key, expectedStoreVersion, signal, request) {
|
|
818
866
|
const rowKey = authorityKey(key.value);
|
|
819
867
|
const current = await this.provider.read(rowKey, signal);
|
|
820
868
|
if (current.kind === 'missing' || current.value.version.value !== expectedStoreVersion)
|
|
821
|
-
return
|
|
869
|
+
return 'conflict';
|
|
822
870
|
const record = decodeAuthorityRecord(current.value.bytes);
|
|
823
871
|
const snapshot = record.snapshot;
|
|
824
|
-
if (snapshot.allocation.state
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
return false;
|
|
872
|
+
if (snapshot.allocation.state === 'active'
|
|
873
|
+
? request === undefined
|
|
874
|
+
: snapshot.pendingCreation === undefined)
|
|
875
|
+
return 'notReclaimable';
|
|
829
876
|
const leaseKey = ownerKey(snapshot.ownerId);
|
|
830
877
|
const descriptorKey = meshKey(snapshot.allocation.descriptor.meshName, snapshot.allocation.descriptor.rid);
|
|
831
878
|
const capacityRowKey = capacityKey(snapshot.allocation.descriptor.meshName, String(snapshot.allocation.descriptor.rid));
|
|
@@ -836,23 +883,95 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
836
883
|
]);
|
|
837
884
|
if (lease.kind === 'found' && lease.value.expiresAt === undefined)
|
|
838
885
|
throw new Error('Location Store owner lease record is invalid.');
|
|
839
|
-
|
|
886
|
+
const ownerLive = sameLiveOwner(lease, snapshot);
|
|
887
|
+
if (snapshot.allocation.state === 'active') {
|
|
888
|
+
if (ownerLive)
|
|
889
|
+
return 'notReclaimable';
|
|
890
|
+
let unavailable = record.aggregate !== undefined || hasRelocationAuthority(snapshot.payload);
|
|
891
|
+
if (snapshot.allocation.objectKind !== 'actor') {
|
|
892
|
+
const spot = (0, service_authority_payload_codec_1.decodeServiceReadySpotAuthority)(snapshot.payload);
|
|
893
|
+
unavailable ||=
|
|
894
|
+
spot === undefined ||
|
|
895
|
+
spot.kind !== request?.key.kind ||
|
|
896
|
+
spot.stableType !== request.intent.stableType ||
|
|
897
|
+
spot.spotId !== request.key.globalId ||
|
|
898
|
+
spot.activationRecovery !== undefined;
|
|
899
|
+
if (spot?.kind === 'user_spot') {
|
|
900
|
+
// The snapshot starts only after the old owner's lease was found invalid.
|
|
901
|
+
for (const prefix of [`${PREFIX}actor:`, `${AUTHORITY_PREIMAGE_PREFIX}actor\0`]) {
|
|
902
|
+
membershipSnapshot: for (;;) {
|
|
903
|
+
let snapshotHasMember = false;
|
|
904
|
+
let cursor;
|
|
905
|
+
do {
|
|
906
|
+
const page = await this.provider.scan({ prefix, cursor, limit: Stores_1.ZLINK_PROVIDER_MAX_PAGE_SIZE }, signal);
|
|
907
|
+
if (page.kind === 'expired')
|
|
908
|
+
continue membershipSnapshot;
|
|
909
|
+
for (const item of page.value.items) {
|
|
910
|
+
if (prefix === `${PREFIX}actor:`) {
|
|
911
|
+
const actor = normalizeActor(decodeJson(item.value.bytes).descriptor);
|
|
912
|
+
snapshotHasMember ||=
|
|
913
|
+
actor.spotKind === contracts_1.ZLinkSpotKind.User &&
|
|
914
|
+
String(actor.spotId) === spot.spotId &&
|
|
915
|
+
actor.spotGeneration === snapshot.objectGeneration;
|
|
916
|
+
}
|
|
917
|
+
else {
|
|
918
|
+
const authority = decodeAuthorityRecord(item.value.bytes).snapshot;
|
|
919
|
+
if (authority.allocation.objectKind !== 'actor')
|
|
920
|
+
continue;
|
|
921
|
+
const actor = (0, actor_authority_payload_codec_1.decodeActorAuthorityPayload)((0, service_relocation_runtime_1.serviceRelocationAuthorityApplicationPayload)(authority.payload));
|
|
922
|
+
snapshotHasMember ||=
|
|
923
|
+
actor?.currentSpotKind === contracts_1.ZLinkSpotKind.User &&
|
|
924
|
+
actor.currentSpotId === spot.spotId &&
|
|
925
|
+
actor.currentSpotGeneration === snapshot.objectGeneration;
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
cursor = page.value.nextCursor;
|
|
929
|
+
} while (cursor !== undefined);
|
|
930
|
+
unavailable ||= snapshotHasMember;
|
|
931
|
+
break;
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
if (unavailable || request?.actorRelocationPolicy !== 'disabled')
|
|
937
|
+
throw new contracts_2.ZLinkFrameworkException(contracts_2.ZLinkFrameworkErrorKind.Unavailable, 'Object owner lease is unavailable.');
|
|
938
|
+
}
|
|
939
|
+
else if (ownerLive &&
|
|
840
940
|
descriptor.kind === 'found' &&
|
|
841
941
|
reviveMeshDescriptor(decodeCanonicalDescriptorRecord(descriptor.value.bytes).descriptor).lifecycleGeneration === snapshot.allocation.descriptorLifecycleGeneration)
|
|
842
|
-
return
|
|
942
|
+
return 'notReclaimable';
|
|
943
|
+
if (snapshot.allocation.state !== 'active' &&
|
|
944
|
+
(record.aggregate !== undefined || hasRelocationAuthority(snapshot.payload)))
|
|
945
|
+
return 'notReclaimable';
|
|
843
946
|
const mutations = [
|
|
844
947
|
{ kind: 'delete', key: rowKey }
|
|
845
948
|
];
|
|
846
949
|
if (capacity.kind === 'found') {
|
|
847
950
|
const stored = decodeJson(capacity.value.bytes);
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
951
|
+
try {
|
|
952
|
+
mutations.push({
|
|
953
|
+
kind: 'put',
|
|
954
|
+
key: capacityRowKey,
|
|
955
|
+
bytes: encodeJson({
|
|
956
|
+
active: snapshot.allocation.state === 'active'
|
|
957
|
+
? subtractCapacity(stored.active, snapshot.allocation.capacity)
|
|
958
|
+
: stored.active,
|
|
959
|
+
pending: snapshot.allocation.state === 'reserved'
|
|
960
|
+
? subtractCapacity(stored.pending, snapshot.allocation.capacity)
|
|
961
|
+
: stored.pending
|
|
962
|
+
})
|
|
963
|
+
});
|
|
964
|
+
}
|
|
965
|
+
catch (error) {
|
|
966
|
+
if (!(error instanceof contracts_2.ZLinkFrameworkException) ||
|
|
967
|
+
error.kind !== contracts_2.ZLinkFrameworkErrorKind.DataLost)
|
|
968
|
+
throw error;
|
|
969
|
+
const observed = await this.provider.read(rowKey, signal);
|
|
970
|
+
if (observed.kind === 'missing' ||
|
|
971
|
+
observed.value.version.value !== current.value.version.value)
|
|
972
|
+
return 'conflict';
|
|
973
|
+
throw error;
|
|
974
|
+
}
|
|
856
975
|
}
|
|
857
976
|
const result = await this.provider.write({
|
|
858
977
|
conditions: [
|
|
@@ -863,11 +982,12 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
863
982
|
],
|
|
864
983
|
mutations
|
|
865
984
|
}, signal);
|
|
866
|
-
return result.kind === 'applied';
|
|
985
|
+
return result.kind === 'applied' ? 'reclaimed' : 'conflict';
|
|
867
986
|
}
|
|
868
987
|
async reserve(request, signal, deadlineUnixMs) {
|
|
869
988
|
const encodedAuthorityKey = (0, authority_key_codec_1.encodeAuthorityKey)(request.key.kind, request.key.globalId);
|
|
870
989
|
const reservationId = (0, node_crypto_1.randomUUID)();
|
|
990
|
+
let reclaimVersion;
|
|
871
991
|
for (;;) {
|
|
872
992
|
throwIfOperationExpired(signal, deadlineUnixMs);
|
|
873
993
|
const rowKey = authorityKey(encodedAuthorityKey.value);
|
|
@@ -882,19 +1002,24 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
882
1002
|
snapshot.allocation.stableType !== request.intent.stableType) {
|
|
883
1003
|
return { kind: 'typeMismatch', current: snapshot };
|
|
884
1004
|
}
|
|
885
|
-
if (snapshot.
|
|
886
|
-
return { kind: 'alreadyExists', current: snapshot };
|
|
887
|
-
}
|
|
888
|
-
if (!(await this.releaseEndedReservation(encodedAuthorityKey, current.value.version.value, signal)))
|
|
1005
|
+
if (reclaimVersion !== undefined && snapshot.storeVersion.value !== reclaimVersion)
|
|
889
1006
|
return { kind: 'conflict', current: snapshot };
|
|
1007
|
+
const reclaim = await this.tryReleaseEndedReservation(encodedAuthorityKey, current.value.version.value, signal, request);
|
|
1008
|
+
if (reclaim === 'notReclaimable')
|
|
1009
|
+
return snapshot.allocation.state === 'active'
|
|
1010
|
+
? { kind: 'alreadyExists', current: snapshot }
|
|
1011
|
+
: { kind: 'conflict', current: snapshot };
|
|
1012
|
+
reclaimVersion = reclaim === 'conflict' ? snapshot.storeVersion.value : undefined;
|
|
890
1013
|
continue;
|
|
891
1014
|
}
|
|
1015
|
+
if (reclaimVersion !== undefined)
|
|
1016
|
+
return { kind: 'conflict', current: { kind: 'missing', storeNow: current.storeNow } };
|
|
892
1017
|
const [descriptorRead, leaseRead] = await Promise.all([
|
|
893
1018
|
this.provider.read(descriptorKey, signal),
|
|
894
1019
|
this.provider.read(leaseKey, signal)
|
|
895
1020
|
]);
|
|
896
1021
|
const descriptor = liveTargetDescriptor(descriptorRead, leaseRead, request.target);
|
|
897
|
-
if (descriptor === undefined || descriptor.state !==
|
|
1022
|
+
if (descriptor === undefined || descriptor.state !== contracts_2.ZLinkFrameworkRuntimeState.Serving) {
|
|
898
1023
|
return { kind: 'conflict', current: { kind: 'missing', storeNow: current.storeNow } };
|
|
899
1024
|
}
|
|
900
1025
|
const [capacityRead, objectGenerationRead, authorityOwnerGenerationRead] = await Promise.all([
|
|
@@ -1171,6 +1296,14 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
1171
1296
|
if (retentionMs <= 0) {
|
|
1172
1297
|
throw new RangeError('Creation terminal expiry must be the live operation deadline plus five minutes.');
|
|
1173
1298
|
}
|
|
1299
|
+
const actor = request.completion.kind === 'created'
|
|
1300
|
+
? (0, actor_authority_payload_codec_1.decodeActorAuthorityPayload)((0, service_relocation_runtime_1.serviceRelocationAuthorityApplicationPayload)(request.completion.readyPayload))
|
|
1301
|
+
: undefined;
|
|
1302
|
+
const membershipConditions = actor?.currentSpotKind === contracts_1.ZLinkSpotKind.User
|
|
1303
|
+
? await this.userSpotMembershipConditions(actor.currentSpotId, actor.currentSpotGeneration, signal, request.target.owner)
|
|
1304
|
+
: [];
|
|
1305
|
+
if (membershipConditions === undefined)
|
|
1306
|
+
return { kind: 'stale' };
|
|
1174
1307
|
const mutations = request.completion.kind === 'created'
|
|
1175
1308
|
? [
|
|
1176
1309
|
{
|
|
@@ -1210,6 +1343,7 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
1210
1343
|
conditions: [
|
|
1211
1344
|
{ kind: 'version', key: rowKey, expected: current.value.version },
|
|
1212
1345
|
{ kind: 'missing', key: terminalRowKey },
|
|
1346
|
+
...membershipConditions,
|
|
1213
1347
|
versionCondition(descriptorKey, descriptorRead),
|
|
1214
1348
|
leaseValueCondition(leaseKey, request.target.owner),
|
|
1215
1349
|
conditionFor(capacityRowKey, capacityRead)
|
|
@@ -1472,7 +1606,7 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
1472
1606
|
return this.listOwnedLocations(`${PREFIX}spot:`, page, normalizeSpot, (value) => matchesSpot(value, filter), signal);
|
|
1473
1607
|
}
|
|
1474
1608
|
async updateActor(location, intent, signal) {
|
|
1475
|
-
return this.updateOwnedLocation(actorKey(location.meshName, location.actorId), normalizeActor(location), intent, signal);
|
|
1609
|
+
return this.updateOwnedLocation(actorKey(location.meshName, location.actorId), normalizeActor(location), intent, signal, location);
|
|
1476
1610
|
}
|
|
1477
1611
|
async removeActor(key, owner, signal) {
|
|
1478
1612
|
return this.removeOwnedLocation(actorKey(key.meshName, key.actorId), owner, signal);
|
|
@@ -1841,7 +1975,37 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
1841
1975
|
continuationToken: result.value.nextCursor?.value
|
|
1842
1976
|
};
|
|
1843
1977
|
}
|
|
1844
|
-
async
|
|
1978
|
+
async userSpotMembershipConditions(spotId, objectGeneration, signal, conditionedOwner) {
|
|
1979
|
+
const key = authorityKey((0, authority_key_codec_1.encodeAuthorityKey)('user_spot', spotId).value);
|
|
1980
|
+
const read = await this.provider.read(key, signal);
|
|
1981
|
+
if (read.kind === 'missing')
|
|
1982
|
+
return undefined;
|
|
1983
|
+
const record = decodeAuthorityRecord(read.value.bytes);
|
|
1984
|
+
const snapshot = record.snapshot;
|
|
1985
|
+
if (record.aggregate !== undefined ||
|
|
1986
|
+
snapshot.allocation.objectKind !== 'user_spot' ||
|
|
1987
|
+
snapshot.allocation.state !== 'active' ||
|
|
1988
|
+
snapshot.objectGeneration !== objectGeneration ||
|
|
1989
|
+
(0, service_authority_payload_codec_1.decodeServiceReadySpotAuthority)(snapshot.payload)?.kind !== 'user_spot')
|
|
1990
|
+
return undefined;
|
|
1991
|
+
const leaseKey = ownerKey(snapshot.ownerId);
|
|
1992
|
+
const lease = await this.provider.read(leaseKey, signal);
|
|
1993
|
+
if (!sameLiveOwner(lease, snapshot))
|
|
1994
|
+
return undefined;
|
|
1995
|
+
return [
|
|
1996
|
+
{ kind: 'version', key, expected: read.value.version },
|
|
1997
|
+
...(conditionedOwner?.ownerId === snapshot.ownerId &&
|
|
1998
|
+
conditionedOwner.leaseGeneration === snapshot.ownerLeaseGeneration
|
|
1999
|
+
? []
|
|
2000
|
+
: [
|
|
2001
|
+
leaseValueCondition(leaseKey, {
|
|
2002
|
+
ownerId: snapshot.ownerId,
|
|
2003
|
+
leaseGeneration: snapshot.ownerLeaseGeneration
|
|
2004
|
+
})
|
|
2005
|
+
])
|
|
2006
|
+
];
|
|
2007
|
+
}
|
|
2008
|
+
async updateOwnedLocation(rowKey, location, intent, signal, membership) {
|
|
1845
2009
|
const leaseKey = ownerKey(location.ownerId);
|
|
1846
2010
|
const [lease, current] = await Promise.all([
|
|
1847
2011
|
this.provider.read(leaseKey, signal),
|
|
@@ -1886,13 +2050,25 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
|
|
|
1886
2050
|
else if (intent === 2) {
|
|
1887
2051
|
return rejected(lease.value.storeNow);
|
|
1888
2052
|
}
|
|
2053
|
+
const previousMembership = current.kind === 'found' && membership !== undefined
|
|
2054
|
+
? decodeJson(current.value.bytes).descriptor
|
|
2055
|
+
: undefined;
|
|
2056
|
+
const membershipConditions = membership?.spotKind === contracts_1.ZLinkSpotKind.User &&
|
|
2057
|
+
(previousMembership?.spotKind !== contracts_1.ZLinkSpotKind.User ||
|
|
2058
|
+
String(previousMembership.spotId) !== String(membership.spotId) ||
|
|
2059
|
+
BigInt(previousMembership.spotGeneration) !== membership.spotGeneration)
|
|
2060
|
+
? await this.userSpotMembershipConditions(String(membership.spotId), membership.spotGeneration, signal, { ownerId: location.ownerId, leaseGeneration: locationOwnerGeneration(location) })
|
|
2061
|
+
: [];
|
|
2062
|
+
if (membershipConditions === undefined)
|
|
2063
|
+
return rejected(lease.value.storeNow);
|
|
1889
2064
|
const result = await this.provider.write({
|
|
1890
2065
|
conditions: [
|
|
1891
2066
|
leaseValueCondition(leaseKey, {
|
|
1892
2067
|
ownerId: location.ownerId,
|
|
1893
2068
|
leaseGeneration: locationOwnerGeneration(location)
|
|
1894
2069
|
}),
|
|
1895
|
-
rowCondition
|
|
2070
|
+
rowCondition,
|
|
2071
|
+
...membershipConditions
|
|
1896
2072
|
],
|
|
1897
2073
|
mutations: [
|
|
1898
2074
|
{
|
|
@@ -2880,7 +3056,7 @@ function liveTargetDescriptor(descriptorRead, leaseRead, target) {
|
|
|
2880
3056
|
descriptor.lifecycleGeneration === target.nodeLifecycleGeneration &&
|
|
2881
3057
|
descriptor.ownerId === target.owner.ownerId &&
|
|
2882
3058
|
descriptor.leaseGeneration === target.owner.leaseGeneration &&
|
|
2883
|
-
descriptor.objectRole ===
|
|
3059
|
+
descriptor.objectRole === contracts_2.ZLinkObjectRole.Server &&
|
|
2884
3060
|
lease.ownerId === target.owner.ownerId &&
|
|
2885
3061
|
BigInt(lease.leaseGeneration) === target.owner.leaseGeneration &&
|
|
2886
3062
|
leaseRead.value.expiresAt !== undefined &&
|
|
@@ -2941,7 +3117,7 @@ function adjustCapacity(usage, delta, direction) {
|
|
|
2941
3117
|
const key = capacityTypeKey(delta.spotType);
|
|
2942
3118
|
const next = (spotTypes[key] ?? 0) + direction * delta.spotType.count;
|
|
2943
3119
|
if (next < 0)
|
|
2944
|
-
throw new
|
|
3120
|
+
throw new contracts_2.ZLinkFrameworkException(contracts_2.ZLinkFrameworkErrorKind.DataLost, 'Provider capacity counter underflow.');
|
|
2945
3121
|
if (next === 0)
|
|
2946
3122
|
delete spotTypes[key];
|
|
2947
3123
|
else
|
|
@@ -2950,7 +3126,7 @@ function adjustCapacity(usage, delta, direction) {
|
|
|
2950
3126
|
const actors = usage.actors + direction * delta.actors;
|
|
2951
3127
|
const spots = usage.spots + direction * delta.spots;
|
|
2952
3128
|
if (actors < 0 || spots < 0)
|
|
2953
|
-
throw new
|
|
3129
|
+
throw new contracts_2.ZLinkFrameworkException(contracts_2.ZLinkFrameworkErrorKind.DataLost, 'Provider capacity counter underflow.');
|
|
2954
3130
|
return { actors, spots, spotTypes };
|
|
2955
3131
|
}
|
|
2956
3132
|
function capacityTypeKey(value) {
|
|
@@ -3275,10 +3451,10 @@ function throwIfOperationExpired(signal, deadlineUnixMs) {
|
|
|
3275
3451
|
}
|
|
3276
3452
|
// Store SPI §6: preserve caller failures and classify provider failures once.
|
|
3277
3453
|
function locationStoreProviderFailure(error, signal) {
|
|
3278
|
-
if (error instanceof
|
|
3454
|
+
if (error instanceof contracts_2.ZLinkFrameworkException ||
|
|
3279
3455
|
error instanceof TypeError ||
|
|
3280
3456
|
error instanceof RangeError ||
|
|
3281
3457
|
signal?.aborted === true)
|
|
3282
3458
|
return error;
|
|
3283
|
-
return new
|
|
3459
|
+
return new contracts_2.ZLinkFrameworkException(contracts_2.ZLinkFrameworkErrorKind.Unavailable, 'Location Store provider is unavailable.', error);
|
|
3284
3460
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ActorRef, RoutingId, SpotId } from '../../contracts/Common';
|
|
2
2
|
import { type SpotHandle, type ZLinkActorSpotHandleResolver, type ZLinkSpotHandleResolver, type ResolvedSpotHandle } from '../spots/spot-handle';
|
|
3
|
-
import type { ZLinkSpotRouteResolver, ZLinkSpotRouteTarget } from '../spots/spot-routing-internal';
|
|
3
|
+
import type { ZLinkSpotRouteResolver, ZLinkSpotRouteTarget, ZLinkInstanceReactivationRoute } from '../spots/spot-routing-internal';
|
|
4
4
|
import { ZLinkFrameworkRuntimeState, ZLinkLocationRole, type ZLinkActorLocation, type ZLinkActorLocationKey, type ZLinkLocationReadiness, type ZLinkLocationRuntimeQuery, type ZLinkPeerLocation, type ZLinkPeerLocationFilter, type ZLinkPeerLocationResolver, type ZLinkRouteLocation, type ZLinkRouteLocationKey, type ZLinkSpotLocation, type ZLinkSpotLocationKey } from './internal-location-contracts';
|
|
5
5
|
import type { ZLinkActorLocationStore, ZLinkAuthorityStore, ZLinkMeshNodeLocationStore, ZLinkPeerLocationStore, ZLinkRouteLocationStore, ZLinkSpotLocationStore } from './internal-store-contracts';
|
|
6
6
|
import { ZLinkOwnerLeaseTracker } from './lease-tracker';
|
|
@@ -135,6 +135,7 @@ export declare class ZLinkAuthoritySpotRouteResolver implements ZLinkSpotRouteRe
|
|
|
135
135
|
private readonly routeEpochs;
|
|
136
136
|
private readonly activeResolutions;
|
|
137
137
|
constructor(store: ZLinkAuthorityStore, routerChannelIdForMesh: (meshName: string) => string, fallback?: ZLinkSpotRouteResolver | undefined, leaseTracker?: ZLinkOwnerLeaseTracker | undefined, routeCacheMaxAgeMs?: number, monotonicNowMs?: () => number, targetNodeStateResolver?: ((meshName: string, nodeRid: RoutingId, expectedLifecycleGeneration: bigint, signal?: AbortSignal) => Promise<ZLinkFrameworkRuntimeState | undefined>) | undefined);
|
|
138
|
+
resolve(spotId: RoutingId, signal: AbortSignal | undefined, instanceIntent: true): Promise<ZLinkSpotRouteTarget | ZLinkInstanceReactivationRoute>;
|
|
138
139
|
resolve(spotId: RoutingId, signal?: AbortSignal): Promise<ZLinkSpotRouteTarget>;
|
|
139
140
|
invalidate(spotId: RoutingId): void;
|
|
140
141
|
private invalidateCore;
|
|
@@ -583,7 +583,7 @@ class ZLinkAuthoritySpotRouteResolver {
|
|
|
583
583
|
this.monotonicNowMs = monotonicNowMs;
|
|
584
584
|
this.targetNodeStateResolver = targetNodeStateResolver;
|
|
585
585
|
}
|
|
586
|
-
async resolve(spotId, signal) {
|
|
586
|
+
async resolve(spotId, signal, instanceIntent) {
|
|
587
587
|
const key = String(spotId);
|
|
588
588
|
const prepared = await this.lane.run(() => this.beginResolutionCore(key));
|
|
589
589
|
try {
|
|
@@ -606,6 +606,15 @@ class ZLinkAuthoritySpotRouteResolver {
|
|
|
606
606
|
leaseGeneration: current.ownerLeaseGeneration
|
|
607
607
|
}, signal);
|
|
608
608
|
if (remainingLeaseMs !== undefined && remainingLeaseMs <= 0) {
|
|
609
|
+
if (instanceIntent === true && ready?.kind === 'instance_spot') {
|
|
610
|
+
return {
|
|
611
|
+
kind: 'coldActivation',
|
|
612
|
+
spotId,
|
|
613
|
+
spotKind: Spots_1.ZLinkSpotKind.Instance,
|
|
614
|
+
meshName: ready.ownerMeshName,
|
|
615
|
+
stableType: ready.stableType
|
|
616
|
+
};
|
|
617
|
+
}
|
|
609
618
|
throw new Errors_1.ZLinkFrameworkException(Errors_1.ZLinkFrameworkErrorKind.Unavailable, `SPOT '${spotId}' Ready authority owner lease is unavailable.`);
|
|
610
619
|
}
|
|
611
620
|
const target = {
|
|
@@ -10,7 +10,7 @@ export declare enum ZLinkSubmitStatus {
|
|
|
10
10
|
export interface ZLinkSubmitResult {
|
|
11
11
|
readonly status: ZLinkSubmitStatus;
|
|
12
12
|
}
|
|
13
|
-
/** Projects
|
|
13
|
+
/** Projects typed submit failure; capacity refusal has no admission wait token. */
|
|
14
14
|
export declare function submitToRequestResult(result: number, phase: 'submit' | 'completion'): number;
|
|
15
15
|
export declare function classifySubmitResult(result: number, operation: string, phase?: 'submit' | 'completion'): ZLinkSubmitResult;
|
|
16
16
|
export declare function requireOneWayCompletion(result: ZLinkSubmitResult, operation: string, notFoundKind?: ZLinkFrameworkInternalErrorKind): void;
|
|
@@ -19,13 +19,13 @@ var ZLinkSubmitStatus;
|
|
|
19
19
|
ZLinkSubmitStatus["RouteNotConnected"] = "routeNotConnected";
|
|
20
20
|
ZLinkSubmitStatus["Shutdown"] = "shutdown";
|
|
21
21
|
})(ZLinkSubmitStatus || (exports.ZLinkSubmitStatus = ZLinkSubmitStatus = {}));
|
|
22
|
-
/** Projects
|
|
22
|
+
/** Projects typed submit failure; capacity refusal has no admission wait token. */
|
|
23
23
|
function submitToRequestResult(result, phase) {
|
|
24
24
|
switch (result) {
|
|
25
25
|
case runtime_values_1.SubmitResult.Ok:
|
|
26
26
|
return runtime_values_1.RequestResult.Ok;
|
|
27
27
|
case runtime_values_1.SubmitResult.Backpressured:
|
|
28
|
-
return
|
|
28
|
+
return runtime_values_1.RequestResult.NotConnected;
|
|
29
29
|
case runtime_values_1.SubmitResult.NotConnected:
|
|
30
30
|
return runtime_values_1.RequestResult.NotConnected;
|
|
31
31
|
case runtime_values_1.SubmitResult.NotFound:
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ApplicationJobOrigin } from '../application-jobs/contracts';
|
|
1
2
|
import type { ActorRef, RoutingId, ZLinkActor, ZLinkActorJoinOperationId } from '../../contracts';
|
|
2
3
|
import type { ZLinkRemoteBoundSessionTarget } from '../actors/actor-runtime-state';
|
|
3
4
|
import type { ZLinkDeferredJoinCompletion } from '../actors/deferred-join-completion';
|
|
@@ -10,6 +11,7 @@ import type { ZLinkActorRequestTerminal } from './spot-actor-packet-dispatch';
|
|
|
10
11
|
* how long the underlying buffer stays valid.
|
|
11
12
|
*/
|
|
12
13
|
export interface ZLinkParkedActorArrival {
|
|
14
|
+
readonly origin: ApplicationJobOrigin;
|
|
13
15
|
readonly header: Buffer;
|
|
14
16
|
readonly payload: Buffer;
|
|
15
17
|
readonly returnResponse: boolean;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ApplicationJobOrigin } from '../application-jobs/contracts';
|
|
1
2
|
import type { ActorRef, RoutingId, Type, ZLinkMessageSerializer, ZLinkInstanceSpot, ZLinkActor, ZLinkChannelClient, ZLinkFanoutClient, ZLinkSpot, ZLinkSpotActorJoinResult, ZLinkSpotInfo, ZLinkSpotPublisherClient } from '../../contracts';
|
|
2
3
|
import type { ZLinkProviderResolver } from '../../contracts/Common/ZLinkProviderResolver';
|
|
3
4
|
import type { ZLinkSpotActorRequestHandlerRegistration, ZLinkSpotActorSendHandlerRegistration, ZLinkSpotPacketHandlerRegistration, ZLinkSpotSubscriptionHandlerRegistration, ZLinkSpotTimerHandlerRegistration } from '../../contracts/Configuration/RegistrationTypes';
|
|
@@ -55,7 +56,7 @@ export interface ZLinkSpotManagerOptions {
|
|
|
55
56
|
readonly entrySpotCallbacks?: {
|
|
56
57
|
onLeaveActor(actor: ZLinkActor, signal?: AbortSignal, actorRef?: ActorRef, membershipEpoch?: bigint): Promise<void>;
|
|
57
58
|
};
|
|
58
|
-
readonly dispatchEntryActorPacket?: (actorId: string, parts: readonly Message[], returnResponse?: boolean, remoteBoundSessionTarget?: ZLinkRemoteBoundSessionTarget, fallbackActorRef?: ActorRef, requestTerminal?: (response: unknown) => Promise<void> | void, messageFollowOrigin?: ZLinkMessageFollowOrigin) => Promise<unknown>;
|
|
59
|
+
readonly dispatchEntryActorPacket?: (origin: ApplicationJobOrigin, actorId: string, parts: readonly Message[], returnResponse?: boolean, remoteBoundSessionTarget?: ZLinkRemoteBoundSessionTarget, fallbackActorRef?: ActorRef, requestTerminal?: (response: unknown) => Promise<void> | void, messageFollowOrigin?: ZLinkMessageFollowOrigin) => Promise<unknown>;
|
|
59
60
|
/**
|
|
60
61
|
* Commits a stateful MeshNode Actor return to the Entry Spot after the
|
|
61
62
|
* stateful reply has committed Core membership.
|
|
@@ -200,7 +201,7 @@ export declare class DefaultZLinkSpotManager {
|
|
|
200
201
|
beginActorTransfer(spotId: RoutingId, actorId: string): Promise<void>;
|
|
201
202
|
cancelActorTransfer(spotId: RoutingId, actorId: string): Promise<void>;
|
|
202
203
|
notifyJoinedSpotActorDisconnected(spotId: RoutingId, actor: ZLinkActor, signal?: AbortSignal): Promise<boolean>;
|
|
203
|
-
dispatchRoutedActorPacket(spotId: RoutingId, actorId: string, parts: readonly Message[], returnResponse?: boolean, remoteBoundSessionTarget?: ZLinkRemoteBoundSessionTarget, fallbackActorRef?: ActorRef): Promise<unknown>;
|
|
204
|
+
dispatchRoutedActorPacket(origin: ApplicationJobOrigin, spotId: RoutingId, actorId: string, parts: readonly Message[], returnResponse?: boolean, remoteBoundSessionTarget?: ZLinkRemoteBoundSessionTarget, fallbackActorRef?: ActorRef): Promise<unknown>;
|
|
204
205
|
dispatchRoutedSpotSend(spotId: RoutingId, packetName: string | undefined, message: unknown, context: {
|
|
205
206
|
readonly channelName: string;
|
|
206
207
|
readonly contentType?: string;
|
|
@@ -220,7 +221,7 @@ export declare class DefaultZLinkSpotManager {
|
|
|
220
221
|
dispatchMeshInstance(meshName: string, owner: ReadyRecord, record: ReceiveRecord): Promise<void>;
|
|
221
222
|
private reportInstanceDispatchFailure;
|
|
222
223
|
private traceInstanceMessage;
|
|
223
|
-
dispatchMeshActor(meshName: string, owner: ReadyRecord, record: ReceiveRecord): Promise<void>;
|
|
224
|
+
dispatchMeshActor(origin: ApplicationJobOrigin, meshName: string, owner: ReadyRecord, record: ReceiveRecord): Promise<void>;
|
|
224
225
|
dispatchMeshActorJoin(meshName: string, owner: ReadyRecord, record: ReceiveRecord): Promise<void>;
|
|
225
226
|
private dispatchMeshActorJoinCore;
|
|
226
227
|
dispatchMeshSpotControl(meshName: string, owner: ReadyRecord, record: ReceiveRecord): Promise<void>;
|
|
@@ -860,20 +860,20 @@ class DefaultZLinkSpotManager {
|
|
|
860
860
|
async notifyJoinedSpotActorDisconnected(spotId, actor, signal) {
|
|
861
861
|
return await this.actorMembership.notifyJoinedActorDisconnected(spotId, actor, signal);
|
|
862
862
|
}
|
|
863
|
-
dispatchRoutedActorPacket(spotId, actorId, parts, returnResponse = false, remoteBoundSessionTarget, fallbackActorRef) {
|
|
863
|
+
dispatchRoutedActorPacket(origin, spotId, actorId, parts, returnResponse = false, remoteBoundSessionTarget, fallbackActorRef) {
|
|
864
864
|
const activation = this.activations.resolveUnique(spotId);
|
|
865
865
|
if (activation === undefined) {
|
|
866
866
|
throw new configuration_1.ZLinkConfigurationException(`Spot '${spotId}' is not active.`);
|
|
867
867
|
}
|
|
868
|
-
return this.dispatchActorPacket(activation, actorId, parts, returnResponse, remoteBoundSessionTarget, fallbackActorRef);
|
|
868
|
+
return this.dispatchActorPacket(origin, activation, actorId, parts, returnResponse, remoteBoundSessionTarget, fallbackActorRef);
|
|
869
869
|
}
|
|
870
870
|
/** @internal Replays a record already owned by the Actor handoff queue. */
|
|
871
|
-
dispatchRoutedActorPacketDirect(spotId, actorId, parts, returnResponse = false, remoteBoundSessionTarget, fallbackActorRef) {
|
|
871
|
+
dispatchRoutedActorPacketDirect(origin, spotId, actorId, parts, returnResponse = false, remoteBoundSessionTarget, fallbackActorRef) {
|
|
872
872
|
const activation = this.activations.resolveUnique(spotId);
|
|
873
873
|
if (activation === undefined) {
|
|
874
874
|
throw new configuration_1.ZLinkConfigurationException(`Spot '${spotId}' is not active.`);
|
|
875
875
|
}
|
|
876
|
-
return this.activationLifecycle.dispatchActorPacketDirect(activation, actorId, parts, returnResponse, remoteBoundSessionTarget, fallbackActorRef);
|
|
876
|
+
return this.activationLifecycle.dispatchActorPacketDirect(origin, activation, actorId, parts, returnResponse, remoteBoundSessionTarget, fallbackActorRef);
|
|
877
877
|
}
|
|
878
878
|
/** @internal Atomically restores one durable packet prefix to an Actor FIFO. */
|
|
879
879
|
admitRoutedActorPacketPrefix(spotId, actorId, records) {
|
|
@@ -1071,7 +1071,7 @@ class DefaultZLinkSpotManager {
|
|
|
1071
1071
|
errorReason
|
|
1072
1072
|
});
|
|
1073
1073
|
}
|
|
1074
|
-
async dispatchMeshActor(meshName, owner, record) {
|
|
1074
|
+
async dispatchMeshActor(origin, meshName, owner, record) {
|
|
1075
1075
|
const spotId = owner.spotId;
|
|
1076
1076
|
const entrySpotId = this.options.entryNodeRidProvider?.() ?? this.options.entryNodeRid;
|
|
1077
1077
|
const targetsEntrySpot = spotId === null || (entrySpotId !== undefined && spotId === entrySpotId);
|
|
@@ -1115,8 +1115,8 @@ class DefaultZLinkSpotManager {
|
|
|
1115
1115
|
throw new Error(`Actor '${actor.actorId}' target transfer reconciliation is not complete.`);
|
|
1116
1116
|
}
|
|
1117
1117
|
const response = targetsEntrySpot
|
|
1118
|
-
? await this.options.dispatchEntryActorPacket?.(actor.actorId, record.parts, request, undefined, ownerActorRef, requestTerminal, record.messageFollowOrigin)
|
|
1119
|
-
: await this.dispatchMeshActorPacket(meshName, spotId, actor.actorId, record.parts, request, ownerActorRef, requestTerminal, record.messageFollowOrigin);
|
|
1118
|
+
? await this.options.dispatchEntryActorPacket?.(origin, actor.actorId, record.parts, request, undefined, ownerActorRef, requestTerminal, record.messageFollowOrigin)
|
|
1119
|
+
: await this.dispatchMeshActorPacket(origin, meshName, spotId, actor.actorId, record.parts, request, ownerActorRef, requestTerminal, record.messageFollowOrigin);
|
|
1120
1120
|
if (targetsEntrySpot && this.options.dispatchEntryActorPacket === undefined) {
|
|
1121
1121
|
throw new configuration_1.ZLinkConfigurationException('MeshNode Entry Spot Actor dispatch is not configured.');
|
|
1122
1122
|
}
|
|
@@ -1631,7 +1631,7 @@ class DefaultZLinkSpotManager {
|
|
|
1631
1631
|
if (this.options.dispatchEntryActorPacket === undefined) {
|
|
1632
1632
|
throw new Error('Entry Spot saved handoff replay requires its Actor packet runtime.');
|
|
1633
1633
|
}
|
|
1634
|
-
return await this.options.dispatchEntryActorPacket(entryActor.context.actorId, parts, returnResponse, remoteBoundSessionTarget, fallbackActorRef);
|
|
1634
|
+
return await this.options.dispatchEntryActorPacket('remote', entryActor.context.actorId, parts, returnResponse, remoteBoundSessionTarget, fallbackActorRef);
|
|
1635
1635
|
}, (index) => this.options.runtimeEventPublisher?.publish({
|
|
1636
1636
|
sourceName: 'zlink.framework.actor-handoff',
|
|
1637
1637
|
timestamp: new Date(),
|
|
@@ -1790,7 +1790,7 @@ class DefaultZLinkSpotManager {
|
|
|
1790
1790
|
};
|
|
1791
1791
|
const completeTargetReady = async () => {
|
|
1792
1792
|
if (pendingTransfer !== undefined) {
|
|
1793
|
-
const handoffResults = await (0, actor_handoff_1.replayActorHandoffBacklog)(pendingTransfer.handoffBacklog, (parts, returnResponse, remoteBoundSessionTarget, _fallbackActorRef) => this.dispatchActorPacket(activation, actor.context.actorId, parts, returnResponse, remoteBoundSessionTarget, undefined), (index) => this.options.runtimeEventPublisher?.publish({
|
|
1793
|
+
const handoffResults = await (0, actor_handoff_1.replayActorHandoffBacklog)(pendingTransfer.handoffBacklog, (parts, returnResponse, remoteBoundSessionTarget, _fallbackActorRef) => this.dispatchActorPacket('remote', activation, actor.context.actorId, parts, returnResponse, remoteBoundSessionTarget, undefined), (index) => this.options.runtimeEventPublisher?.publish({
|
|
1794
1794
|
sourceName: 'zlink.framework.actor-handoff',
|
|
1795
1795
|
timestamp: new Date(),
|
|
1796
1796
|
marker: 'backlog_enqueued',
|
|
@@ -2033,8 +2033,8 @@ class DefaultZLinkSpotManager {
|
|
|
2033
2033
|
throw new configuration_1.ZLinkConfigurationException('Spot type is not registered as a spot factory.');
|
|
2034
2034
|
}
|
|
2035
2035
|
}
|
|
2036
|
-
async dispatchActorPacket(activation, actorId, parts, returnResponse = false, remoteBoundSessionTarget, fallbackActorRef, requestTerminal, messageFollowOrigin) {
|
|
2037
|
-
return await this.activationLifecycle.dispatchActorPacket(activation, actorId, parts, returnResponse, remoteBoundSessionTarget, fallbackActorRef, requestTerminal, messageFollowOrigin);
|
|
2036
|
+
async dispatchActorPacket(origin, activation, actorId, parts, returnResponse = false, remoteBoundSessionTarget, fallbackActorRef, requestTerminal, messageFollowOrigin) {
|
|
2037
|
+
return await this.activationLifecycle.dispatchActorPacket(origin, activation, actorId, parts, returnResponse, remoteBoundSessionTarget, fallbackActorRef, requestTerminal, messageFollowOrigin);
|
|
2038
2038
|
}
|
|
2039
2039
|
/**
|
|
2040
2040
|
* Spec 15 §4.2 relocation temporary queue: drains every arrival parked
|
|
@@ -2050,7 +2050,7 @@ class DefaultZLinkSpotManager {
|
|
|
2050
2050
|
const drained = this.formalRemoteActorAdmissions.completeMigration(transferId);
|
|
2051
2051
|
for (const arrival of drained) {
|
|
2052
2052
|
try {
|
|
2053
|
-
const response = await this.dispatchActorPacket(activation, actor.context.actorId, [runtime_message_1.ZLinkBufferMessage.from(arrival.header), runtime_message_1.ZLinkBufferMessage.from(arrival.payload)], arrival.returnResponse, arrival.remoteBoundSessionTarget, arrival.fallbackActorRef, arrival.requestTerminal);
|
|
2053
|
+
const response = await this.dispatchActorPacket(arrival.origin, activation, actor.context.actorId, [runtime_message_1.ZLinkBufferMessage.from(arrival.header), runtime_message_1.ZLinkBufferMessage.from(arrival.payload)], arrival.returnResponse, arrival.remoteBoundSessionTarget, arrival.fallbackActorRef, arrival.requestTerminal);
|
|
2054
2054
|
arrival.resolve(response);
|
|
2055
2055
|
}
|
|
2056
2056
|
catch (error) {
|
|
@@ -2058,12 +2058,12 @@ class DefaultZLinkSpotManager {
|
|
|
2058
2058
|
}
|
|
2059
2059
|
}
|
|
2060
2060
|
}
|
|
2061
|
-
async dispatchMeshActorPacket(meshName, spotId, actorId, parts, returnResponse, fallbackActorRef, requestTerminal, messageFollowOrigin) {
|
|
2061
|
+
async dispatchMeshActorPacket(origin, meshName, spotId, actorId, parts, returnResponse, fallbackActorRef, requestTerminal, messageFollowOrigin) {
|
|
2062
2062
|
const activation = this.activations.resolve(meshName, spotId);
|
|
2063
2063
|
if (activation === undefined) {
|
|
2064
2064
|
throw new configuration_1.ZLinkConfigurationException(`Spot '${String(spotId)}' is not active in mesh '${meshName}'.`);
|
|
2065
2065
|
}
|
|
2066
|
-
return await this.dispatchActorPacket(activation, actorId, parts, returnResponse, undefined, fallbackActorRef, requestTerminal, messageFollowOrigin);
|
|
2066
|
+
return await this.dispatchActorPacket(origin, activation, actorId, parts, returnResponse, undefined, fallbackActorRef, requestTerminal, messageFollowOrigin);
|
|
2067
2067
|
}
|
|
2068
2068
|
}
|
|
2069
2069
|
exports.DefaultZLinkSpotManager = DefaultZLinkSpotManager;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ApplicationJobOrigin } from '../application-jobs/contracts';
|
|
1
2
|
import type { ActorRef, RoutingId, Type, ZLinkActor, ZLinkChannelClient, ZLinkFanoutClient, ZLinkMessageSerializer, ZLinkInstanceSpot, ZLinkSpot, ZLinkSpotPublisherClient } from '../../contracts';
|
|
2
3
|
import type { ZLinkProviderResolver } from '../../contracts/Common/ZLinkProviderResolver';
|
|
3
4
|
import type { ZLinkRuntimeAdmissionGate } from '../admission';
|
|
@@ -82,7 +83,7 @@ export declare class ZLinkSpotActivationLifecycle {
|
|
|
82
83
|
/** Returns the OnClosing failure, which cleanup records and does not rethrow. */
|
|
83
84
|
cleanupClosedActivation(activation: ZLinkSpotActivation, reason?: ZLinkSpotCloseReason, deadline?: Date): Promise<unknown>;
|
|
84
85
|
cleanupFailedIncarnation(activation: ZLinkSpotActivation): Promise<void>;
|
|
85
|
-
dispatchActorPacket(activation: ZLinkSpotActivation, actorId: string, parts: readonly Message[], returnResponse?: boolean, remoteBoundSessionTarget?: ZLinkRemoteBoundSessionTarget, fallbackActorRef?: ActorRef, requestTerminal?: (response: unknown) => Promise<void> | void, messageFollowOrigin?: ZLinkMessageFollowOrigin): Promise<unknown>;
|
|
86
|
+
dispatchActorPacket(origin: ApplicationJobOrigin, activation: ZLinkSpotActivation, actorId: string, parts: readonly Message[], returnResponse?: boolean, remoteBoundSessionTarget?: ZLinkRemoteBoundSessionTarget, fallbackActorRef?: ActorRef, requestTerminal?: (response: unknown) => Promise<void> | void, messageFollowOrigin?: ZLinkMessageFollowOrigin): Promise<unknown>;
|
|
86
87
|
private runCreateLifecycle;
|
|
87
88
|
private cleanupActivation;
|
|
88
89
|
private runCleanup;
|