@fluidframework/container-runtime 0.58.3000-61081 → 0.59.1001-62246
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/blobManager.d.ts +13 -1
- package/dist/blobManager.d.ts.map +1 -1
- package/dist/blobManager.js +52 -0
- package/dist/blobManager.js.map +1 -1
- package/dist/connectionTelemetry.js +7 -7
- package/dist/connectionTelemetry.js.map +1 -1
- package/dist/containerRuntime.d.ts +27 -3
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +100 -14
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStore.js +8 -1
- package/dist/dataStore.js.map +1 -1
- package/dist/dataStoreContext.d.ts +9 -3
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +22 -6
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/dataStores.d.ts +13 -5
- package/dist/dataStores.d.ts.map +1 -1
- package/dist/dataStores.js +39 -18
- package/dist/dataStores.js.map +1 -1
- package/dist/deltaScheduler.d.ts +4 -5
- package/dist/deltaScheduler.d.ts.map +1 -1
- package/dist/deltaScheduler.js +54 -35
- package/dist/deltaScheduler.js.map +1 -1
- package/dist/garbageCollection.d.ts +31 -27
- package/dist/garbageCollection.d.ts.map +1 -1
- package/dist/garbageCollection.js +76 -75
- package/dist/garbageCollection.js.map +1 -1
- package/dist/orderedClientElection.d.ts +6 -57
- package/dist/orderedClientElection.d.ts.map +1 -1
- package/dist/orderedClientElection.js +25 -140
- package/dist/orderedClientElection.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/summarizerClientElection.d.ts +0 -2
- package/dist/summarizerClientElection.d.ts.map +1 -1
- package/dist/summarizerClientElection.js +2 -7
- package/dist/summarizerClientElection.js.map +1 -1
- package/dist/summaryManager.d.ts.map +1 -1
- package/dist/summaryManager.js +3 -14
- package/dist/summaryManager.js.map +1 -1
- package/lib/blobManager.d.ts +13 -1
- package/lib/blobManager.d.ts.map +1 -1
- package/lib/blobManager.js +52 -0
- package/lib/blobManager.js.map +1 -1
- package/lib/connectionTelemetry.js +7 -7
- package/lib/connectionTelemetry.js.map +1 -1
- package/lib/containerRuntime.d.ts +27 -3
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +101 -15
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStore.js +8 -1
- package/lib/dataStore.js.map +1 -1
- package/lib/dataStoreContext.d.ts +9 -3
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +22 -6
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/dataStores.d.ts +13 -5
- package/lib/dataStores.d.ts.map +1 -1
- package/lib/dataStores.js +39 -18
- package/lib/dataStores.js.map +1 -1
- package/lib/deltaScheduler.d.ts +4 -5
- package/lib/deltaScheduler.d.ts.map +1 -1
- package/lib/deltaScheduler.js +54 -35
- package/lib/deltaScheduler.js.map +1 -1
- package/lib/garbageCollection.d.ts +31 -27
- package/lib/garbageCollection.d.ts.map +1 -1
- package/lib/garbageCollection.js +75 -74
- package/lib/garbageCollection.js.map +1 -1
- package/lib/orderedClientElection.d.ts +6 -57
- package/lib/orderedClientElection.d.ts.map +1 -1
- package/lib/orderedClientElection.js +25 -140
- package/lib/orderedClientElection.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/summarizerClientElection.d.ts +0 -2
- package/lib/summarizerClientElection.d.ts.map +1 -1
- package/lib/summarizerClientElection.js +2 -7
- package/lib/summarizerClientElection.js.map +1 -1
- package/lib/summaryManager.d.ts.map +1 -1
- package/lib/summaryManager.js +3 -14
- package/lib/summaryManager.js.map +1 -1
- package/package.json +33 -21
- package/src/blobManager.ts +60 -1
- package/src/connectionTelemetry.ts +7 -7
- package/src/containerRuntime.ts +106 -17
- package/src/dataStore.ts +7 -1
- package/src/dataStoreContext.ts +22 -7
- package/src/dataStores.ts +40 -19
- package/src/deltaScheduler.ts +65 -39
- package/src/garbageCollection.ts +92 -78
- package/src/orderedClientElection.ts +25 -154
- package/src/packageVersion.ts +1 -1
- package/src/summarizerClientElection.ts +2 -7
- package/src/summaryManager.ts +4 -15
package/lib/containerRuntime.js
CHANGED
|
@@ -7,6 +7,7 @@ import { DataCorruptionError, GenericError, UsageError, extractSafePropertiesFro
|
|
|
7
7
|
import { MessageType, SummaryType, } from "@fluidframework/protocol-definitions";
|
|
8
8
|
import { FlushMode, channelsTreeName, } from "@fluidframework/runtime-definitions";
|
|
9
9
|
import { addBlobToSummary, addTreeToSummary, createRootSummarizerNodeWithGC, RequestParser, create404Response, exceptionToResponse, requestFluidObject, responseToException, seqFromTree, calculateStats, } from "@fluidframework/runtime-utils";
|
|
10
|
+
import { GCDataBuilder } from "@fluidframework/garbage-collector";
|
|
10
11
|
import { v4 as uuid } from "uuid";
|
|
11
12
|
import { ContainerFluidHandleContext } from "./containerHandleContext";
|
|
12
13
|
import { FluidDataStoreRegistry } from "./dataStoreRegistry";
|
|
@@ -24,7 +25,7 @@ import { OrderedClientCollection, OrderedClientElection } from "./orderedClientE
|
|
|
24
25
|
import { SummarizerClientElection, summarizerClientType } from "./summarizerClientElection";
|
|
25
26
|
import { formExponentialFn, Throttler } from "./throttler";
|
|
26
27
|
import { RunWhileConnectedCoordinator } from "./runWhileConnectedCoordinator";
|
|
27
|
-
import { GarbageCollector, gcTreeKey, } from "./garbageCollection";
|
|
28
|
+
import { GarbageCollector, GCNodeType, gcTreeKey, } from "./garbageCollection";
|
|
28
29
|
import { channelToDataStore, isDataStoreAliasMessage, } from "./dataStore";
|
|
29
30
|
import { BindBatchTracker } from "./batchTracker";
|
|
30
31
|
import { OpTracker } from "./opTelemetry";
|
|
@@ -312,7 +313,7 @@ export class ScheduleManager {
|
|
|
312
313
|
assert(this.batchClientId === undefined, 0x2a2 /* "Batch is interrupted by other client op. Should be caught by trackPending()" */);
|
|
313
314
|
// This could be the beginning of a new batch or an individual message.
|
|
314
315
|
this.emitter.emit("batchBegin", message);
|
|
315
|
-
this.deltaScheduler.batchBegin();
|
|
316
|
+
this.deltaScheduler.batchBegin(message);
|
|
316
317
|
const batch = (_a = message === null || message === void 0 ? void 0 : message.metadata) === null || _a === void 0 ? void 0 : _a.batch;
|
|
317
318
|
if (batch) {
|
|
318
319
|
this.batchClientId = message.clientId;
|
|
@@ -332,7 +333,7 @@ export class ScheduleManager {
|
|
|
332
333
|
this.hitError = true;
|
|
333
334
|
this.batchClientId = undefined;
|
|
334
335
|
this.emitter.emit("batchEnd", error, message);
|
|
335
|
-
this.deltaScheduler.batchEnd();
|
|
336
|
+
this.deltaScheduler.batchEnd(message);
|
|
336
337
|
return;
|
|
337
338
|
}
|
|
338
339
|
const batch = (_a = message === null || message === void 0 ? void 0 : message.metadata) === null || _a === void 0 ? void 0 : _a.batch;
|
|
@@ -341,7 +342,7 @@ export class ScheduleManager {
|
|
|
341
342
|
if (this.batchClientId === undefined || batch === false) {
|
|
342
343
|
this.batchClientId = undefined;
|
|
343
344
|
this.emitter.emit("batchEnd", undefined, message);
|
|
344
|
-
this.deltaScheduler.batchEnd();
|
|
345
|
+
this.deltaScheduler.batchEnd(message);
|
|
345
346
|
return;
|
|
346
347
|
}
|
|
347
348
|
}
|
|
@@ -466,12 +467,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
466
467
|
this._maxOpSizeInBytes = ((_d = this.mc.config.getNumber(maxOpSizeInBytesKey)) !== null && _d !== void 0 ? _d : defaultMaxOpSizeInBytes);
|
|
467
468
|
this.maxConsecutiveReconnects = (_e = this.mc.config.getNumber(maxConsecutiveReconnectsKey)) !== null && _e !== void 0 ? _e : this.defaultMaxConsecutiveReconnects;
|
|
468
469
|
this._flushMode = runtimeOptions.flushMode;
|
|
469
|
-
this.garbageCollector = GarbageCollector.create(this, this.runtimeOptions.gcOptions, (
|
|
470
|
-
/**
|
|
471
|
-
* Returns the timestamp of the last message seen by this client. This is used by garbage collector as
|
|
472
|
-
* the current reference timestamp for tracking unreferenced objects.
|
|
473
|
-
*/
|
|
474
|
-
() => { var _a, _b, _c; return (_b = (_a = this.deltaManager.lastMessage) === null || _a === void 0 ? void 0 : _a.timestamp) !== null && _b !== void 0 ? _b : (_c = this.messageAtLastSummary) === null || _c === void 0 ? void 0 : _c.timestamp; }, () => { var _a; return (_a = this.messageAtLastSummary) === null || _a === void 0 ? void 0 : _a.timestamp; }, context.baseSnapshot, async (id) => readAndParse(this.storage, id), this.mc.logger, existing, metadata);
|
|
470
|
+
this.garbageCollector = GarbageCollector.create(this, this.runtimeOptions.gcOptions, (nodePath) => this.getGCNodePackagePath(nodePath), () => { var _a; return (_a = this.messageAtLastSummary) === null || _a === void 0 ? void 0 : _a.timestamp; }, context.baseSnapshot, async (id) => readAndParse(this.storage, id), this.mc.logger, existing, metadata);
|
|
475
471
|
const loadedFromSequenceNumber = this.deltaManager.initialSequenceNumber;
|
|
476
472
|
this.summarizerNode = createRootSummarizerNodeWithGC(ChildLogger.create(this.logger, "SummarizerNode"),
|
|
477
473
|
// Summarize function to call when summarize is called. Summarizer node always tracks summary state.
|
|
@@ -492,7 +488,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
492
488
|
if (this.context.baseSnapshot) {
|
|
493
489
|
this.summarizerNode.loadBaseSummaryWithoutDifferential(this.context.baseSnapshot);
|
|
494
490
|
}
|
|
495
|
-
this.dataStores = new DataStores(getSummaryForDatastores(context.baseSnapshot, metadata), this, (attachMsg) => this.submit(ContainerMessageType.Attach, attachMsg), (id, createParam) => (summarizeInternal, getGCDataFn, getBaseGCDetailsFn) => this.summarizerNode.createChild(summarizeInternal, id, createParam, undefined, getGCDataFn, getBaseGCDetailsFn), (id) => this.summarizerNode.deleteChild(id), this.mc.logger, async () => this.garbageCollector.
|
|
491
|
+
this.dataStores = new DataStores(getSummaryForDatastores(context.baseSnapshot, metadata), this, (attachMsg) => this.submit(ContainerMessageType.Attach, attachMsg), (id, createParam) => (summarizeInternal, getGCDataFn, getBaseGCDetailsFn) => this.summarizerNode.createChild(summarizeInternal, id, createParam, undefined, getGCDataFn, getBaseGCDetailsFn), (id) => this.summarizerNode.deleteChild(id), this.mc.logger, async () => this.garbageCollector.getBaseGCDetails(), (path, timestampMs, packagePath) => this.garbageCollector.nodeUpdated(path, "Changed", timestampMs, packagePath), new Map(dataStoreAliasMap), this.garbageCollector.writeDataAtRoot);
|
|
496
492
|
this.blobManager = new BlobManager(this.handleContext, blobManagerSnapshot, () => this.storage, (blobId) => this.submit(ContainerMessageType.BlobAttach, undefined, undefined, { blobId }), this, this.logger);
|
|
497
493
|
this.scheduleManager = new ScheduleManager(context.deltaManager, this, ChildLogger.create(this.logger, "ScheduleManager"));
|
|
498
494
|
this.deltaSender = this.deltaManager;
|
|
@@ -1163,7 +1159,14 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1163
1159
|
*/
|
|
1164
1160
|
async createRootDataStoreLegacy(pkg, rootDataStoreId) {
|
|
1165
1161
|
const fluidDataStore = await this._createDataStore(pkg, true /* isRoot */, rootDataStoreId);
|
|
1166
|
-
|
|
1162
|
+
// back-compat 0.59.1000 - makeVisibleAndAttachGraph was added in this version to IFluidDataStoreChannel. For
|
|
1163
|
+
// older versions, we still have to call bindToContext.
|
|
1164
|
+
if (fluidDataStore.makeVisibleAndAttachGraph !== undefined) {
|
|
1165
|
+
fluidDataStore.makeVisibleAndAttachGraph();
|
|
1166
|
+
}
|
|
1167
|
+
else {
|
|
1168
|
+
fluidDataStore.bindToContext();
|
|
1169
|
+
}
|
|
1167
1170
|
return fluidDataStore;
|
|
1168
1171
|
}
|
|
1169
1172
|
async createRootDataStore(pkg, rootDataStoreId) {
|
|
@@ -1217,7 +1220,14 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1217
1220
|
async _createDataStoreWithPropsLegacy(pkg, props, id = uuid(), isRoot = false) {
|
|
1218
1221
|
const fluidDataStore = await this.dataStores._createFluidDataStoreContext(Array.isArray(pkg) ? pkg : [pkg], id, isRoot, props).realize();
|
|
1219
1222
|
if (isRoot) {
|
|
1220
|
-
|
|
1223
|
+
// back-compat 0.59.1000 - makeVisibleAndAttachGraph was added in this version to IFluidDataStoreChannel.
|
|
1224
|
+
// For older versions, we still have to call bindToContext.
|
|
1225
|
+
if (fluidDataStore.makeVisibleAndAttachGraph !== undefined) {
|
|
1226
|
+
fluidDataStore.makeVisibleAndAttachGraph();
|
|
1227
|
+
}
|
|
1228
|
+
else {
|
|
1229
|
+
fluidDataStore.bindToContext();
|
|
1230
|
+
}
|
|
1221
1231
|
this.logger.sendTelemetryEvent({
|
|
1222
1232
|
eventName: "Root datastore with props",
|
|
1223
1233
|
hasProps: props !== undefined,
|
|
@@ -1364,7 +1374,12 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1364
1374
|
* @param fullGC - true to bypass optimizations and force full generation of GC data.
|
|
1365
1375
|
*/
|
|
1366
1376
|
async getGCData(fullGC) {
|
|
1367
|
-
|
|
1377
|
+
const builder = new GCDataBuilder();
|
|
1378
|
+
const dsGCData = await this.dataStores.getGCData(fullGC);
|
|
1379
|
+
builder.addNodes(dsGCData.gcNodes);
|
|
1380
|
+
const blobsGCData = this.blobManager.getGCData(fullGC);
|
|
1381
|
+
builder.addNodes(blobsGCData.gcNodes);
|
|
1382
|
+
return builder.getGCData();
|
|
1368
1383
|
}
|
|
1369
1384
|
/**
|
|
1370
1385
|
* Implementation of IGarbageCollectionRuntime::updateUsedRoutes.
|
|
@@ -1378,7 +1393,78 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1378
1393
|
// summarizing is required and asserted by the the summarizer node. We are the root and are
|
|
1379
1394
|
// always referenced, so the used routes is only self-route (empty string).
|
|
1380
1395
|
this.summarizerNode.updateUsedRoutes([""]);
|
|
1381
|
-
|
|
1396
|
+
const dataStoreUsedRoutes = [];
|
|
1397
|
+
for (const route of usedRoutes) {
|
|
1398
|
+
if (route.split("/")[1] !== BlobManager.basePath) {
|
|
1399
|
+
dataStoreUsedRoutes.push(route);
|
|
1400
|
+
}
|
|
1401
|
+
}
|
|
1402
|
+
return this.dataStores.updateUsedRoutes(dataStoreUsedRoutes, gcTimestamp);
|
|
1403
|
+
}
|
|
1404
|
+
/**
|
|
1405
|
+
* When running GC in test mode, this is called to delete objects whose routes are unused. This enables testing
|
|
1406
|
+
* scenarios with accessing deleted content.
|
|
1407
|
+
* @param unusedRoutes - The routes that are unused in all data stores in this Container.
|
|
1408
|
+
*/
|
|
1409
|
+
deleteUnusedRoutes(unusedRoutes) {
|
|
1410
|
+
const blobManagerUnusedRoutes = [];
|
|
1411
|
+
const dataStoreUnusedRoutes = [];
|
|
1412
|
+
for (const route of unusedRoutes) {
|
|
1413
|
+
if (this.isBlobPath(route)) {
|
|
1414
|
+
blobManagerUnusedRoutes.push(route);
|
|
1415
|
+
}
|
|
1416
|
+
else {
|
|
1417
|
+
dataStoreUnusedRoutes.push(route);
|
|
1418
|
+
}
|
|
1419
|
+
}
|
|
1420
|
+
this.blobManager.deleteUnusedRoutes(blobManagerUnusedRoutes);
|
|
1421
|
+
this.dataStores.deleteUnusedRoutes(dataStoreUnusedRoutes);
|
|
1422
|
+
}
|
|
1423
|
+
/**
|
|
1424
|
+
* Returns a server generated referenced timestamp to be used to track unreferenced nodes by GC.
|
|
1425
|
+
*/
|
|
1426
|
+
getCurrentReferenceTimestampMs() {
|
|
1427
|
+
var _a, _b, _c;
|
|
1428
|
+
// Use the timestamp of the last message seen by this client as that is server generated. If no messages have
|
|
1429
|
+
// been processed, use the timestamp of the message from the last summary.
|
|
1430
|
+
return (_b = (_a = this.deltaManager.lastMessage) === null || _a === void 0 ? void 0 : _a.timestamp) !== null && _b !== void 0 ? _b : (_c = this.messageAtLastSummary) === null || _c === void 0 ? void 0 : _c.timestamp;
|
|
1431
|
+
}
|
|
1432
|
+
/**
|
|
1433
|
+
* Returns the type of the GC node. Currently, there are nodes that belong to data store and nodes that belong
|
|
1434
|
+
* to the blob manager.
|
|
1435
|
+
*/
|
|
1436
|
+
getNodeType(nodePath) {
|
|
1437
|
+
if (this.isBlobPath(nodePath)) {
|
|
1438
|
+
return GCNodeType.Blob;
|
|
1439
|
+
}
|
|
1440
|
+
if (this.dataStores.isDataStoreNode(nodePath)) {
|
|
1441
|
+
return GCNodeType.DataStore;
|
|
1442
|
+
}
|
|
1443
|
+
// Root node ("/") and DDS nodes belong to "Other" node types.
|
|
1444
|
+
return GCNodeType.Other;
|
|
1445
|
+
}
|
|
1446
|
+
/**
|
|
1447
|
+
* Called by GC to retrieve the package path of the node with the given path. The node should belong to a
|
|
1448
|
+
* data store or an attachment blob.
|
|
1449
|
+
*/
|
|
1450
|
+
getGCNodePackagePath(nodePath) {
|
|
1451
|
+
// If the node is a blob, return "_blobs" as the package path.
|
|
1452
|
+
if (this.isBlobPath(nodePath)) {
|
|
1453
|
+
return ["_blobs"];
|
|
1454
|
+
}
|
|
1455
|
+
const dataStorePkgPath = this.dataStores.getDataStorePackagePath(nodePath);
|
|
1456
|
+
assert(dataStorePkgPath !== undefined, 0x2d6 /* "Package path requested for unknown node type." */);
|
|
1457
|
+
return dataStorePkgPath;
|
|
1458
|
+
}
|
|
1459
|
+
/**
|
|
1460
|
+
* Returns whether a given path is for attachment blobs that are in the format - "/BlobManager.basePath/...".
|
|
1461
|
+
*/
|
|
1462
|
+
isBlobPath(path) {
|
|
1463
|
+
const pathParts = path.split("/");
|
|
1464
|
+
if (pathParts.length < 2 || pathParts[1] !== BlobManager.basePath) {
|
|
1465
|
+
return false;
|
|
1466
|
+
}
|
|
1467
|
+
return true;
|
|
1382
1468
|
}
|
|
1383
1469
|
/**
|
|
1384
1470
|
* Runs garbage collection and updates the reference / used state of the nodes in the container.
|