@fluidframework/container-runtime 0.58.3000-61081 → 0.59.2000-61729

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.
Files changed (93) hide show
  1. package/dist/blobManager.d.ts +13 -1
  2. package/dist/blobManager.d.ts.map +1 -1
  3. package/dist/blobManager.js +52 -0
  4. package/dist/blobManager.js.map +1 -1
  5. package/dist/connectionTelemetry.js +8 -8
  6. package/dist/connectionTelemetry.js.map +1 -1
  7. package/dist/containerRuntime.d.ts +27 -3
  8. package/dist/containerRuntime.d.ts.map +1 -1
  9. package/dist/containerRuntime.js +100 -14
  10. package/dist/containerRuntime.js.map +1 -1
  11. package/dist/dataStore.js +8 -1
  12. package/dist/dataStore.js.map +1 -1
  13. package/dist/dataStoreContext.d.ts +9 -3
  14. package/dist/dataStoreContext.d.ts.map +1 -1
  15. package/dist/dataStoreContext.js +22 -6
  16. package/dist/dataStoreContext.js.map +1 -1
  17. package/dist/dataStores.d.ts +13 -5
  18. package/dist/dataStores.d.ts.map +1 -1
  19. package/dist/dataStores.js +39 -18
  20. package/dist/dataStores.js.map +1 -1
  21. package/dist/deltaScheduler.d.ts +4 -5
  22. package/dist/deltaScheduler.d.ts.map +1 -1
  23. package/dist/deltaScheduler.js +54 -35
  24. package/dist/deltaScheduler.js.map +1 -1
  25. package/dist/garbageCollection.d.ts +31 -27
  26. package/dist/garbageCollection.d.ts.map +1 -1
  27. package/dist/garbageCollection.js +76 -75
  28. package/dist/garbageCollection.js.map +1 -1
  29. package/dist/orderedClientElection.d.ts.map +1 -1
  30. package/dist/orderedClientElection.js +2 -2
  31. package/dist/orderedClientElection.js.map +1 -1
  32. package/dist/packageVersion.d.ts +1 -1
  33. package/dist/packageVersion.js +1 -1
  34. package/dist/packageVersion.js.map +1 -1
  35. package/dist/summarizerClientElection.d.ts.map +1 -1
  36. package/dist/summarizerClientElection.js +8 -0
  37. package/dist/summarizerClientElection.js.map +1 -1
  38. package/dist/summaryGenerator.d.ts.map +1 -1
  39. package/dist/summaryGenerator.js +2 -3
  40. package/dist/summaryGenerator.js.map +1 -1
  41. package/lib/blobManager.d.ts +13 -1
  42. package/lib/blobManager.d.ts.map +1 -1
  43. package/lib/blobManager.js +52 -0
  44. package/lib/blobManager.js.map +1 -1
  45. package/lib/connectionTelemetry.js +8 -8
  46. package/lib/connectionTelemetry.js.map +1 -1
  47. package/lib/containerRuntime.d.ts +27 -3
  48. package/lib/containerRuntime.d.ts.map +1 -1
  49. package/lib/containerRuntime.js +101 -15
  50. package/lib/containerRuntime.js.map +1 -1
  51. package/lib/dataStore.js +8 -1
  52. package/lib/dataStore.js.map +1 -1
  53. package/lib/dataStoreContext.d.ts +9 -3
  54. package/lib/dataStoreContext.d.ts.map +1 -1
  55. package/lib/dataStoreContext.js +22 -6
  56. package/lib/dataStoreContext.js.map +1 -1
  57. package/lib/dataStores.d.ts +13 -5
  58. package/lib/dataStores.d.ts.map +1 -1
  59. package/lib/dataStores.js +39 -18
  60. package/lib/dataStores.js.map +1 -1
  61. package/lib/deltaScheduler.d.ts +4 -5
  62. package/lib/deltaScheduler.d.ts.map +1 -1
  63. package/lib/deltaScheduler.js +54 -35
  64. package/lib/deltaScheduler.js.map +1 -1
  65. package/lib/garbageCollection.d.ts +31 -27
  66. package/lib/garbageCollection.d.ts.map +1 -1
  67. package/lib/garbageCollection.js +75 -74
  68. package/lib/garbageCollection.js.map +1 -1
  69. package/lib/orderedClientElection.d.ts.map +1 -1
  70. package/lib/orderedClientElection.js +2 -2
  71. package/lib/orderedClientElection.js.map +1 -1
  72. package/lib/packageVersion.d.ts +1 -1
  73. package/lib/packageVersion.js +1 -1
  74. package/lib/packageVersion.js.map +1 -1
  75. package/lib/summarizerClientElection.d.ts.map +1 -1
  76. package/lib/summarizerClientElection.js +8 -0
  77. package/lib/summarizerClientElection.js.map +1 -1
  78. package/lib/summaryGenerator.d.ts.map +1 -1
  79. package/lib/summaryGenerator.js +2 -3
  80. package/lib/summaryGenerator.js.map +1 -1
  81. package/package.json +33 -21
  82. package/src/blobManager.ts +60 -1
  83. package/src/connectionTelemetry.ts +9 -9
  84. package/src/containerRuntime.ts +106 -17
  85. package/src/dataStore.ts +7 -1
  86. package/src/dataStoreContext.ts +22 -7
  87. package/src/dataStores.ts +40 -19
  88. package/src/deltaScheduler.ts +65 -39
  89. package/src/garbageCollection.ts +92 -78
  90. package/src/orderedClientElection.ts +2 -1
  91. package/src/packageVersion.ts +1 -1
  92. package/src/summarizerClientElection.ts +8 -0
  93. package/src/summaryGenerator.ts +1 -7
@@ -10,6 +10,7 @@ const container_utils_1 = require("@fluidframework/container-utils");
10
10
  const protocol_definitions_1 = require("@fluidframework/protocol-definitions");
11
11
  const runtime_definitions_1 = require("@fluidframework/runtime-definitions");
12
12
  const runtime_utils_1 = require("@fluidframework/runtime-utils");
13
+ const garbage_collector_1 = require("@fluidframework/garbage-collector");
13
14
  const uuid_1 = require("uuid");
14
15
  const containerHandleContext_1 = require("./containerHandleContext");
15
16
  const dataStoreRegistry_1 = require("./dataStoreRegistry");
@@ -317,7 +318,7 @@ class ScheduleManager {
317
318
  common_utils_1.assert(this.batchClientId === undefined, 0x2a2 /* "Batch is interrupted by other client op. Should be caught by trackPending()" */);
318
319
  // This could be the beginning of a new batch or an individual message.
319
320
  this.emitter.emit("batchBegin", message);
320
- this.deltaScheduler.batchBegin();
321
+ this.deltaScheduler.batchBegin(message);
321
322
  const batch = (_a = message === null || message === void 0 ? void 0 : message.metadata) === null || _a === void 0 ? void 0 : _a.batch;
322
323
  if (batch) {
323
324
  this.batchClientId = message.clientId;
@@ -337,7 +338,7 @@ class ScheduleManager {
337
338
  this.hitError = true;
338
339
  this.batchClientId = undefined;
339
340
  this.emitter.emit("batchEnd", error, message);
340
- this.deltaScheduler.batchEnd();
341
+ this.deltaScheduler.batchEnd(message);
341
342
  return;
342
343
  }
343
344
  const batch = (_a = message === null || message === void 0 ? void 0 : message.metadata) === null || _a === void 0 ? void 0 : _a.batch;
@@ -346,7 +347,7 @@ class ScheduleManager {
346
347
  if (this.batchClientId === undefined || batch === false) {
347
348
  this.batchClientId = undefined;
348
349
  this.emitter.emit("batchEnd", undefined, message);
349
- this.deltaScheduler.batchEnd();
350
+ this.deltaScheduler.batchEnd(message);
350
351
  return;
351
352
  }
352
353
  }
@@ -473,12 +474,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
473
474
  this._maxOpSizeInBytes = ((_d = this.mc.config.getNumber(maxOpSizeInBytesKey)) !== null && _d !== void 0 ? _d : defaultMaxOpSizeInBytes);
474
475
  this.maxConsecutiveReconnects = (_e = this.mc.config.getNumber(maxConsecutiveReconnectsKey)) !== null && _e !== void 0 ? _e : this.defaultMaxConsecutiveReconnects;
475
476
  this._flushMode = runtimeOptions.flushMode;
476
- this.garbageCollector = garbageCollection_1.GarbageCollector.create(this, this.runtimeOptions.gcOptions, (unusedRoutes) => this.dataStores.deleteUnusedRoutes(unusedRoutes), (nodePath) => this.dataStores.getNodePackagePath(nodePath),
477
- /**
478
- * Returns the timestamp of the last message seen by this client. This is used by garbage collector as
479
- * the current reference timestamp for tracking unreferenced objects.
480
- */
481
- () => { 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) => driver_utils_1.readAndParse(this.storage, id), this.mc.logger, existing, metadata);
477
+ this.garbageCollector = garbageCollection_1.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) => driver_utils_1.readAndParse(this.storage, id), this.mc.logger, existing, metadata);
482
478
  const loadedFromSequenceNumber = this.deltaManager.initialSequenceNumber;
483
479
  this.summarizerNode = runtime_utils_1.createRootSummarizerNodeWithGC(telemetry_utils_1.ChildLogger.create(this.logger, "SummarizerNode"),
484
480
  // Summarize function to call when summarize is called. Summarizer node always tracks summary state.
@@ -499,7 +495,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
499
495
  if (this.context.baseSnapshot) {
500
496
  this.summarizerNode.loadBaseSummaryWithoutDifferential(this.context.baseSnapshot);
501
497
  }
502
- this.dataStores = new dataStores_1.DataStores(dataStores_1.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.getDataStoreBaseGCDetails(), (path, timestampMs, packagePath) => this.garbageCollector.nodeUpdated(path, "Changed", timestampMs, packagePath), new Map(dataStoreAliasMap), this.garbageCollector.writeDataAtRoot);
498
+ this.dataStores = new dataStores_1.DataStores(dataStores_1.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);
503
499
  this.blobManager = new blobManager_1.BlobManager(this.handleContext, blobManagerSnapshot, () => this.storage, (blobId) => this.submit(ContainerMessageType.BlobAttach, undefined, undefined, { blobId }), this, this.logger);
504
500
  this.scheduleManager = new ScheduleManager(context.deltaManager, this, telemetry_utils_1.ChildLogger.create(this.logger, "ScheduleManager"));
505
501
  this.deltaSender = this.deltaManager;
@@ -1170,7 +1166,14 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1170
1166
  */
1171
1167
  async createRootDataStoreLegacy(pkg, rootDataStoreId) {
1172
1168
  const fluidDataStore = await this._createDataStore(pkg, true /* isRoot */, rootDataStoreId);
1173
- fluidDataStore.bindToContext();
1169
+ // back-compat 0.59.1000 - makeVisibleAndAttachGraph was added in this version to IFluidDataStoreChannel. For
1170
+ // older versions, we still have to call bindToContext.
1171
+ if (fluidDataStore.makeVisibleAndAttachGraph !== undefined) {
1172
+ fluidDataStore.makeVisibleAndAttachGraph();
1173
+ }
1174
+ else {
1175
+ fluidDataStore.bindToContext();
1176
+ }
1174
1177
  return fluidDataStore;
1175
1178
  }
1176
1179
  async createRootDataStore(pkg, rootDataStoreId) {
@@ -1224,7 +1227,14 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1224
1227
  async _createDataStoreWithPropsLegacy(pkg, props, id = uuid_1.v4(), isRoot = false) {
1225
1228
  const fluidDataStore = await this.dataStores._createFluidDataStoreContext(Array.isArray(pkg) ? pkg : [pkg], id, isRoot, props).realize();
1226
1229
  if (isRoot) {
1227
- fluidDataStore.bindToContext();
1230
+ // back-compat 0.59.1000 - makeVisibleAndAttachGraph was added in this version to IFluidDataStoreChannel.
1231
+ // For older versions, we still have to call bindToContext.
1232
+ if (fluidDataStore.makeVisibleAndAttachGraph !== undefined) {
1233
+ fluidDataStore.makeVisibleAndAttachGraph();
1234
+ }
1235
+ else {
1236
+ fluidDataStore.bindToContext();
1237
+ }
1228
1238
  this.logger.sendTelemetryEvent({
1229
1239
  eventName: "Root datastore with props",
1230
1240
  hasProps: props !== undefined,
@@ -1371,7 +1381,12 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1371
1381
  * @param fullGC - true to bypass optimizations and force full generation of GC data.
1372
1382
  */
1373
1383
  async getGCData(fullGC) {
1374
- return this.dataStores.getGCData(fullGC);
1384
+ const builder = new garbage_collector_1.GCDataBuilder();
1385
+ const dsGCData = await this.dataStores.getGCData(fullGC);
1386
+ builder.addNodes(dsGCData.gcNodes);
1387
+ const blobsGCData = this.blobManager.getGCData(fullGC);
1388
+ builder.addNodes(blobsGCData.gcNodes);
1389
+ return builder.getGCData();
1375
1390
  }
1376
1391
  /**
1377
1392
  * Implementation of IGarbageCollectionRuntime::updateUsedRoutes.
@@ -1385,7 +1400,78 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1385
1400
  // summarizing is required and asserted by the the summarizer node. We are the root and are
1386
1401
  // always referenced, so the used routes is only self-route (empty string).
1387
1402
  this.summarizerNode.updateUsedRoutes([""]);
1388
- return this.dataStores.updateUsedRoutes(usedRoutes, gcTimestamp);
1403
+ const dataStoreUsedRoutes = [];
1404
+ for (const route of usedRoutes) {
1405
+ if (route.split("/")[1] !== blobManager_1.BlobManager.basePath) {
1406
+ dataStoreUsedRoutes.push(route);
1407
+ }
1408
+ }
1409
+ return this.dataStores.updateUsedRoutes(dataStoreUsedRoutes, gcTimestamp);
1410
+ }
1411
+ /**
1412
+ * When running GC in test mode, this is called to delete objects whose routes are unused. This enables testing
1413
+ * scenarios with accessing deleted content.
1414
+ * @param unusedRoutes - The routes that are unused in all data stores in this Container.
1415
+ */
1416
+ deleteUnusedRoutes(unusedRoutes) {
1417
+ const blobManagerUnusedRoutes = [];
1418
+ const dataStoreUnusedRoutes = [];
1419
+ for (const route of unusedRoutes) {
1420
+ if (this.isBlobPath(route)) {
1421
+ blobManagerUnusedRoutes.push(route);
1422
+ }
1423
+ else {
1424
+ dataStoreUnusedRoutes.push(route);
1425
+ }
1426
+ }
1427
+ this.blobManager.deleteUnusedRoutes(blobManagerUnusedRoutes);
1428
+ this.dataStores.deleteUnusedRoutes(dataStoreUnusedRoutes);
1429
+ }
1430
+ /**
1431
+ * Returns a server generated referenced timestamp to be used to track unreferenced nodes by GC.
1432
+ */
1433
+ getCurrentReferenceTimestampMs() {
1434
+ var _a, _b, _c;
1435
+ // Use the timestamp of the last message seen by this client as that is server generated. If no messages have
1436
+ // been processed, use the timestamp of the message from the last summary.
1437
+ 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;
1438
+ }
1439
+ /**
1440
+ * Returns the type of the GC node. Currently, there are nodes that belong to data store and nodes that belong
1441
+ * to the blob manager.
1442
+ */
1443
+ getNodeType(nodePath) {
1444
+ if (this.isBlobPath(nodePath)) {
1445
+ return garbageCollection_1.GCNodeType.Blob;
1446
+ }
1447
+ if (this.dataStores.isDataStoreNode(nodePath)) {
1448
+ return garbageCollection_1.GCNodeType.DataStore;
1449
+ }
1450
+ // Root node ("/") and DDS nodes belong to "Other" node types.
1451
+ return garbageCollection_1.GCNodeType.Other;
1452
+ }
1453
+ /**
1454
+ * Called by GC to retrieve the package path of the node with the given path. The node should belong to a
1455
+ * data store or an attachment blob.
1456
+ */
1457
+ getGCNodePackagePath(nodePath) {
1458
+ // If the node is a blob, return "_blobs" as the package path.
1459
+ if (this.isBlobPath(nodePath)) {
1460
+ return ["_blobs"];
1461
+ }
1462
+ const dataStorePkgPath = this.dataStores.getDataStorePackagePath(nodePath);
1463
+ common_utils_1.assert(dataStorePkgPath !== undefined, 0x2d6 /* "Package path requested for unknown node type." */);
1464
+ return dataStorePkgPath;
1465
+ }
1466
+ /**
1467
+ * Returns whether a given path is for attachment blobs that are in the format - "/BlobManager.basePath/...".
1468
+ */
1469
+ isBlobPath(path) {
1470
+ const pathParts = path.split("/");
1471
+ if (pathParts.length < 2 || pathParts[1] !== blobManager_1.BlobManager.basePath) {
1472
+ return false;
1473
+ }
1474
+ return true;
1389
1475
  }
1390
1476
  /**
1391
1477
  * Runs garbage collection and updates the reference / used state of the nodes in the container.