@serve.zone/interfaces 32.11.0 → 32.12.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/changelog.md +10 -0
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/data/serviceruntime.d.ts +2 -0
- package/dist_ts/data/serviceruntime.js +3 -1
- package/dist_ts/requests/service.d.ts +74 -5
- package/package.json +1 -1
- package/readme.md +26 -4
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/data/serviceruntime.ts +2 -0
- package/ts/requests/service.ts +83 -5
package/changelog.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2026-09-20 - 32.12.0
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
- Preserve one canonical service on multiple cluster runtime targets. The existing runtime spec,
|
|
8
|
+
status, write, assignment and push shapes stay unchanged; exact-cluster and paged target reads
|
|
9
|
+
expose every target, while the scalar read refuses an ambiguous multi-target result. A guarded
|
|
10
|
+
exact-cluster removal carries only its revision fence, leaving Cloudly to derive held state,
|
|
11
|
+
completed slot settlement and release, and current runtime-phase authority.
|
|
12
|
+
|
|
3
13
|
## 2026-09-20 - 32.11.0
|
|
4
14
|
|
|
5
15
|
### Features
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@serve.zone/interfaces',
|
|
6
|
-
version: '32.
|
|
6
|
+
version: '32.12.0',
|
|
7
7
|
description: 'Shared TypeScript interfaces and TypedRequest contracts for the serve.zone ecosystem.'
|
|
8
8
|
};
|
|
9
9
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSx3QkFBd0I7SUFDOUIsT0FBTyxFQUFFLFNBQVM7SUFDbEIsV0FBVyxFQUFFLHVGQUF1RjtDQUNyRyxDQUFBIn0=
|
|
@@ -66,6 +66,8 @@ export declare const serviceRuntimeContract: Readonly<{
|
|
|
66
66
|
/** A node can run workloads only as an egress member of the protected authority, which admits at most this many. */
|
|
67
67
|
readonly maximumPinnedNodes: 256;
|
|
68
68
|
readonly maximumPlatformEndpoints: 64;
|
|
69
|
+
/** The largest `limit` `getServiceRuntimeSpecs` accepts; Cloudly refuses a larger one. */
|
|
70
|
+
readonly maximumSpecPageSize: 256;
|
|
69
71
|
/** The largest `limit` `getClusterRuntimeAssignments` accepts; Cloudly refuses a larger one. */
|
|
70
72
|
readonly maximumAssignmentPageSize: 256;
|
|
71
73
|
}>;
|
|
@@ -9,6 +9,8 @@ export const serviceRuntimeContract = Object.freeze({
|
|
|
9
9
|
/** A node can run workloads only as an egress member of the protected authority, which admits at most this many. */
|
|
10
10
|
maximumPinnedNodes: runtimeNetworkAuthorityContract.maximumEgressAuthorities,
|
|
11
11
|
maximumPlatformEndpoints: runtimeNetworkAuthorityContract.maximumPlatformEndpoints,
|
|
12
|
+
/** The largest `limit` `getServiceRuntimeSpecs` accepts; Cloudly refuses a larger one. */
|
|
13
|
+
maximumSpecPageSize: 256,
|
|
12
14
|
/** The largest `limit` `getClusterRuntimeAssignments` accepts; Cloudly refuses a larger one. */
|
|
13
15
|
maximumAssignmentPageSize: 256,
|
|
14
16
|
});
|
|
@@ -92,4 +94,4 @@ export const snapshotServiceRuntimeStatus = (value) => producerSafe(() => {
|
|
|
92
94
|
requireNetwork(item.state === 'refused' && isOneOf(serviceRuntimeRefusals, item.reason));
|
|
93
95
|
return { ...base, state: item.state, reason: item.reason };
|
|
94
96
|
});
|
|
95
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
97
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmljZXJ1bnRpbWUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9kYXRhL3NlcnZpY2VydW50aW1lLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUlBLE9BQU8sRUFBRSwrQkFBK0IsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ3hFLE9BQU8sRUFBRSxjQUFjLEVBQUUsZ0JBQWdCLEVBQUUsY0FBYyxFQUFFLFNBQVMsRUFBRSxXQUFXLEVBQUUsYUFBYSxFQUFFLGFBQWEsRUFBRSxhQUFhLEVBQzVILGNBQWMsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQ3hELE9BQU8sRUFBRSxZQUFZLEVBQUUsT0FBTyxFQUFFLFlBQVksRUFBRSxTQUFTLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNoRyxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsZ0JBQWdCLEVBQUUsa0JBQWtCLEVBQUUsdUJBQXVCLEVBQUUsa0JBQWtCLEVBQ2hILG9CQUFvQixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUF3RDVELE1BQU0sQ0FBQyxNQUFNLHNCQUFzQixHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUM7SUFDbEQsc0JBQXNCLEVBQUUsRUFBRTtJQUMxQiwrRkFBK0Y7SUFDL0YsZUFBZSxFQUFFLEVBQUU7SUFDbkIsb0hBQW9IO0lBQ3BILGtCQUFrQixFQUFFLCtCQUErQixDQUFDLHdCQUF3QjtJQUM1RSx3QkFBd0IsRUFBRSwrQkFBK0IsQ0FBQyx3QkFBd0I7SUFDbEYsMEZBQTBGO0lBQzFGLG1CQUFtQixFQUFFLEdBQUc7SUFDeEIsZ0dBQWdHO0lBQ2hHLHlCQUF5QixFQUFFLEdBQUc7Q0FDdEIsQ0FBQyxDQUFDO0FBRVosTUFBTSw0QkFBNEIsR0FBRyxDQUFDLHNCQUFzQixFQUFFLFVBQVUsRUFBRSxpQkFBaUIsQ0FBVSxDQUFDO0FBQ3RHLE1BQU0sc0JBQXNCLEdBQUc7SUFDN0IseUJBQXlCLEVBQUUsc0JBQXNCLEVBQUUsb0JBQW9CLEVBQUUsc0JBQXNCO0lB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
|
|
@@ -270,9 +270,10 @@ export interface IRequest_Any_Cloudly_DeleteServiceById extends plugins.typedreq
|
|
|
270
270
|
/**
|
|
271
271
|
* Writes the complete runtime spec of one service.
|
|
272
272
|
*
|
|
273
|
-
* `expectedRevision` is the revision the caller read
|
|
274
|
-
* spec; any other stored revision refuses the write.
|
|
275
|
-
* service and answers with the stored spec at its new
|
|
273
|
+
* `expectedRevision` is the revision the caller read for the target `(serviceId, spec.clusterId)`,
|
|
274
|
+
* or `null` when that target has never had a spec; any other stored revision refuses the write.
|
|
275
|
+
* Cloudly copies the organization from the service and answers with the stored spec at its new
|
|
276
|
+
* target-local revision.
|
|
276
277
|
*/
|
|
277
278
|
export interface IRequest_Any_Cloudly_SetServiceRuntimeSpec extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IRequest_Any_Cloudly_SetServiceRuntimeSpec> {
|
|
278
279
|
method: 'setServiceRuntimeSpec';
|
|
@@ -287,8 +288,19 @@ export interface IRequest_Any_Cloudly_SetServiceRuntimeSpec extends plugins.type
|
|
|
287
288
|
};
|
|
288
289
|
}
|
|
289
290
|
/**
|
|
290
|
-
*
|
|
291
|
-
*
|
|
291
|
+
* The named refusal data when a scalar runtime-spec read finds more than one cluster target.
|
|
292
|
+
*
|
|
293
|
+
* This travels as `TypedResponseError.errorData`. The condition needs an explicit cluster or the
|
|
294
|
+
* paged read, never a retry of the same ambiguous request.
|
|
295
|
+
*/
|
|
296
|
+
export interface IServiceRuntimeSpecAmbiguityErrorData {
|
|
297
|
+
code: 'service-runtime-spec-ambiguous';
|
|
298
|
+
retryable: false;
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* The only runtime spec of a service and the producer's verdict on it. Zero targets answer both
|
|
302
|
+
* members as `null`; one target answers it, with `status: null` until the producer first decides it.
|
|
303
|
+
* More than one target refuses with `IServiceRuntimeSpecAmbiguityErrorData`; Cloudly never picks one.
|
|
292
304
|
*/
|
|
293
305
|
export interface IRequest_Any_Cloudly_GetServiceRuntimeSpec extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IRequest_Any_Cloudly_GetServiceRuntimeSpec> {
|
|
294
306
|
method: 'getServiceRuntimeSpec';
|
|
@@ -304,6 +316,63 @@ export interface IRequest_Any_Cloudly_GetServiceRuntimeSpec extends plugins.type
|
|
|
304
316
|
status: IServiceRuntimeStatus | null;
|
|
305
317
|
};
|
|
306
318
|
}
|
|
319
|
+
/** One service's runtime spec for one exact cluster target, or no such target. */
|
|
320
|
+
export interface IRequest_Any_Cloudly_GetServiceRuntimeSpecForCluster extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IRequest_Any_Cloudly_GetServiceRuntimeSpecForCluster> {
|
|
321
|
+
method: 'getServiceRuntimeSpecForCluster';
|
|
322
|
+
request: {
|
|
323
|
+
identity: IIdentity;
|
|
324
|
+
serviceId: string;
|
|
325
|
+
clusterId: string;
|
|
326
|
+
};
|
|
327
|
+
response: {
|
|
328
|
+
spec: null;
|
|
329
|
+
status: null;
|
|
330
|
+
} | {
|
|
331
|
+
spec: IServiceRuntimeSpec;
|
|
332
|
+
status: IServiceRuntimeStatus | null;
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Every cluster target of one service, ordered by cluster id and read a bounded page at a time.
|
|
337
|
+
* `cursor` is opaque and `limit` runs from 1 through `serviceRuntimeContract.maximumSpecPageSize`;
|
|
338
|
+
* Cloudly refuses any other limit. A returned status belongs to the spec beside it.
|
|
339
|
+
*/
|
|
340
|
+
export interface IRequest_Any_Cloudly_GetServiceRuntimeSpecs extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IRequest_Any_Cloudly_GetServiceRuntimeSpecs> {
|
|
341
|
+
method: 'getServiceRuntimeSpecs';
|
|
342
|
+
request: {
|
|
343
|
+
identity: IIdentity;
|
|
344
|
+
serviceId: string;
|
|
345
|
+
cursor: string | null;
|
|
346
|
+
limit: number;
|
|
347
|
+
};
|
|
348
|
+
response: {
|
|
349
|
+
entries: Array<{
|
|
350
|
+
spec: IServiceRuntimeSpec;
|
|
351
|
+
status: IServiceRuntimeStatus | null;
|
|
352
|
+
}>;
|
|
353
|
+
nextCursor: string | null;
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* Removes one exact cluster target at the revision the administrator read.
|
|
358
|
+
*
|
|
359
|
+
* Cloudly derives every safety fact itself and fences them in the removal transaction: the current
|
|
360
|
+
* spec revision equals `expectedRevision`, that spec is held, every slot of this service on this
|
|
361
|
+
* cluster is fully settled and released, and the cluster's current phase still gives the spec
|
|
362
|
+
* producer authority. The caller supplies no phase, settlement, release or authority proof.
|
|
363
|
+
*/
|
|
364
|
+
export interface IRequest_Any_Cloudly_RemoveServiceRuntimeSpecForCluster extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IRequest_Any_Cloudly_RemoveServiceRuntimeSpecForCluster> {
|
|
365
|
+
method: 'removeServiceRuntimeSpecForCluster';
|
|
366
|
+
request: {
|
|
367
|
+
identity: IIdentity;
|
|
368
|
+
serviceId: string;
|
|
369
|
+
clusterId: string;
|
|
370
|
+
expectedRevision: number;
|
|
371
|
+
};
|
|
372
|
+
response: {
|
|
373
|
+
removed: true;
|
|
374
|
+
};
|
|
375
|
+
}
|
|
307
376
|
/** Every current runtime assignment of one service, one per replica slot. */
|
|
308
377
|
export interface IRequest_Any_Cloudly_GetServiceRuntimeAssignments extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IRequest_Any_Cloudly_GetServiceRuntimeAssignments> {
|
|
309
378
|
method: 'getServiceRuntimeAssignments';
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -1055,10 +1055,32 @@ an operator's service edit.
|
|
|
1055
1055
|
with sorted unique endpoint ids.
|
|
1056
1056
|
|
|
1057
1057
|
`snapshotServiceRuntimeSpec` checks all of that; whether the cluster, the nodes and the endpoints
|
|
1058
|
-
exist is Cloudly's.
|
|
1059
|
-
|
|
1060
|
-
`
|
|
1061
|
-
|
|
1058
|
+
exist is Cloudly's. One canonical service may have one runtime target on each of several clusters.
|
|
1059
|
+
Every public target keeps the same `IServiceRuntimeSpec`: `id` is the exact service id and
|
|
1060
|
+
`clusterId` names that target. Cloudly's private persistence joins those two values; no composite
|
|
1061
|
+
public service id is introduced.
|
|
1062
|
+
|
|
1063
|
+
`requests.service.setServiceRuntimeSpec { identity, serviceId, expectedRevision, spec }` writes
|
|
1064
|
+
`TServiceRuntimeSpecWritableData`, and Cloudly copies the organization from the service. Its
|
|
1065
|
+
compare-and-swap is for `(serviceId, spec.clusterId)`: `null` means that exact target is absent, and
|
|
1066
|
+
each target advances its own revision. The request bytes and public spec shape are unchanged.
|
|
1067
|
+
|
|
1068
|
+
`getServiceRuntimeSpecForCluster { identity, serviceId, clusterId }` reads one exact target.
|
|
1069
|
+
`getServiceRuntimeSpecs { identity, serviceId, cursor, limit }` reads targets in cluster-id order,
|
|
1070
|
+
with an opaque cursor and a limit from 1 through `serviceRuntimeContract.maximumSpecPageSize`.
|
|
1071
|
+
Both reads answer each spec with its producer status, which is `null` until the producer first
|
|
1072
|
+
decides the spec. A status never comes without its spec.
|
|
1073
|
+
|
|
1074
|
+
The original `getServiceRuntimeSpec { identity, serviceId }` remains a scalar compatibility read:
|
|
1075
|
+
zero targets answer `{ spec: null, status: null }`, and one target answers it. More than one target
|
|
1076
|
+
is refused with `IServiceRuntimeSpecAmbiguityErrorData { code: 'service-runtime-spec-ambiguous',
|
|
1077
|
+
retryable: false }` in `TypedResponseError.errorData`; Cloudly never selects a target implicitly.
|
|
1078
|
+
|
|
1079
|
+
`removeServiceRuntimeSpecForCluster { identity, serviceId, clusterId, expectedRevision }` removes
|
|
1080
|
+
one exact target only after Cloudly transactionally derives and fences all authority and safety
|
|
1081
|
+
facts: the revision still matches, the target is held, every target slot is fully settled and
|
|
1082
|
+
released, and the cluster's current phase still belongs to the spec producer. Callers provide no
|
|
1083
|
+
phase, settlement, release or authority booleans or evidence.
|
|
1062
1084
|
|
|
1063
1085
|
`data.IServiceRuntimeStatus { id, specRevision, state, reason, changedAt }` is the producer's verdict
|
|
1064
1086
|
on one spec revision, and each reason belongs to exactly one state. `converged` and `converging`
|
package/ts/00_commitinfo_data.ts
CHANGED
|
@@ -70,6 +70,8 @@ export const serviceRuntimeContract = Object.freeze({
|
|
|
70
70
|
/** A node can run workloads only as an egress member of the protected authority, which admits at most this many. */
|
|
71
71
|
maximumPinnedNodes: runtimeNetworkAuthorityContract.maximumEgressAuthorities,
|
|
72
72
|
maximumPlatformEndpoints: runtimeNetworkAuthorityContract.maximumPlatformEndpoints,
|
|
73
|
+
/** The largest `limit` `getServiceRuntimeSpecs` accepts; Cloudly refuses a larger one. */
|
|
74
|
+
maximumSpecPageSize: 256,
|
|
73
75
|
/** The largest `limit` `getClusterRuntimeAssignments` accepts; Cloudly refuses a larger one. */
|
|
74
76
|
maximumAssignmentPageSize: 256,
|
|
75
77
|
} as const);
|
package/ts/requests/service.ts
CHANGED
|
@@ -393,9 +393,10 @@ extends plugins.typedrequestInterfaces.implementsTR<
|
|
|
393
393
|
/**
|
|
394
394
|
* Writes the complete runtime spec of one service.
|
|
395
395
|
*
|
|
396
|
-
* `expectedRevision` is the revision the caller read
|
|
397
|
-
* spec; any other stored revision refuses the write.
|
|
398
|
-
* service and answers with the stored spec at its new
|
|
396
|
+
* `expectedRevision` is the revision the caller read for the target `(serviceId, spec.clusterId)`,
|
|
397
|
+
* or `null` when that target has never had a spec; any other stored revision refuses the write.
|
|
398
|
+
* Cloudly copies the organization from the service and answers with the stored spec at its new
|
|
399
|
+
* target-local revision.
|
|
399
400
|
*/
|
|
400
401
|
export interface IRequest_Any_Cloudly_SetServiceRuntimeSpec
|
|
401
402
|
extends plugins.typedrequestInterfaces.implementsTR<
|
|
@@ -415,8 +416,20 @@ extends plugins.typedrequestInterfaces.implementsTR<
|
|
|
415
416
|
}
|
|
416
417
|
|
|
417
418
|
/**
|
|
418
|
-
*
|
|
419
|
-
*
|
|
419
|
+
* The named refusal data when a scalar runtime-spec read finds more than one cluster target.
|
|
420
|
+
*
|
|
421
|
+
* This travels as `TypedResponseError.errorData`. The condition needs an explicit cluster or the
|
|
422
|
+
* paged read, never a retry of the same ambiguous request.
|
|
423
|
+
*/
|
|
424
|
+
export interface IServiceRuntimeSpecAmbiguityErrorData {
|
|
425
|
+
code: 'service-runtime-spec-ambiguous';
|
|
426
|
+
retryable: false;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
/**
|
|
430
|
+
* The only runtime spec of a service and the producer's verdict on it. Zero targets answer both
|
|
431
|
+
* members as `null`; one target answers it, with `status: null` until the producer first decides it.
|
|
432
|
+
* More than one target refuses with `IServiceRuntimeSpecAmbiguityErrorData`; Cloudly never picks one.
|
|
420
433
|
*/
|
|
421
434
|
export interface IRequest_Any_Cloudly_GetServiceRuntimeSpec
|
|
422
435
|
extends plugins.typedrequestInterfaces.implementsTR<
|
|
@@ -433,6 +446,71 @@ extends plugins.typedrequestInterfaces.implementsTR<
|
|
|
433
446
|
| { spec: IServiceRuntimeSpec; status: IServiceRuntimeStatus | null };
|
|
434
447
|
}
|
|
435
448
|
|
|
449
|
+
/** One service's runtime spec for one exact cluster target, or no such target. */
|
|
450
|
+
export interface IRequest_Any_Cloudly_GetServiceRuntimeSpecForCluster
|
|
451
|
+
extends plugins.typedrequestInterfaces.implementsTR<
|
|
452
|
+
plugins.typedrequestInterfaces.ITypedRequest,
|
|
453
|
+
IRequest_Any_Cloudly_GetServiceRuntimeSpecForCluster
|
|
454
|
+
> {
|
|
455
|
+
method: 'getServiceRuntimeSpecForCluster';
|
|
456
|
+
request: {
|
|
457
|
+
identity: IIdentity;
|
|
458
|
+
serviceId: string;
|
|
459
|
+
clusterId: string;
|
|
460
|
+
};
|
|
461
|
+
response:
|
|
462
|
+
| { spec: null; status: null }
|
|
463
|
+
| { spec: IServiceRuntimeSpec; status: IServiceRuntimeStatus | null };
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
/**
|
|
467
|
+
* Every cluster target of one service, ordered by cluster id and read a bounded page at a time.
|
|
468
|
+
* `cursor` is opaque and `limit` runs from 1 through `serviceRuntimeContract.maximumSpecPageSize`;
|
|
469
|
+
* Cloudly refuses any other limit. A returned status belongs to the spec beside it.
|
|
470
|
+
*/
|
|
471
|
+
export interface IRequest_Any_Cloudly_GetServiceRuntimeSpecs
|
|
472
|
+
extends plugins.typedrequestInterfaces.implementsTR<
|
|
473
|
+
plugins.typedrequestInterfaces.ITypedRequest,
|
|
474
|
+
IRequest_Any_Cloudly_GetServiceRuntimeSpecs
|
|
475
|
+
> {
|
|
476
|
+
method: 'getServiceRuntimeSpecs';
|
|
477
|
+
request: {
|
|
478
|
+
identity: IIdentity;
|
|
479
|
+
serviceId: string;
|
|
480
|
+
cursor: string | null;
|
|
481
|
+
limit: number;
|
|
482
|
+
};
|
|
483
|
+
response: {
|
|
484
|
+
entries: Array<{ spec: IServiceRuntimeSpec; status: IServiceRuntimeStatus | null }>;
|
|
485
|
+
nextCursor: string | null;
|
|
486
|
+
};
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
/**
|
|
490
|
+
* Removes one exact cluster target at the revision the administrator read.
|
|
491
|
+
*
|
|
492
|
+
* Cloudly derives every safety fact itself and fences them in the removal transaction: the current
|
|
493
|
+
* spec revision equals `expectedRevision`, that spec is held, every slot of this service on this
|
|
494
|
+
* cluster is fully settled and released, and the cluster's current phase still gives the spec
|
|
495
|
+
* producer authority. The caller supplies no phase, settlement, release or authority proof.
|
|
496
|
+
*/
|
|
497
|
+
export interface IRequest_Any_Cloudly_RemoveServiceRuntimeSpecForCluster
|
|
498
|
+
extends plugins.typedrequestInterfaces.implementsTR<
|
|
499
|
+
plugins.typedrequestInterfaces.ITypedRequest,
|
|
500
|
+
IRequest_Any_Cloudly_RemoveServiceRuntimeSpecForCluster
|
|
501
|
+
> {
|
|
502
|
+
method: 'removeServiceRuntimeSpecForCluster';
|
|
503
|
+
request: {
|
|
504
|
+
identity: IIdentity;
|
|
505
|
+
serviceId: string;
|
|
506
|
+
clusterId: string;
|
|
507
|
+
expectedRevision: number;
|
|
508
|
+
};
|
|
509
|
+
response: {
|
|
510
|
+
removed: true;
|
|
511
|
+
};
|
|
512
|
+
}
|
|
513
|
+
|
|
436
514
|
/** Every current runtime assignment of one service, one per replica slot. */
|
|
437
515
|
export interface IRequest_Any_Cloudly_GetServiceRuntimeAssignments
|
|
438
516
|
extends plugins.typedrequestInterfaces.implementsTR<
|