@fluidframework/container-runtime 2.0.0-rc.3.0.0 → 2.0.0-rc.3.0.10
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/api-report/container-runtime.api.md +30 -12
- package/dist/channelCollection.d.ts +5 -3
- package/dist/channelCollection.d.ts.map +1 -1
- package/dist/channelCollection.js +88 -29
- package/dist/channelCollection.js.map +1 -1
- package/dist/containerRuntime.d.ts +6 -1
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +55 -48
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStoreContext.d.ts +1 -1
- package/dist/dataStoreContexts.d.ts +2 -0
- package/dist/dataStoreContexts.d.ts.map +1 -1
- package/dist/dataStoreContexts.js +7 -0
- package/dist/dataStoreContexts.js.map +1 -1
- package/dist/gc/garbageCollection.d.ts +4 -11
- package/dist/gc/garbageCollection.d.ts.map +1 -1
- package/dist/gc/garbageCollection.js +45 -29
- package/dist/gc/garbageCollection.js.map +1 -1
- package/dist/gc/gcDefinitions.d.ts +26 -5
- package/dist/gc/gcDefinitions.d.ts.map +1 -1
- package/dist/gc/gcDefinitions.js.map +1 -1
- package/dist/gc/gcHelpers.d.ts +5 -4
- package/dist/gc/gcHelpers.d.ts.map +1 -1
- package/dist/gc/gcHelpers.js +14 -2
- package/dist/gc/gcHelpers.js.map +1 -1
- package/dist/gc/gcTelemetry.d.ts +13 -2
- package/dist/gc/gcTelemetry.d.ts.map +1 -1
- package/dist/gc/gcTelemetry.js +24 -21
- package/dist/gc/gcTelemetry.js.map +1 -1
- package/dist/gc/index.d.ts +2 -2
- package/dist/gc/index.d.ts.map +1 -1
- package/dist/gc/index.js +2 -2
- package/dist/gc/index.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/legacy.d.ts +1 -0
- package/dist/metadata.d.ts +2 -2
- package/dist/metadata.d.ts.map +1 -1
- package/dist/metadata.js.map +1 -1
- package/dist/opLifecycle/batchManager.d.ts +4 -1
- package/dist/opLifecycle/batchManager.d.ts.map +1 -1
- package/dist/opLifecycle/batchManager.js +0 -10
- package/dist/opLifecycle/batchManager.js.map +1 -1
- package/dist/opLifecycle/outbox.d.ts +0 -4
- package/dist/opLifecycle/outbox.d.ts.map +1 -1
- package/dist/opLifecycle/outbox.js +7 -38
- package/dist/opLifecycle/outbox.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.d.ts.map +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/summary/documentSchema.js +1 -1
- package/dist/summary/documentSchema.js.map +1 -1
- package/lib/channelCollection.d.ts +5 -3
- package/lib/channelCollection.d.ts.map +1 -1
- package/lib/channelCollection.js +90 -31
- package/lib/channelCollection.js.map +1 -1
- package/lib/containerRuntime.d.ts +6 -1
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +54 -47
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStoreContext.d.ts +1 -1
- package/lib/dataStoreContexts.d.ts +2 -0
- package/lib/dataStoreContexts.d.ts.map +1 -1
- package/lib/dataStoreContexts.js +7 -0
- package/lib/dataStoreContexts.js.map +1 -1
- package/lib/gc/garbageCollection.d.ts +4 -11
- package/lib/gc/garbageCollection.d.ts.map +1 -1
- package/lib/gc/garbageCollection.js +47 -31
- package/lib/gc/garbageCollection.js.map +1 -1
- package/lib/gc/gcDefinitions.d.ts +26 -5
- package/lib/gc/gcDefinitions.d.ts.map +1 -1
- package/lib/gc/gcDefinitions.js.map +1 -1
- package/lib/gc/gcHelpers.d.ts +5 -4
- package/lib/gc/gcHelpers.d.ts.map +1 -1
- package/lib/gc/gcHelpers.js +12 -1
- package/lib/gc/gcHelpers.js.map +1 -1
- package/lib/gc/gcTelemetry.d.ts +13 -2
- package/lib/gc/gcTelemetry.d.ts.map +1 -1
- package/lib/gc/gcTelemetry.js +24 -21
- package/lib/gc/gcTelemetry.js.map +1 -1
- package/lib/gc/index.d.ts +2 -2
- package/lib/gc/index.d.ts.map +1 -1
- package/lib/gc/index.js +1 -1
- package/lib/gc/index.js.map +1 -1
- package/lib/index.d.ts +2 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib/legacy.d.ts +1 -0
- package/lib/metadata.d.ts +2 -2
- package/lib/metadata.d.ts.map +1 -1
- package/lib/metadata.js.map +1 -1
- package/lib/opLifecycle/batchManager.d.ts +4 -1
- package/lib/opLifecycle/batchManager.d.ts.map +1 -1
- package/lib/opLifecycle/batchManager.js +0 -10
- package/lib/opLifecycle/batchManager.js.map +1 -1
- package/lib/opLifecycle/outbox.d.ts +0 -4
- package/lib/opLifecycle/outbox.d.ts.map +1 -1
- package/lib/opLifecycle/outbox.js +7 -38
- package/lib/opLifecycle/outbox.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.d.ts.map +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/summary/documentSchema.js +1 -1
- package/lib/summary/documentSchema.js.map +1 -1
- package/package.json +20 -20
- package/src/channelCollection.ts +108 -49
- package/src/containerRuntime.ts +66 -80
- package/src/dataStoreContexts.ts +12 -0
- package/src/gc/garbageCollection.ts +63 -41
- package/src/gc/gcDefinitions.ts +21 -9
- package/src/gc/gcHelpers.ts +14 -1
- package/src/gc/gcTelemetry.ts +56 -47
- package/src/gc/index.ts +2 -1
- package/src/index.ts +2 -0
- package/src/metadata.ts +2 -2
- package/src/opLifecycle/README.md +4 -4
- package/src/opLifecycle/batchManager.ts +5 -14
- package/src/opLifecycle/outbox.ts +7 -53
- package/src/packageVersion.ts +1 -1
- package/src/summary/documentSchema.ts +1 -1
- package/dist/public.d.ts +0 -12
- package/lib/public.d.ts +0 -12
package/dist/containerRuntime.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Licensed under the MIT License.
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.ContainerRuntime = exports.makeLegacySendBatchFn = exports.getDeviceSpec = exports.agentSchedulerId = exports.isRuntimeMessage = exports.defaultPendingOpsRetryDelayMs = exports.defaultPendingOpsWaitTimeoutMs = exports.disabledCompressionConfig = exports.CompressionAlgorithms = exports.defaultRuntimeHeaderData = exports.InactiveResponseHeaderKey = exports.TombstoneResponseHeaderKey = exports.DefaultSummaryConfiguration = void 0;
|
|
7
|
+
exports.ContainerRuntime = exports.makeLegacySendBatchFn = exports.getDeviceSpec = exports.agentSchedulerId = exports.isRuntimeMessage = exports.defaultPendingOpsRetryDelayMs = exports.defaultPendingOpsWaitTimeoutMs = exports.disabledCompressionConfig = exports.CompressionAlgorithms = exports.defaultRuntimeHeaderData = exports.InactiveResponseHeaderKey = exports.TombstoneResponseHeaderKey = exports.DeletedResponseHeaderKey = exports.DefaultSummaryConfiguration = void 0;
|
|
8
8
|
const client_utils_1 = require("@fluid-internal/client-utils");
|
|
9
9
|
const container_definitions_1 = require("@fluidframework/container-definitions");
|
|
10
10
|
const internal_1 = require("@fluidframework/container-definitions/internal");
|
|
@@ -61,6 +61,11 @@ exports.DefaultSummaryConfiguration = {
|
|
|
61
61
|
runtimeOpWeight: 1.0,
|
|
62
62
|
nonRuntimeHeuristicThreshold: 20,
|
|
63
63
|
};
|
|
64
|
+
/**
|
|
65
|
+
* Error responses when requesting a deleted object will have this header set to true
|
|
66
|
+
* @alpha
|
|
67
|
+
*/
|
|
68
|
+
exports.DeletedResponseHeaderKey = "wasDeleted";
|
|
64
69
|
/**
|
|
65
70
|
* Tombstone error responses will have this header set to true
|
|
66
71
|
* @alpha
|
|
@@ -740,7 +745,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
740
745
|
const envelope2 = this.createNewSignalEnvelope(envelope1.address, type, envelope1.contents);
|
|
741
746
|
return this.submitSignalFn(envelope2, targetClientId);
|
|
742
747
|
};
|
|
743
|
-
this.channelCollection = new channelCollection_js_1.ChannelCollection((0, channelCollection_js_1.getSummaryForDatastores)(baseSnapshot, metadata), parentContext, this.mc.logger, (
|
|
748
|
+
this.channelCollection = new channelCollection_js_1.ChannelCollection((0, channelCollection_js_1.getSummaryForDatastores)(baseSnapshot, metadata), parentContext, this.mc.logger, (props) => this.garbageCollector.nodeUpdated(props), (path) => this.garbageCollector.isNodeDeleted(path), new Map(dataStoreAliasMap), async (runtime) => provideEntryPoint);
|
|
744
749
|
this.blobManager = new blobManager_js_1.BlobManager({
|
|
745
750
|
routeContext: this.handleContext,
|
|
746
751
|
snapshot: blobManagerSnapshot,
|
|
@@ -753,7 +758,10 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
753
758
|
});
|
|
754
759
|
}
|
|
755
760
|
},
|
|
756
|
-
blobRequested: (blobPath) => this.garbageCollector.nodeUpdated(
|
|
761
|
+
blobRequested: (blobPath) => this.garbageCollector.nodeUpdated({
|
|
762
|
+
node: { type: "Blob", path: blobPath },
|
|
763
|
+
reason: "Loaded",
|
|
764
|
+
}),
|
|
757
765
|
isBlobDeleted: (blobPath) => this.garbageCollector.isNodeDeleted(blobPath),
|
|
758
766
|
runtime: this,
|
|
759
767
|
stashedBlobs: pendingRuntimeState?.pendingAttachmentBlobs,
|
|
@@ -1236,6 +1244,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1236
1244
|
this.emitDirtyDocumentEvent = false;
|
|
1237
1245
|
let newState;
|
|
1238
1246
|
try {
|
|
1247
|
+
this.submitIdAllocationOpIfNeeded(true);
|
|
1239
1248
|
// replay the ops
|
|
1240
1249
|
this.pendingStateManager.replayPendingStates();
|
|
1241
1250
|
}
|
|
@@ -1412,9 +1421,10 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1412
1421
|
// We do not need to make a deep copy. Each layer will just replace message.contents itself,
|
|
1413
1422
|
// but will not modify the contents object (likely it will replace it on the message).
|
|
1414
1423
|
const messageCopy = { ...messageArg };
|
|
1424
|
+
const savedOp = messageCopy.metadata?.savedOp;
|
|
1415
1425
|
for (const message of this.remoteMessageProcessor.process(messageCopy)) {
|
|
1416
|
-
|
|
1417
|
-
|
|
1426
|
+
const msg = modernRuntimeMessage
|
|
1427
|
+
? {
|
|
1418
1428
|
// Cast it since we expect it to be this based on modernRuntimeMessage computation above.
|
|
1419
1429
|
// There is nothing really ensuring that anytime original message.type is Operation that
|
|
1420
1430
|
// the result messages will be so. In the end modern bool being true only directs to
|
|
@@ -1422,12 +1432,16 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1422
1432
|
message: message,
|
|
1423
1433
|
local,
|
|
1424
1434
|
modernRuntimeMessage,
|
|
1425
|
-
}
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1435
|
+
}
|
|
1436
|
+
: // Unrecognized message will be ignored.
|
|
1437
|
+
{
|
|
1438
|
+
message,
|
|
1439
|
+
local,
|
|
1440
|
+
modernRuntimeMessage,
|
|
1441
|
+
};
|
|
1442
|
+
msg.savedOp = savedOp;
|
|
1443
|
+
// ensure that we observe any re-entrancy, and if needed, rebase ops
|
|
1444
|
+
this.ensureNoDataModelChanges(() => this.processCore(msg));
|
|
1431
1445
|
}
|
|
1432
1446
|
}
|
|
1433
1447
|
/**
|
|
@@ -1492,9 +1506,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1492
1506
|
// stashed ops flow. The compressor is stashed with these ops already processed.
|
|
1493
1507
|
// That said, in idCompressorMode === "delayed", we might not serialize ID compressor, and
|
|
1494
1508
|
// thus we need to process all the ops.
|
|
1495
|
-
if (!(this.skipSavedCompressorOps &&
|
|
1496
|
-
messageWithContext.message.metadata?.savedOp ===
|
|
1497
|
-
true)) {
|
|
1509
|
+
if (!(this.skipSavedCompressorOps && messageWithContext.savedOp === true)) {
|
|
1498
1510
|
const range = messageWithContext.message.contents;
|
|
1499
1511
|
// Some other client turned on the id compressor. If we have not turned it on,
|
|
1500
1512
|
// put it in a pending queue and delay finalization.
|
|
@@ -1623,9 +1635,9 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1623
1635
|
let checkpoint;
|
|
1624
1636
|
let result;
|
|
1625
1637
|
if (this.mc.config.getBoolean("Fluid.ContainerRuntime.EnableRollback")) {
|
|
1626
|
-
// Note: we are not touching
|
|
1627
|
-
// 1. It would not help, as
|
|
1628
|
-
// 2. There is no way to undo process of data store creation.
|
|
1638
|
+
// Note: we are not touching any batches other than mainBatch here, for two reasons:
|
|
1639
|
+
// 1. It would not help, as other batches are flushed independently from main batch.
|
|
1640
|
+
// 2. There is no way to undo process of data store creation, blob creation, ID compressor ops, or other things tracked by other batches.
|
|
1629
1641
|
checkpoint = this.outbox.checkpoint().mainBatch;
|
|
1630
1642
|
}
|
|
1631
1643
|
try {
|
|
@@ -1688,7 +1700,11 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1688
1700
|
if (channel.entryPoint === undefined) {
|
|
1689
1701
|
throw new internal_7.UsageError("entryPoint must be defined on data store runtime for using getAliasedDataStoreEntryPoint");
|
|
1690
1702
|
}
|
|
1691
|
-
this.garbageCollector.nodeUpdated(
|
|
1703
|
+
this.garbageCollector.nodeUpdated({
|
|
1704
|
+
node: { type: "DataStore", path: `/${internalId}` },
|
|
1705
|
+
reason: "Loaded",
|
|
1706
|
+
packagePath: context.packagePath,
|
|
1707
|
+
});
|
|
1692
1708
|
return channel.entryPoint;
|
|
1693
1709
|
}
|
|
1694
1710
|
createDetachedDataStore(pkg, loadingGroupId) {
|
|
@@ -2083,9 +2099,17 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2083
2099
|
const message = `Summary @${summaryRefSeqNum}:${this.deltaManager.minimumSequenceNumber}`;
|
|
2084
2100
|
const lastAck = this.summaryCollection.latestAck;
|
|
2085
2101
|
const startSummaryResult = this.summarizerNode.startSummary(summaryRefSeqNum, summaryNumberLogger, latestSummaryRefSeqNum);
|
|
2102
|
+
/**
|
|
2103
|
+
* This was added to validate that the summarizer node tree has the same reference sequence number from the
|
|
2104
|
+
* top running summarizer down to the lowest summarizer node.
|
|
2105
|
+
*
|
|
2106
|
+
* The order of mismatch numbers goes (validate sequence number)-(node sequence number).
|
|
2107
|
+
* Generally the validate sequence number comes from the running summarizer and the node sequence number comes from the
|
|
2108
|
+
* summarizer nodes.
|
|
2109
|
+
*/
|
|
2086
2110
|
if (startSummaryResult.invalidNodes > 0 ||
|
|
2087
2111
|
startSummaryResult.mismatchNumbers.size > 0) {
|
|
2088
|
-
summaryLogger.
|
|
2112
|
+
summaryLogger.sendTelemetryEvent({
|
|
2089
2113
|
eventName: "LatestSummaryRefSeqNumMismatch",
|
|
2090
2114
|
details: {
|
|
2091
2115
|
...startSummaryResult,
|
|
@@ -2358,9 +2382,11 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2358
2382
|
this.verifyNotClosed();
|
|
2359
2383
|
return this.blobManager.createBlob(blob, signal);
|
|
2360
2384
|
}
|
|
2361
|
-
submitIdAllocationOpIfNeeded() {
|
|
2385
|
+
submitIdAllocationOpIfNeeded(resubmitOutstandingRanges = false) {
|
|
2362
2386
|
if (this._idCompressor) {
|
|
2363
|
-
const idRange =
|
|
2387
|
+
const idRange = resubmitOutstandingRanges
|
|
2388
|
+
? this.idCompressor?.takeUnfinalizedCreationRange()
|
|
2389
|
+
: this._idCompressor.takeNextCreationRange();
|
|
2364
2390
|
// Don't include the idRange if there weren't any Ids allocated
|
|
2365
2391
|
if (idRange?.ids !== undefined) {
|
|
2366
2392
|
const idAllocationMessage = {
|
|
@@ -2422,32 +2448,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2422
2448
|
referenceSequenceNumber: this.deltaManager.lastSequenceNumber,
|
|
2423
2449
|
});
|
|
2424
2450
|
}
|
|
2425
|
-
|
|
2426
|
-
// Is it safe:
|
|
2427
|
-
// Yes, this should be safe reordering. Newly created data stores are not visible through API surface.
|
|
2428
|
-
// They become visible only when aliased, or handle to some sub-element of newly created datastore
|
|
2429
|
-
// is stored in some DDS, i.e. only after some other op.
|
|
2430
|
-
// Why:
|
|
2431
|
-
// Attach ops are large, and expensive to process. Plus there are scenarios where a lot of new data
|
|
2432
|
-
// stores are created, causing issues like relay service throttling (too many ops) and catastrophic
|
|
2433
|
-
// failure (batch is too large). Pushing them earlier and outside of main batch should alleviate
|
|
2434
|
-
// these issues.
|
|
2435
|
-
// Cons:
|
|
2436
|
-
// 1. With large batches, relay service may throttle clients. Clients may disconnect while throttled.
|
|
2437
|
-
// This change creates new possibility of a lot of newly created data stores never being referenced
|
|
2438
|
-
// because client died before it had a change to submit the rest of the ops. This will create more
|
|
2439
|
-
// garbage that needs to be collected leveraging GC (Garbage Collection) feature.
|
|
2440
|
-
// 2. Sending ops out of order means they are excluded from rollback functionality. This is not an issue
|
|
2441
|
-
// today as rollback can't undo creation of data store. To some extent not sending them is a bigger
|
|
2442
|
-
// issue than sending.
|
|
2443
|
-
// Please note that this does not change file format, so it can be disabled in the future if this
|
|
2444
|
-
// optimization no longer makes sense (for example, batch compression may make it less appealing).
|
|
2445
|
-
if (this.currentlyBatching() &&
|
|
2446
|
-
type === messageTypes_js_1.ContainerMessageType.Attach &&
|
|
2447
|
-
this.disableAttachReorder !== true) {
|
|
2448
|
-
this.outbox.submitAttach(message);
|
|
2449
|
-
}
|
|
2450
|
-
else if (type === messageTypes_js_1.ContainerMessageType.BlobAttach) {
|
|
2451
|
+
if (type === messageTypes_js_1.ContainerMessageType.BlobAttach) {
|
|
2451
2452
|
// BlobAttach ops must have their metadata visible and cannot be grouped (see opGroupingManager.ts)
|
|
2452
2453
|
this.outbox.submitBlobAttach(message);
|
|
2453
2454
|
}
|
|
@@ -2579,7 +2580,13 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2579
2580
|
this.channelCollection.reSubmit(message.type, message.contents, localOpMetadata);
|
|
2580
2581
|
break;
|
|
2581
2582
|
case messageTypes_js_1.ContainerMessageType.IdAllocation: {
|
|
2582
|
-
|
|
2583
|
+
// Allocation ops are never resubmitted/rebased. This is because they require special handling to
|
|
2584
|
+
// avoid being submitted out of order. For example, if the pending state manager contained
|
|
2585
|
+
// [idOp1, dataOp1, idOp2, dataOp2] and the resubmission of dataOp1 generated idOp3, that would be
|
|
2586
|
+
// placed into the outbox in the same batch as idOp1, but before idOp2 is resubmitted.
|
|
2587
|
+
// To avoid this, allocation ops are simply never resubmitted. Prior to invoking the pending state
|
|
2588
|
+
// manager to replay pending ops, the runtime will always submit a new allocation range that includes
|
|
2589
|
+
// all pending IDs. The resubmitted allocation ops are then ignored here.
|
|
2583
2590
|
break;
|
|
2584
2591
|
}
|
|
2585
2592
|
case messageTypes_js_1.ContainerMessageType.ChunkedOp:
|