@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
|
@@ -30,7 +30,10 @@ class ZLinkHostSpotAddressTransport {
|
|
|
30
30
|
}
|
|
31
31
|
async sendToSpotAddressScoped(spotId, message, call) {
|
|
32
32
|
const activationDeadlineUnixMs = BigInt(Math.round(Date.now() + this.options.defaultRequestTimeoutMs));
|
|
33
|
-
const
|
|
33
|
+
const resolution = await this.resolveExisting(spotId, undefined, call);
|
|
34
|
+
const existing = resolution !== undefined && !('kind' in resolution) ? resolution : undefined;
|
|
35
|
+
if (resolution !== undefined && 'kind' in resolution)
|
|
36
|
+
call = this.reactivationCall(resolution, call);
|
|
34
37
|
if (existing !== undefined) {
|
|
35
38
|
this.validateExisting(existing, call);
|
|
36
39
|
try {
|
|
@@ -64,7 +67,7 @@ class ZLinkHostSpotAddressTransport {
|
|
|
64
67
|
if (!call.instanceSpot) {
|
|
65
68
|
return { status: submission_result_1.ZLinkSubmitStatus.TargetNotFound };
|
|
66
69
|
}
|
|
67
|
-
const selected = this.selectMissingTarget(spotId, call);
|
|
70
|
+
const selected = this.selectMissingTarget(spotId, call, resolution);
|
|
68
71
|
if (selected.kind === 'unsupported') {
|
|
69
72
|
this.traceInstanceAddress(ZLinkDispatchOptions_1.ZLinkRuntimeMessageFlowOutcome.Dropped, ZLinkDispatchOptions_1.ZLinkDispatchMessageKind.Send, spotId, message, call.initialMeshName, call.instanceSpotType, undefined, ZLinkDispatchOptions_1.ZLinkRuntimeDispatchErrorReason.StaleTarget);
|
|
70
73
|
return { status: submission_result_1.ZLinkSubmitStatus.TargetNotFound };
|
|
@@ -91,10 +94,13 @@ class ZLinkHostSpotAddressTransport {
|
|
|
91
94
|
const timeoutMs = call.timeoutMs ?? this.options.defaultRequestTimeoutMs;
|
|
92
95
|
const deadline = createSpotAddressDeadline(timeoutMs, call.signal);
|
|
93
96
|
try {
|
|
94
|
-
const
|
|
97
|
+
const resolution = await this.resolveExisting(spotId, deadline.signal, call);
|
|
98
|
+
const existing = resolution !== undefined && !('kind' in resolution) ? resolution : undefined;
|
|
99
|
+
if (resolution !== undefined && 'kind' in resolution)
|
|
100
|
+
call = this.reactivationCall(resolution, call);
|
|
95
101
|
deadline.requireRemaining();
|
|
96
102
|
if (existing === undefined) {
|
|
97
|
-
return await this.requestToMissingInstance(spotId, request, call, deadline);
|
|
103
|
+
return await this.requestToMissingInstance(spotId, request, call, deadline, resolution);
|
|
98
104
|
}
|
|
99
105
|
this.validateExisting(existing, call);
|
|
100
106
|
try {
|
|
@@ -143,11 +149,11 @@ class ZLinkHostSpotAddressTransport {
|
|
|
143
149
|
this.traceInstanceAddress(ZLinkDispatchOptions_1.ZLinkRuntimeMessageFlowOutcome.ReplyReceived, ZLinkDispatchOptions_1.ZLinkDispatchMessageKind.Request, spotId, request, existing.routerChannelId, existing.stableType, existing.targetNodeRid);
|
|
144
150
|
return reply;
|
|
145
151
|
}
|
|
146
|
-
async requestToMissingInstance(spotId, request, call, deadline) {
|
|
152
|
+
async requestToMissingInstance(spotId, request, call, deadline, current) {
|
|
147
153
|
if (!call.instanceSpot) {
|
|
148
154
|
throw (0, framework_errors_internal_1.createInternalFrameworkException)(framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.RequestTargetNotFound, `Spot '${String(spotId)}' has no Ready authority.`);
|
|
149
155
|
}
|
|
150
|
-
const selected = this.selectMissingTarget(spotId, call);
|
|
156
|
+
const selected = this.selectMissingTarget(spotId, call, current);
|
|
151
157
|
if (selected.kind === 'capacity') {
|
|
152
158
|
throw missingInstancePlacementCapacity(spotId, call.instanceSpotType);
|
|
153
159
|
}
|
|
@@ -214,13 +220,15 @@ class ZLinkHostSpotAddressTransport {
|
|
|
214
220
|
errorReason
|
|
215
221
|
});
|
|
216
222
|
}
|
|
217
|
-
async resolveExisting(spotId, signal) {
|
|
223
|
+
async resolveExisting(spotId, signal, call) {
|
|
218
224
|
const resolver = this.options.resolver();
|
|
219
225
|
if (resolver === undefined) {
|
|
220
226
|
throw new Error('Global Spot address resolution requires a Location Store.');
|
|
221
227
|
}
|
|
222
228
|
try {
|
|
223
|
-
return await (0, abort_1.awaitWithAbort)(
|
|
229
|
+
return await (0, abort_1.awaitWithAbort)(call?.instanceSpot === true
|
|
230
|
+
? resolver.resolve(spotId, signal, true)
|
|
231
|
+
: resolver.resolve(spotId, signal), signal);
|
|
224
232
|
}
|
|
225
233
|
catch (error) {
|
|
226
234
|
if (error instanceof contracts_1.ZLinkFrameworkException &&
|
|
@@ -230,7 +238,11 @@ class ZLinkHostSpotAddressTransport {
|
|
|
230
238
|
throw error;
|
|
231
239
|
}
|
|
232
240
|
}
|
|
233
|
-
|
|
241
|
+
reactivationCall(route, call) {
|
|
242
|
+
this.validateExisting(route, call);
|
|
243
|
+
return { ...call, initialMeshName: route.meshName, instanceSpotType: route.stableType };
|
|
244
|
+
}
|
|
245
|
+
selectMissingTarget(spotId, call, current) {
|
|
234
246
|
const configuredMeshes = this.options.meshNames();
|
|
235
247
|
if (call.initialMeshName !== undefined &&
|
|
236
248
|
this.options.isMeshConfigured?.(call.initialMeshName) === false) {
|
|
@@ -253,11 +265,11 @@ class ZLinkHostSpotAddressTransport {
|
|
|
253
265
|
const stableType = call.instanceSpotType ?? (distinctTypes.length === 1 ? distinctTypes[0] : undefined);
|
|
254
266
|
if (stableType === undefined) {
|
|
255
267
|
if (distinctTypes.length === 0)
|
|
256
|
-
return { kind: 'unsupported' };
|
|
268
|
+
return { kind: current === undefined ? 'unsupported' : 'unavailable' };
|
|
257
269
|
throw (0, framework_errors_internal_1.createInternalFrameworkException)(framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.InvalidOperation, 'Instance Spot type is required when multiple types are registered.');
|
|
258
270
|
}
|
|
259
271
|
if (canInspectPlacementTypes && !distinctTypes.includes(stableType)) {
|
|
260
|
-
return { kind: 'unsupported' };
|
|
272
|
+
return { kind: current === undefined ? 'unsupported' : 'unavailable' };
|
|
261
273
|
}
|
|
262
274
|
let unavailable = false;
|
|
263
275
|
let capacity = false;
|
|
@@ -276,6 +288,7 @@ class ZLinkHostSpotAddressTransport {
|
|
|
276
288
|
node,
|
|
277
289
|
target: {
|
|
278
290
|
...placement.target,
|
|
291
|
+
targetMeshName: meshName,
|
|
279
292
|
targetSpotId: String(spotId),
|
|
280
293
|
stableType
|
|
281
294
|
}
|
|
@@ -293,7 +306,7 @@ class ZLinkHostSpotAddressTransport {
|
|
|
293
306
|
if (capacity)
|
|
294
307
|
return { kind: 'capacity' };
|
|
295
308
|
if (unsupported)
|
|
296
|
-
return { kind: 'unsupported' };
|
|
309
|
+
return { kind: current === undefined ? 'unsupported' : 'unavailable' };
|
|
297
310
|
return { kind: 'unavailable' };
|
|
298
311
|
}
|
|
299
312
|
validateExisting(target, call) {
|
|
@@ -25,12 +25,12 @@ class ZLinkSpotRuntimeOptionsFactory {
|
|
|
25
25
|
?.notifyPrimaryEntrySpotActorLeft(actor, signal, actorRef, membershipEpoch) ??
|
|
26
26
|
Promise.resolve()
|
|
27
27
|
},
|
|
28
|
-
dispatchEntryActorPacket: (actorId, parts, returnResponse, remoteBoundSessionTarget, fallbackActorRef, requestTerminal, messageFollowOrigin) => {
|
|
28
|
+
dispatchEntryActorPacket: (origin, actorId, parts, returnResponse, remoteBoundSessionTarget, fallbackActorRef, requestTerminal, messageFollowOrigin) => {
|
|
29
29
|
const runtime = this.options.spotNodeRuntime();
|
|
30
30
|
if (runtime === undefined) {
|
|
31
31
|
throw new configuration_1.ZLinkConfigurationException('Entry Spot actor packet dispatch requires the MeshNode runtime.');
|
|
32
32
|
}
|
|
33
|
-
return runtime.dispatchEntryActorPacket(actorId, parts, returnResponse, remoteBoundSessionTarget, fallbackActorRef, requestTerminal, messageFollowOrigin);
|
|
33
|
+
return runtime.dispatchEntryActorPacket(origin, actorId, parts, returnResponse, remoteBoundSessionTarget, fallbackActorRef, requestTerminal, messageFollowOrigin);
|
|
34
34
|
},
|
|
35
35
|
dispatchEntryActorJoin: async (meshName, actor, handoffBacklog) => {
|
|
36
36
|
const runtime = this.options.spotNodeRuntime();
|
|
@@ -5,6 +5,7 @@ import type { ZLinkAuthoritySnapshot, ZLinkLocationOwnerToken } from '../locatio
|
|
|
5
5
|
import type { ZLinkAuthorityStore, ZLinkObjectCreationStore } from '../locations/internal-store-contracts';
|
|
6
6
|
import type { ZLinkLocalSpotCreateResult } from '../spots/spot-manager-internal-contracts';
|
|
7
7
|
export interface ZLinkUserSpotCreationCoordinatorOptions {
|
|
8
|
+
readonly relocationPolicy?: (meshName: string, stableType: string) => import('../locations/internal-location-contracts').ZLinkObjectReserveRequest['actorRelocationPolicy'];
|
|
8
9
|
readonly store: ZLinkObjectCreationStore & ZLinkAuthorityStore;
|
|
9
10
|
readonly target: (request: Pick<ZLinkUserSpotCreationRequest, 'meshName' | 'stableType'>, signal?: AbortSignal, excludedNodeRids?: ReadonlySet<string>) => Promise<{
|
|
10
11
|
readonly meshName: string;
|
|
@@ -62,6 +62,7 @@ class ZLinkUserSpotCreationCoordinator {
|
|
|
62
62
|
try {
|
|
63
63
|
reserved = await this.options.store.reserve({
|
|
64
64
|
key: { kind: 'user_spot', globalId: String(request.spotId) },
|
|
65
|
+
actorRelocationPolicy: this.options.relocationPolicy?.(target.meshName, request.stableType),
|
|
65
66
|
intent: {
|
|
66
67
|
stableType: request.stableType,
|
|
67
68
|
requestContentReference: contentReference,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ZLinkLocationOwnerToken, ZLinkLocationPage, ZLinkLocationWriteIntent, ZLinkLocationWriteResult, ZLinkLocationWriteStatus, ZLinkMeshNodeDescriptor, ZLinkMeshNodeDescriptorKey, ZLinkClientServerServerDescriptor, ZLinkClientServerServerDescriptorKey, ZLinkFanoutPublisherDescriptor, ZLinkFanoutPublisherDescriptorKey, ZLinkOwnerLeaseClaimResult, ZLinkOwnerLeaseReadResult, ZLinkOwnerLeaseReleaseResult, ZLinkOwnerLeaseRenewResult, ZLinkPageRequest } from '../../contracts/Locations/Models';
|
|
2
|
-
import type { ZLinkAggregateAbortResult, ZLinkAggregateCommitResult, ZLinkAggregateFence, ZLinkAggregatePrepareRequest, ZLinkAggregatePrepareResult, ZLinkAuthorityCompareExchangeResult, ZLinkAuthorityKey, ZLinkAuthorityMutation, ZLinkAuthorityReadResult, ZLinkAuthorityScanCursor, ZLinkAuthorityScanResult, ZLinkAuthorityStoreVersion, ZLinkCreationOperationIdentity, ZLinkCreationTerminalReadResult, ZLinkObjectAbortRequest, ZLinkObjectAbortResult, ZLinkObjectCommitRequest, ZLinkObjectCommitResult, ZLinkObjectCreationCompleteRequest, ZLinkObjectCreationCompleteResult,
|
|
2
|
+
import type { ZLinkAggregateAbortResult, ZLinkAggregateCommitResult, ZLinkAggregateFence, ZLinkAggregatePrepareRequest, ZLinkAggregatePrepareResult, ZLinkAuthorityCompareExchangeResult, ZLinkAuthorityKey, ZLinkAuthorityMutation, ZLinkAuthorityReadResult, ZLinkAuthorityScanCursor, ZLinkAuthorityScanResult, ZLinkAuthorityStoreVersion, ZLinkCreationOperationIdentity, ZLinkCreationTerminalReadResult, ZLinkObjectAbortRequest, ZLinkObjectAbortResult, ZLinkObjectCommitRequest, ZLinkObjectCommitResult, ZLinkObjectCreationCompleteRequest, ZLinkObjectCreationCompleteResult, ZLinkObjectReserveResult } from '../../contracts/Locations/Authority';
|
|
3
|
+
import type { ZLinkObjectReserveRequest, ZLinkEndedOwnerReleaseIntent } from './internal-location-contracts';
|
|
3
4
|
/**
|
|
4
5
|
* Framework-private domain repository. Provider implementations never
|
|
5
6
|
* implement this interface; the framework maps it to the opaque Store SPI.
|
|
@@ -25,7 +26,7 @@ export interface ZLinkDomainLocationStore {
|
|
|
25
26
|
reserve(request: ZLinkObjectReserveRequest, signal?: AbortSignal, deadlineUnixMs?: bigint): Promise<ZLinkObjectReserveResult>;
|
|
26
27
|
commit(request: ZLinkObjectCommitRequest, signal?: AbortSignal, deadlineUnixMs?: bigint): Promise<ZLinkObjectCommitResult>;
|
|
27
28
|
completeCreation(request: ZLinkObjectCreationCompleteRequest, signal?: AbortSignal): Promise<ZLinkObjectCreationCompleteResult>;
|
|
28
|
-
releaseEndedReservation?(key: ZLinkAuthorityKey, expectedStoreVersion: string, signal?: AbortSignal): Promise<boolean>;
|
|
29
|
+
releaseEndedReservation?(key: ZLinkAuthorityKey, expectedStoreVersion: string, signal?: AbortSignal, request?: ZLinkEndedOwnerReleaseIntent): Promise<boolean>;
|
|
29
30
|
abort(request: ZLinkObjectAbortRequest, signal?: AbortSignal, deadlineUnixMs?: bigint): Promise<ZLinkObjectAbortResult>;
|
|
30
31
|
prepareAggregate(request: ZLinkAggregatePrepareRequest, signal?: AbortSignal): Promise<ZLinkAggregatePrepareResult>;
|
|
31
32
|
commitAggregate(fence: ZLinkAggregateFence, signal?: AbortSignal): Promise<ZLinkAggregateCommitResult>;
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import type { ZLinkAggregateAbortResult, ZLinkAggregateCommitResult, ZLinkAggregateFence, ZLinkAggregatePrepareRequest, ZLinkAggregatePrepareResult, ZLinkAuthorityCompareExchangeResult, ZLinkAuthorityKey, ZLinkAuthorityMutation, ZLinkAuthorityReadResult, ZLinkAuthorityScanCursor, ZLinkAuthorityScanResult, ZLinkAuthorityStoreVersion, ZLinkCapacityVector, ZLinkLocationOwnerToken, ZLinkMeshNodeDescriptorKey, ZLinkObjectAbortRequest, ZLinkObjectAbortResult, ZLinkObjectCommitRequest, ZLinkObjectCommitResult, ZLinkObjectCreationCompleteRequest, ZLinkObjectCreationCompleteResult, ZLinkObjectReserveRequest, ZLinkObjectReserveResult, ZLinkCreationOperationIdentity, ZLinkCreationTerminalReadResult } from './internal-location-contracts';
|
|
1
|
+
import type { ZLinkAggregateAbortResult, ZLinkAggregateCommitResult, ZLinkAggregateFence, ZLinkAggregatePrepareRequest, ZLinkAggregatePrepareResult, ZLinkAuthorityCompareExchangeResult, ZLinkAuthorityKey, ZLinkAuthorityMutation, ZLinkAuthorityReadResult, ZLinkAuthorityScanCursor, ZLinkAuthorityScanResult, ZLinkAuthorityStoreVersion, ZLinkCapacityVector, ZLinkLocationOwnerToken, ZLinkMeshNodeDescriptorKey, ZLinkObjectAbortRequest, ZLinkObjectAbortResult, ZLinkObjectCommitRequest, ZLinkObjectCommitResult, ZLinkObjectCreationCompleteRequest, ZLinkObjectCreationCompleteResult, ZLinkEndedOwnerReleaseIntent, ZLinkObjectReserveRequest, ZLinkObjectReserveResult, ZLinkCreationOperationIdentity, ZLinkCreationTerminalReadResult } from './internal-location-contracts';
|
|
2
2
|
export interface ZLinkInMemoryAuthorityValidation {
|
|
3
|
+
isOwnerLive(owner: ZLinkLocationOwnerToken): boolean;
|
|
3
4
|
isTargetLive(descriptor: ZLinkMeshNodeDescriptorKey, lifecycleGeneration: bigint, owner: ZLinkLocationOwnerToken): boolean;
|
|
4
5
|
placementCapacityAvailable?(descriptor: ZLinkMeshNodeDescriptorKey, requested: ZLinkCapacityVector, currentReserved: ZLinkCapacityVector, currentActive: ZLinkCapacityVector): boolean;
|
|
5
6
|
identityClaimed?(authorityKey: string): boolean;
|
|
7
|
+
hasSpotMembers?(spotId: string, objectGeneration: bigint): boolean;
|
|
6
8
|
}
|
|
7
9
|
/**
|
|
8
10
|
* In-memory reference provider for the provider-owned authority state machine.
|
|
@@ -26,7 +28,8 @@ export declare class ZLinkInMemoryAuthorityStore {
|
|
|
26
28
|
compareExchangeAuthority(key: ZLinkAuthorityKey, expectedStoreVersion: ZLinkAuthorityStoreVersion, mutation: ZLinkAuthorityMutation, signal?: AbortSignal): Promise<ZLinkAuthorityCompareExchangeResult>;
|
|
27
29
|
listAuthorities(prefix: string, cursor: ZLinkAuthorityScanCursor | undefined, limit: number, signal?: AbortSignal): Promise<ZLinkAuthorityScanResult>;
|
|
28
30
|
removeAllByOwner(owner: ZLinkLocationOwnerToken, signal?: AbortSignal): Promise<bigint>;
|
|
29
|
-
releaseEndedReservation(key: ZLinkAuthorityKey, expectedStoreVersion: string, signal?: AbortSignal): Promise<boolean>;
|
|
31
|
+
releaseEndedReservation(key: ZLinkAuthorityKey, expectedStoreVersion: string, signal?: AbortSignal, request?: ZLinkEndedOwnerReleaseIntent): Promise<boolean>;
|
|
32
|
+
acceptsUserSpotMembership(spotId: string, objectGeneration: bigint): boolean;
|
|
30
33
|
private tryReleaseEndedReservation;
|
|
31
34
|
reserve(request: ZLinkObjectReserveRequest, signal?: AbortSignal): Promise<ZLinkObjectReserveResult>;
|
|
32
35
|
commit(request: ZLinkObjectCommitRequest, signal?: AbortSignal): Promise<ZLinkObjectCommitResult>;
|
|
@@ -6,12 +6,18 @@ const stream_wire_1 = require("@zlink-systems/stream-wire");
|
|
|
6
6
|
const CoreTypes_1 = require("../../contracts/Common/CoreTypes");
|
|
7
7
|
const Stores_1 = require("../../contracts/Locations/Stores");
|
|
8
8
|
const node_crypto_1 = require("node:crypto");
|
|
9
|
+
const contracts_1 = require("../../contracts");
|
|
9
10
|
const actor_join_recovery_codec_1 = require("../foundation/actor-join-recovery-codec");
|
|
10
11
|
const authority_key_codec_1 = require("./authority-key-codec");
|
|
11
12
|
const opaque_record_key_1 = require("./opaque-record-key");
|
|
13
|
+
const service_relocation_runtime_1 = require("../foundation/service-relocation-runtime");
|
|
14
|
+
const service_authority_payload_codec_1 = require("../foundation/service-authority-payload-codec");
|
|
15
|
+
const actor_authority_payload_codec_1 = require("../actors/actor-authority-payload-codec");
|
|
16
|
+
const contracts_2 = require("../../contracts");
|
|
12
17
|
const MAX_GENERATION = 0x7fffffffffffffffn;
|
|
13
18
|
const CREATION_TERMINAL_RETENTION_MS = 5 * 60 * 1000;
|
|
14
19
|
const MAX_U64 = stream_wire_1.UINT64_MAX;
|
|
20
|
+
const relocationAuthorityCodec = new service_relocation_runtime_1.ServiceRelocationAuthorityPayloadCodec();
|
|
15
21
|
/**
|
|
16
22
|
* In-memory reference provider for the provider-owned authority state machine.
|
|
17
23
|
* Opaque payload bytes are copied but never parsed.
|
|
@@ -105,6 +111,18 @@ class ZLinkInMemoryAuthorityStore {
|
|
|
105
111
|
if (!this.isOwnerLive(row.snapshot)) {
|
|
106
112
|
return { kind: 'conflict', current: this.read(keyValue) };
|
|
107
113
|
}
|
|
114
|
+
const actor = row.snapshot.allocation.objectKind === 'actor'
|
|
115
|
+
? (0, actor_authority_payload_codec_1.decodeActorAuthorityPayload)((0, service_relocation_runtime_1.serviceRelocationAuthorityApplicationPayload)(mutation.payload))
|
|
116
|
+
: undefined;
|
|
117
|
+
const previousActor = actor === undefined
|
|
118
|
+
? undefined
|
|
119
|
+
: (0, actor_authority_payload_codec_1.decodeActorAuthorityPayload)((0, service_relocation_runtime_1.serviceRelocationAuthorityApplicationPayload)(row.snapshot.payload));
|
|
120
|
+
if (actor?.currentSpotKind === contracts_2.ZLinkSpotKind.User &&
|
|
121
|
+
(previousActor?.currentSpotKind !== contracts_2.ZLinkSpotKind.User ||
|
|
122
|
+
previousActor.currentSpotId !== actor.currentSpotId ||
|
|
123
|
+
previousActor.currentSpotGeneration !== actor.currentSpotGeneration) &&
|
|
124
|
+
!this.acceptsUserSpotMembership(actor.currentSpotId, actor.currentSpotGeneration))
|
|
125
|
+
return { kind: 'conflict', current: this.read(keyValue) };
|
|
108
126
|
if (mutation.generationTransition === 'reincarnate' &&
|
|
109
127
|
(this.objectGeneration >= MAX_GENERATION || this.ownerGeneration >= MAX_GENERATION)) {
|
|
110
128
|
return { kind: 'generationExhausted' };
|
|
@@ -171,24 +189,77 @@ class ZLinkInMemoryAuthorityStore {
|
|
|
171
189
|
this.scanRevision++;
|
|
172
190
|
return BigInt(removed);
|
|
173
191
|
}
|
|
174
|
-
async releaseEndedReservation(key, expectedStoreVersion, signal) {
|
|
192
|
+
async releaseEndedReservation(key, expectedStoreVersion, signal, request) {
|
|
175
193
|
signal?.throwIfAborted();
|
|
176
|
-
return this.tryReleaseEndedReservation(key, expectedStoreVersion);
|
|
177
|
-
}
|
|
178
|
-
|
|
194
|
+
return this.tryReleaseEndedReservation(key, expectedStoreVersion, request);
|
|
195
|
+
}
|
|
196
|
+
acceptsUserSpotMembership(spotId, objectGeneration) {
|
|
197
|
+
const row = this.rows.get((0, authority_key_codec_1.encodeAuthorityKey)('user_spot', spotId).value);
|
|
198
|
+
return (row !== undefined &&
|
|
199
|
+
row.snapshot.allocation.objectKind === 'user_spot' &&
|
|
200
|
+
row.snapshot.allocation.state === 'active' &&
|
|
201
|
+
row.snapshot.objectGeneration === objectGeneration &&
|
|
202
|
+
(0, service_authority_payload_codec_1.decodeServiceReadySpotAuthority)(row.snapshot.payload)?.kind === 'user_spot' &&
|
|
203
|
+
this.isOwnerLive(row.snapshot));
|
|
204
|
+
}
|
|
205
|
+
tryReleaseEndedReservation(key, expectedStoreVersion, request) {
|
|
179
206
|
const current = this.rows.get(key.value);
|
|
180
207
|
if (current === undefined ||
|
|
181
208
|
current.snapshot.storeVersion.value !== expectedStoreVersion ||
|
|
182
|
-
current.snapshot.allocation.state
|
|
183
|
-
|
|
184
|
-
|
|
209
|
+
(current.snapshot.allocation.state === 'active'
|
|
210
|
+
? request === undefined
|
|
211
|
+
: current.creation === undefined))
|
|
212
|
+
return false;
|
|
213
|
+
if (current.snapshot.allocation.state === 'active') {
|
|
214
|
+
let unavailable = false;
|
|
215
|
+
for (const aggregate of this.aggregates.values()) {
|
|
216
|
+
if (aggregate.state === 'prepared' &&
|
|
217
|
+
aggregate.request.participants.some((participant) => participant.authorityKey.value === key.value))
|
|
218
|
+
unavailable = true;
|
|
219
|
+
}
|
|
220
|
+
unavailable ||= relocationAuthorityCodec.read(current.snapshot.payload) !== undefined;
|
|
221
|
+
if (this.validation.isOwnerLive({
|
|
185
222
|
ownerId: current.snapshot.ownerId,
|
|
186
223
|
leaseGeneration: current.snapshot.ownerLeaseGeneration
|
|
187
224
|
}))
|
|
225
|
+
return false;
|
|
226
|
+
const spot = current.snapshot.allocation.objectKind === 'actor'
|
|
227
|
+
? undefined
|
|
228
|
+
: (0, service_authority_payload_codec_1.decodeServiceReadySpotAuthority)(current.snapshot.payload);
|
|
229
|
+
if (current.snapshot.allocation.objectKind !== 'actor') {
|
|
230
|
+
unavailable ||=
|
|
231
|
+
spot === undefined ||
|
|
232
|
+
spot.kind !== request?.key.kind ||
|
|
233
|
+
spot.stableType !== request.intent.stableType ||
|
|
234
|
+
spot.spotId !== request.key.globalId ||
|
|
235
|
+
spot.activationRecovery !== undefined;
|
|
236
|
+
if (spot?.kind === 'user_spot') {
|
|
237
|
+
unavailable ||=
|
|
238
|
+
this.validation.hasSpotMembers?.(spot.spotId, current.snapshot.objectGeneration) ===
|
|
239
|
+
true;
|
|
240
|
+
for (const row of this.rows.values()) {
|
|
241
|
+
if (row.snapshot.allocation.objectKind !== 'actor')
|
|
242
|
+
continue;
|
|
243
|
+
const actor = (0, actor_authority_payload_codec_1.decodeActorAuthorityPayload)((0, service_relocation_runtime_1.serviceRelocationAuthorityApplicationPayload)(row.snapshot.payload));
|
|
244
|
+
unavailable ||=
|
|
245
|
+
actor?.currentSpotKind === contracts_2.ZLinkSpotKind.User &&
|
|
246
|
+
actor.currentSpotId === spot.spotId &&
|
|
247
|
+
actor.currentSpotGeneration === current.snapshot.objectGeneration;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
if (unavailable || request?.actorRelocationPolicy !== 'disabled')
|
|
252
|
+
throw new contracts_1.ZLinkFrameworkException(contracts_1.ZLinkFrameworkErrorKind.Unavailable, 'Object owner lease is unavailable.');
|
|
253
|
+
}
|
|
254
|
+
else if (this.validation.isTargetLive(current.snapshot.allocation.descriptor, current.snapshot.allocation.descriptorLifecycleGeneration, {
|
|
255
|
+
ownerId: current.snapshot.ownerId,
|
|
256
|
+
leaseGeneration: current.snapshot.ownerLeaseGeneration
|
|
257
|
+
}))
|
|
188
258
|
return false;
|
|
189
|
-
this.adjustCapacity(this.pendingCapacity, current.snapshot.allocation, -1);
|
|
259
|
+
this.adjustCapacity(current.snapshot.allocation.state === 'active' ? this.activeCapacity : this.pendingCapacity, current.snapshot.allocation, -1);
|
|
190
260
|
this.rows.delete(key.value);
|
|
191
|
-
|
|
261
|
+
if (current.snapshot.allocation.state === 'reserved' && current.creation !== undefined)
|
|
262
|
+
this.creationTerminals.set(current.creation.reservationId, 'aborted');
|
|
192
263
|
this.scanRevision++;
|
|
193
264
|
return true;
|
|
194
265
|
}
|
|
@@ -205,11 +276,10 @@ class ZLinkInMemoryAuthorityStore {
|
|
|
205
276
|
current.snapshot.allocation.stableType !== request.intent.stableType) {
|
|
206
277
|
return { kind: 'typeMismatch', current: this.snapshot(current.snapshot) };
|
|
207
278
|
}
|
|
208
|
-
if (current.snapshot.
|
|
209
|
-
return
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
return { kind: 'conflict', current: this.read(key) };
|
|
279
|
+
if (!this.tryReleaseEndedReservation((0, authority_key_codec_1.encodeAuthorityKey)(request.key.kind, request.key.globalId), current.snapshot.storeVersion.value, request))
|
|
280
|
+
return current.snapshot.allocation.state === 'active'
|
|
281
|
+
? { kind: 'alreadyExists', current: this.snapshot(current.snapshot) }
|
|
282
|
+
: { kind: 'conflict', current: this.read(key) };
|
|
213
283
|
}
|
|
214
284
|
const target = creationTarget(request);
|
|
215
285
|
if (!this.validation.isTargetLive(target.descriptor, target.lifecycleGeneration, target.owner)) {
|
|
@@ -336,6 +406,12 @@ class ZLinkInMemoryAuthorityStore {
|
|
|
336
406
|
if (!this.creationTerminalAvailable(terminalRecord)) {
|
|
337
407
|
return { kind: 'stale' };
|
|
338
408
|
}
|
|
409
|
+
const actor = request.completion.kind === 'created'
|
|
410
|
+
? (0, actor_authority_payload_codec_1.decodeActorAuthorityPayload)((0, service_relocation_runtime_1.serviceRelocationAuthorityApplicationPayload)(request.completion.readyPayload))
|
|
411
|
+
: undefined;
|
|
412
|
+
if (actor?.currentSpotKind === contracts_2.ZLinkSpotKind.User &&
|
|
413
|
+
!this.acceptsUserSpotMembership(actor.currentSpotId, actor.currentSpotGeneration))
|
|
414
|
+
return { kind: 'stale' };
|
|
339
415
|
const nextVersion = this.tryNextStoreVersion();
|
|
340
416
|
if (nextVersion === undefined)
|
|
341
417
|
return { kind: 'generationExhausted' };
|
|
@@ -479,6 +555,23 @@ class ZLinkInMemoryAuthorityStore {
|
|
|
479
555
|
row.snapshot.storeVersion.value !== participant.expectedStoreVersion.value) {
|
|
480
556
|
return { kind: 'stale' };
|
|
481
557
|
}
|
|
558
|
+
const actor = row.snapshot.allocation.objectKind === 'actor'
|
|
559
|
+
? (0, actor_authority_payload_codec_1.decodeActorAuthorityPayload)((0, service_relocation_runtime_1.serviceRelocationAuthorityApplicationPayload)(participant.authorityPayload))
|
|
560
|
+
: undefined;
|
|
561
|
+
if (actor?.currentSpotKind === contracts_2.ZLinkSpotKind.User) {
|
|
562
|
+
const participantSpot = aggregate.request.participants.find((candidate) => candidate.authorityKey.value ===
|
|
563
|
+
(0, authority_key_codec_1.encodeAuthorityKey)('user_spot', actor.currentSpotId).value);
|
|
564
|
+
if (participantSpot === undefined) {
|
|
565
|
+
if (!this.acceptsUserSpotMembership(actor.currentSpotId, actor.currentSpotGeneration))
|
|
566
|
+
return { kind: 'stale' };
|
|
567
|
+
}
|
|
568
|
+
else {
|
|
569
|
+
const spot = this.rows.get(participantSpot.authorityKey.value);
|
|
570
|
+
if (spot?.snapshot.allocation.objectKind !== 'user_spot' ||
|
|
571
|
+
spot.snapshot.objectGeneration !== actor.currentSpotGeneration)
|
|
572
|
+
return { kind: 'stale' };
|
|
573
|
+
}
|
|
574
|
+
}
|
|
482
575
|
if (participant.ownerTransition === 'newOwner') {
|
|
483
576
|
if (!this.validation.isTargetLive(aggregate.request.targetDescriptor, aggregate.request.targetDescriptorLifecycleGeneration, aggregate.request.targetOwner)) {
|
|
484
577
|
return { kind: 'stale' };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ZLinkActorTransferPrepareRequest, ZLinkActorTransferRecord, ZLinkActorTransferWriteResult } from '../../contracts/Locations/ActorTransfer';
|
|
2
2
|
import type { ZLinkDomainLocationStore } from './domain-store-contract';
|
|
3
|
-
import { ZLinkLocationWriteIntent, ZLinkLocationWriteStatus, type ZLinkActorLocation, type ZLinkActorLocationFilter, type ZLinkActorLocationKey, type ZLinkAggregateAbortResult, type ZLinkAggregateCommitResult, type ZLinkAggregateFence, type ZLinkAggregatePrepareRequest, type ZLinkAggregatePrepareResult, type ZLinkAuthorityCompareExchangeResult, type ZLinkAuthorityKey, type ZLinkAuthorityMutation, type ZLinkAuthorityReadResult, type ZLinkAuthorityScanCursor, type ZLinkAuthorityScanResult, type ZLinkAuthorityStoreVersion, type ZLinkClientServerServerDescriptor, type ZLinkClientServerServerDescriptorKey, type ZLinkCreationOperationIdentity, type ZLinkCreationTerminalReadResult, type ZLinkFanoutPublisherDescriptor, type ZLinkFanoutPublisherDescriptorKey, type ZLinkLocationChangeStampScope, type ZLinkLocationOwnerToken, type ZLinkLocationPage, type ZLinkLocationWriteResult, type ZLinkMeshNodeDescriptor, type ZLinkMeshNodeDescriptorKey, type ZLinkObjectAbortRequest, type ZLinkObjectAbortResult, type ZLinkObjectCommitRequest, type ZLinkObjectCommitResult, type ZLinkObjectCreationCompleteRequest, type ZLinkObjectCreationCompleteResult, type ZLinkObjectReserveRequest, type ZLinkObjectReserveResult, type ZLinkOwnerLeaseClaimResult, type ZLinkOwnerLeaseReadResult, type ZLinkOwnerLeaseReleaseResult, type ZLinkOwnerLeaseRenewResult, type ZLinkPageRequest, type ZLinkPeerLocation, type ZLinkPeerLocationFilter, type ZLinkPeerLocationKey, type ZLinkRouteLocation, type ZLinkRouteLocationFilter, type ZLinkRouteLocationKey, type ZLinkSpotLocation, type ZLinkSpotLocationFilter, type ZLinkSpotLocationKey } from './internal-location-contracts';
|
|
3
|
+
import { ZLinkLocationWriteIntent, ZLinkLocationWriteStatus, type ZLinkActorLocation, type ZLinkActorLocationFilter, type ZLinkActorLocationKey, type ZLinkAggregateAbortResult, type ZLinkAggregateCommitResult, type ZLinkAggregateFence, type ZLinkAggregatePrepareRequest, type ZLinkAggregatePrepareResult, type ZLinkAuthorityCompareExchangeResult, type ZLinkAuthorityKey, type ZLinkAuthorityMutation, type ZLinkAuthorityReadResult, type ZLinkAuthorityScanCursor, type ZLinkAuthorityScanResult, type ZLinkAuthorityStoreVersion, type ZLinkClientServerServerDescriptor, type ZLinkClientServerServerDescriptorKey, type ZLinkCreationOperationIdentity, type ZLinkCreationTerminalReadResult, type ZLinkFanoutPublisherDescriptor, type ZLinkFanoutPublisherDescriptorKey, type ZLinkLocationChangeStampScope, type ZLinkLocationOwnerToken, type ZLinkLocationPage, type ZLinkLocationWriteResult, type ZLinkMeshNodeDescriptor, type ZLinkMeshNodeDescriptorKey, type ZLinkObjectAbortRequest, type ZLinkObjectAbortResult, type ZLinkObjectCommitRequest, type ZLinkObjectCommitResult, type ZLinkObjectCreationCompleteRequest, type ZLinkObjectCreationCompleteResult, type ZLinkEndedOwnerReleaseIntent, type ZLinkObjectReserveRequest, type ZLinkObjectReserveResult, type ZLinkOwnerLeaseClaimResult, type ZLinkOwnerLeaseReadResult, type ZLinkOwnerLeaseReleaseResult, type ZLinkOwnerLeaseRenewResult, type ZLinkPageRequest, type ZLinkPeerLocation, type ZLinkPeerLocationFilter, type ZLinkPeerLocationKey, type ZLinkRouteLocation, type ZLinkRouteLocationFilter, type ZLinkRouteLocationKey, type ZLinkSpotLocation, type ZLinkSpotLocationFilter, type ZLinkSpotLocationKey } from './internal-location-contracts';
|
|
4
4
|
import type { ZLinkFanoutLocationStore } from './internal-store-contracts';
|
|
5
5
|
export declare class ZLinkInMemoryLocationStore implements ZLinkDomainLocationStore, ZLinkFanoutLocationStore {
|
|
6
6
|
private readonly now;
|
|
@@ -25,7 +25,7 @@ export declare class ZLinkInMemoryLocationStore implements ZLinkDomainLocationSt
|
|
|
25
25
|
commit(request: ZLinkObjectCommitRequest, signal?: AbortSignal): Promise<ZLinkObjectCommitResult>;
|
|
26
26
|
completeCreation(request: ZLinkObjectCreationCompleteRequest, signal?: AbortSignal): Promise<ZLinkObjectCreationCompleteResult>;
|
|
27
27
|
readCreationTerminal(operation: ZLinkCreationOperationIdentity, signal?: AbortSignal): Promise<ZLinkCreationTerminalReadResult>;
|
|
28
|
-
releaseEndedReservation(key: ZLinkAuthorityKey, expectedStoreVersion: string, signal?: AbortSignal): Promise<boolean>;
|
|
28
|
+
releaseEndedReservation(key: ZLinkAuthorityKey, expectedStoreVersion: string, signal?: AbortSignal, request?: ZLinkEndedOwnerReleaseIntent): Promise<boolean>;
|
|
29
29
|
abort(request: ZLinkObjectAbortRequest, signal?: AbortSignal): Promise<ZLinkObjectAbortResult>;
|
|
30
30
|
prepareAggregate(request: ZLinkAggregatePrepareRequest, signal?: AbortSignal): Promise<ZLinkAggregatePrepareResult>;
|
|
31
31
|
commitAggregate(fence: ZLinkAggregateFence, signal?: AbortSignal): Promise<ZLinkAggregateCommitResult>;
|
|
@@ -72,7 +72,7 @@ export declare class ZLinkInMemoryLocationStore implements ZLinkDomainLocationSt
|
|
|
72
72
|
private transitionActorTransfer;
|
|
73
73
|
private remove;
|
|
74
74
|
private removeByOwner;
|
|
75
|
-
private
|
|
75
|
+
private liveOwnerLease;
|
|
76
76
|
private bump;
|
|
77
77
|
private removeFanoutByOwner;
|
|
78
78
|
private bumpScope;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ZLinkInMemoryLocationStore = void 0;
|
|
4
|
+
const contracts_1 = require("../../contracts");
|
|
4
5
|
const CoreTypes_1 = require("../../contracts/Common/CoreTypes");
|
|
5
6
|
const RegistrationBuilderPolicy_1 = require("../../contracts/Configuration/RegistrationBuilderPolicy");
|
|
6
7
|
const location_store_integration_1 = require("../../location-store-integration");
|
|
@@ -27,19 +28,19 @@ class ZLinkInMemoryLocationStore {
|
|
|
27
28
|
authority;
|
|
28
29
|
constructor(now = () => new Date()) {
|
|
29
30
|
this.now = now;
|
|
31
|
+
const isOwnerLive = (owner) => this.liveOwnerLease(owner.ownerId, this.now())?.token.leaseGeneration ===
|
|
32
|
+
owner.leaseGeneration;
|
|
30
33
|
this.authority = new in_memory_authority_store_1.ZLinkInMemoryAuthorityStore({
|
|
34
|
+
isOwnerLive,
|
|
31
35
|
isTargetLive: (key, lifecycleGeneration, owner) => {
|
|
32
36
|
const descriptor = this.meshNodes.rows.get(meshNodeKey(key.meshName, key.rid));
|
|
33
|
-
const lease = this.leases.get(owner.ownerId);
|
|
34
37
|
return (descriptor !== undefined &&
|
|
35
38
|
descriptor.lifecycleGeneration === lifecycleGeneration &&
|
|
36
39
|
descriptor.ownerId === owner.ownerId &&
|
|
37
40
|
descriptor.leaseGeneration === owner.leaseGeneration &&
|
|
38
41
|
descriptor.objectRole === internal_location_contracts_1.ZLinkObjectRole.Server &&
|
|
39
42
|
descriptor.state === internal_location_contracts_1.ZLinkFrameworkRuntimeState.Serving &&
|
|
40
|
-
|
|
41
|
-
lease.token.leaseGeneration === owner.leaseGeneration &&
|
|
42
|
-
lease.leaseExpiresAt.getTime() > this.now().getTime());
|
|
43
|
+
isOwnerLive(owner));
|
|
43
44
|
},
|
|
44
45
|
placementCapacityAvailable: (key, requested, reserved, active) => {
|
|
45
46
|
const descriptor = this.meshNodes.rows.get(meshNodeKey(key.meshName, key.rid));
|
|
@@ -62,7 +63,16 @@ class ZLinkInMemoryLocationStore {
|
|
|
62
63
|
spotType.count <=
|
|
63
64
|
typeCapacity.limit))));
|
|
64
65
|
},
|
|
65
|
-
identityClaimed: (authorityKey) => this.entrySpotClaims.has(authorityKey)
|
|
66
|
+
identityClaimed: (authorityKey) => this.entrySpotClaims.has(authorityKey),
|
|
67
|
+
hasSpotMembers: (spotId, objectGeneration) => {
|
|
68
|
+
for (const actor of this.actors.rows.values()) {
|
|
69
|
+
if (actor.spotKind === contracts_1.ZLinkSpotKind.User &&
|
|
70
|
+
String(actor.spotId) === spotId &&
|
|
71
|
+
actor.spotGeneration === objectGeneration)
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
66
76
|
}, now);
|
|
67
77
|
}
|
|
68
78
|
async readAuthority(key, signal) {
|
|
@@ -86,8 +96,8 @@ class ZLinkInMemoryLocationStore {
|
|
|
86
96
|
async readCreationTerminal(operation, signal) {
|
|
87
97
|
return this.authority.readCreationTerminal(operation, signal);
|
|
88
98
|
}
|
|
89
|
-
async releaseEndedReservation(key, expectedStoreVersion, signal) {
|
|
90
|
-
return this.authority.releaseEndedReservation(key, expectedStoreVersion, signal);
|
|
99
|
+
async releaseEndedReservation(key, expectedStoreVersion, signal, request) {
|
|
100
|
+
return this.authority.releaseEndedReservation(key, expectedStoreVersion, signal, request);
|
|
91
101
|
}
|
|
92
102
|
async abort(request, signal) {
|
|
93
103
|
return this.authority.abort(request, signal);
|
|
@@ -316,7 +326,7 @@ class ZLinkInMemoryLocationStore {
|
|
|
316
326
|
async listFanoutPublishers(channelName, page = {}, signal) {
|
|
317
327
|
signal?.throwIfAborted();
|
|
318
328
|
const storeNow = this.now();
|
|
319
|
-
return pageRows(this.fanoutPublishers, (row) => row.channelName === channelName && this.
|
|
329
|
+
return pageRows(this.fanoutPublishers, (row) => row.channelName === channelName && this.liveOwnerLease(row.ownerId, storeNow) !== undefined, page);
|
|
320
330
|
}
|
|
321
331
|
async updatePeer(peer, intent) {
|
|
322
332
|
return this.write(this.peers, key_codec_1.ZLinkLocationKeyCodec.encodePeerKey({
|
|
@@ -342,7 +352,7 @@ class ZLinkInMemoryLocationStore {
|
|
|
342
352
|
const current = this.spots.rows.get(key);
|
|
343
353
|
if (intent === internal_location_contracts_1.ZLinkLocationWriteIntent.NewClaim &&
|
|
344
354
|
current !== undefined &&
|
|
345
|
-
this.
|
|
355
|
+
this.liveOwnerLease(current.ownerId, updatedAt) !== undefined) {
|
|
346
356
|
return rejectedConflict();
|
|
347
357
|
}
|
|
348
358
|
if (intent === internal_location_contracts_1.ZLinkLocationWriteIntent.Renew) {
|
|
@@ -389,9 +399,15 @@ class ZLinkInMemoryLocationStore {
|
|
|
389
399
|
});
|
|
390
400
|
const updatedAt = this.now();
|
|
391
401
|
const current = this.actors.rows.get(key);
|
|
402
|
+
if (actor.spotKind === contracts_1.ZLinkSpotKind.User &&
|
|
403
|
+
(current?.spotKind !== contracts_1.ZLinkSpotKind.User ||
|
|
404
|
+
String(current.spotId) !== String(actor.spotId) ||
|
|
405
|
+
current.spotGeneration !== actor.spotGeneration) &&
|
|
406
|
+
!this.authority.acceptsUserSpotMembership(String(actor.spotId), actor.spotGeneration))
|
|
407
|
+
return rejectedConflict();
|
|
392
408
|
if (intent === internal_location_contracts_1.ZLinkLocationWriteIntent.NewClaim &&
|
|
393
409
|
current !== undefined &&
|
|
394
|
-
this.
|
|
410
|
+
this.liveOwnerLease(current.ownerId, updatedAt) !== undefined) {
|
|
395
411
|
return rejectedConflict();
|
|
396
412
|
}
|
|
397
413
|
if (intent === internal_location_contracts_1.ZLinkLocationWriteIntent.Renew) {
|
|
@@ -651,7 +667,7 @@ class ZLinkInMemoryLocationStore {
|
|
|
651
667
|
const current = table.rows.get(key);
|
|
652
668
|
if (intent === internal_location_contracts_1.ZLinkLocationWriteIntent.NewClaim &&
|
|
653
669
|
current !== undefined &&
|
|
654
|
-
this.
|
|
670
|
+
this.liveOwnerLease(ownerOf(current), updatedAt) !== undefined) {
|
|
655
671
|
return rejectedConflict();
|
|
656
672
|
}
|
|
657
673
|
if (intent === internal_location_contracts_1.ZLinkLocationWriteIntent.NewClaim ||
|
|
@@ -714,9 +730,11 @@ class ZLinkInMemoryLocationStore {
|
|
|
714
730
|
}
|
|
715
731
|
return removed;
|
|
716
732
|
}
|
|
717
|
-
|
|
733
|
+
liveOwnerLease(ownerId, now) {
|
|
718
734
|
const lease = this.leases.get(ownerId);
|
|
719
|
-
return lease !== undefined && lease.leaseExpiresAt.getTime() > now.getTime()
|
|
735
|
+
return lease !== undefined && lease.leaseExpiresAt.getTime() > now.getTime()
|
|
736
|
+
? lease
|
|
737
|
+
: undefined;
|
|
720
738
|
}
|
|
721
739
|
bump(kind, meshName) {
|
|
722
740
|
this.bumpScope({ kind, meshName });
|
|
@@ -1,4 +1,12 @@
|
|
|
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
|
+
}
|
|
7
|
+
export type ZLinkEndedOwnerReleaseIntent = Pick<ZLinkObjectReserveRequest, 'key' | 'actorRelocationPolicy'> & {
|
|
8
|
+
readonly intent: Pick<ZLinkObjectReserveRequest['intent'], 'stableType'>;
|
|
9
|
+
};
|
|
2
10
|
export type * from '../../contracts/Locations/Authority';
|
|
3
11
|
export type { ZLinkActorLocation, ZLinkPeerLocation, ZLinkRouteLocation, ZLinkSpotLocation } from '../../contracts/Locations/Rows';
|
|
4
12
|
export type { ZLinkActorLocationFilter, ZLinkActorLocationKey, ZLinkLocationKey, ZLinkPeerLocationFilter, ZLinkPeerLocationKey, ZLinkRouteLocationFilter, ZLinkRouteLocationKey, ZLinkSpotLocationFilter, ZLinkSpotLocationKey } from '../../contracts/Locations/Keys';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type ZLinkClientServerServerDescriptor, type ZLinkClientServerServerDescriptorKey, type ZLinkFanoutPublisherDescriptor, type ZLinkFanoutPublisherDescriptorKey, type ZLinkLocationPage, type ZLinkLocationStore, type ZLinkMeshNodeDescriptor, type ZLinkMeshNodeDescriptorKey, type ZLinkPageRequest } from '../../contracts';
|
|
2
2
|
import { ZLinkInMemoryLocationStore } from './in-memory-location-store';
|
|
3
|
-
import { type ZLinkActorLocation, type ZLinkActorLocationFilter, type ZLinkActorLocationKey, type ZLinkAggregateAbortResult, type ZLinkAggregateCommitResult, type ZLinkAggregateFence, type ZLinkAggregatePrepareRequest, type ZLinkAggregatePrepareResult, type ZLinkAuthorityCompareExchangeResult, type ZLinkAuthorityKey, type ZLinkAuthorityMutation, type ZLinkAuthorityReadResult, type ZLinkAuthorityScanCursor, type ZLinkAuthorityScanResult, type ZLinkAuthorityStoreVersion, type ZLinkCreationOperationIdentity, type ZLinkCreationTerminalReadResult, type ZLinkLocationOwnerToken, type ZLinkLocationWriteResult, type ZLinkLocationWriteStatus, type ZLinkObjectAbortRequest, type ZLinkObjectAbortResult, type ZLinkObjectCommitRequest, type ZLinkObjectCommitResult, type ZLinkObjectCreationCompleteRequest, type ZLinkObjectCreationCompleteResult, type ZLinkObjectReserveRequest, type ZLinkObjectReserveResult, type ZLinkOwnerLeaseClaimResult, type ZLinkOwnerLeaseReadResult, type ZLinkOwnerLeaseReleaseResult, type ZLinkOwnerLeaseRenewResult, type ZLinkRouteLocation, type ZLinkRouteLocationFilter, type ZLinkRouteLocationKey, type ZLinkSpotLocation, type ZLinkSpotLocationFilter, type ZLinkSpotLocationKey, ZLinkLocationWriteIntent } from './internal-location-contracts';
|
|
3
|
+
import { type ZLinkActorLocation, type ZLinkActorLocationFilter, type ZLinkActorLocationKey, type ZLinkAggregateAbortResult, type ZLinkAggregateCommitResult, type ZLinkAggregateFence, type ZLinkAggregatePrepareRequest, type ZLinkAggregatePrepareResult, type ZLinkAuthorityCompareExchangeResult, type ZLinkAuthorityKey, type ZLinkAuthorityMutation, type ZLinkAuthorityReadResult, type ZLinkAuthorityScanCursor, type ZLinkAuthorityScanResult, type ZLinkAuthorityStoreVersion, type ZLinkCreationOperationIdentity, type ZLinkCreationTerminalReadResult, type ZLinkLocationOwnerToken, type ZLinkLocationWriteResult, type ZLinkLocationWriteStatus, type ZLinkObjectAbortRequest, type ZLinkObjectAbortResult, type ZLinkObjectCommitRequest, type ZLinkObjectCommitResult, type ZLinkObjectCreationCompleteRequest, type ZLinkObjectCreationCompleteResult, type ZLinkEndedOwnerReleaseIntent, type ZLinkObjectReserveRequest, type ZLinkObjectReserveResult, type ZLinkOwnerLeaseClaimResult, type ZLinkOwnerLeaseReadResult, type ZLinkOwnerLeaseReleaseResult, type ZLinkOwnerLeaseRenewResult, type ZLinkRouteLocation, type ZLinkRouteLocationFilter, type ZLinkRouteLocationKey, type ZLinkSpotLocation, type ZLinkSpotLocationFilter, type ZLinkSpotLocationKey, ZLinkLocationWriteIntent } from './internal-location-contracts';
|
|
4
4
|
/**
|
|
5
5
|
* Maps framework domain records to the minimal provider SPI.
|
|
6
6
|
*
|
|
@@ -20,7 +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>;
|
|
23
|
+
releaseEndedReservation(key: ZLinkAuthorityKey, expectedStoreVersion: string, signal?: AbortSignal, request?: ZLinkEndedOwnerReleaseIntent): Promise<boolean>;
|
|
24
|
+
private tryReleaseEndedReservation;
|
|
24
25
|
reserve(request: ZLinkObjectReserveRequest, signal?: AbortSignal, deadlineUnixMs?: bigint): Promise<ZLinkObjectReserveResult>;
|
|
25
26
|
commit(request: ZLinkObjectCommitRequest, signal?: AbortSignal, deadlineUnixMs?: bigint): Promise<ZLinkObjectCommitResult>;
|
|
26
27
|
abort(request: ZLinkObjectAbortRequest, signal?: AbortSignal, deadlineUnixMs?: bigint): Promise<ZLinkObjectAbortResult>;
|
|
@@ -58,6 +59,7 @@ export declare class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationS
|
|
|
58
59
|
private writeDescriptorWithReconciliation;
|
|
59
60
|
private removeDescriptor;
|
|
60
61
|
private listDescriptors;
|
|
62
|
+
private userSpotMembershipConditions;
|
|
61
63
|
private updateOwnedLocation;
|
|
62
64
|
private removeOwnedLocation;
|
|
63
65
|
private readOwnedLocation;
|