@fluidframework/container-runtime 0.52.0 → 0.54.0-47413

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 (132) hide show
  1. package/dist/containerHandleContext.d.ts +0 -1
  2. package/dist/containerHandleContext.d.ts.map +1 -1
  3. package/dist/containerHandleContext.js +0 -1
  4. package/dist/containerHandleContext.js.map +1 -1
  5. package/dist/containerRuntime.d.ts +43 -19
  6. package/dist/containerRuntime.d.ts.map +1 -1
  7. package/dist/containerRuntime.js +201 -111
  8. package/dist/containerRuntime.js.map +1 -1
  9. package/dist/dataStoreContext.d.ts +33 -4
  10. package/dist/dataStoreContext.d.ts.map +1 -1
  11. package/dist/dataStoreContext.js +45 -17
  12. package/dist/dataStoreContext.js.map +1 -1
  13. package/dist/dataStores.d.ts +14 -10
  14. package/dist/dataStores.d.ts.map +1 -1
  15. package/dist/dataStores.js +73 -41
  16. package/dist/dataStores.js.map +1 -1
  17. package/dist/garbageCollection.d.ts +82 -15
  18. package/dist/garbageCollection.d.ts.map +1 -1
  19. package/dist/garbageCollection.js +359 -26
  20. package/dist/garbageCollection.js.map +1 -1
  21. package/dist/index.d.ts +2 -2
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +11 -2
  24. package/dist/index.js.map +1 -1
  25. package/dist/packageVersion.d.ts +1 -1
  26. package/dist/packageVersion.d.ts.map +1 -1
  27. package/dist/packageVersion.js +1 -1
  28. package/dist/packageVersion.js.map +1 -1
  29. package/dist/pendingStateManager.d.ts +0 -1
  30. package/dist/pendingStateManager.d.ts.map +1 -1
  31. package/dist/pendingStateManager.js +0 -36
  32. package/dist/pendingStateManager.js.map +1 -1
  33. package/dist/runningSummarizer.d.ts +3 -2
  34. package/dist/runningSummarizer.d.ts.map +1 -1
  35. package/dist/runningSummarizer.js +6 -6
  36. package/dist/runningSummarizer.js.map +1 -1
  37. package/dist/summarizer.d.ts +23 -3
  38. package/dist/summarizer.d.ts.map +1 -1
  39. package/dist/summarizer.js +135 -45
  40. package/dist/summarizer.js.map +1 -1
  41. package/dist/summarizerTypes.d.ts +3 -10
  42. package/dist/summarizerTypes.d.ts.map +1 -1
  43. package/dist/summarizerTypes.js.map +1 -1
  44. package/dist/summaryFormat.d.ts +10 -1
  45. package/dist/summaryFormat.d.ts.map +1 -1
  46. package/dist/summaryFormat.js +2 -1
  47. package/dist/summaryFormat.js.map +1 -1
  48. package/dist/summaryGenerator.d.ts.map +1 -1
  49. package/dist/summaryGenerator.js +1 -3
  50. package/dist/summaryGenerator.js.map +1 -1
  51. package/dist/summaryManager.d.ts +0 -15
  52. package/dist/summaryManager.d.ts.map +1 -1
  53. package/dist/summaryManager.js +1 -35
  54. package/dist/summaryManager.js.map +1 -1
  55. package/lib/containerHandleContext.d.ts +0 -1
  56. package/lib/containerHandleContext.d.ts.map +1 -1
  57. package/lib/containerHandleContext.js +0 -1
  58. package/lib/containerHandleContext.js.map +1 -1
  59. package/lib/containerRuntime.d.ts +43 -19
  60. package/lib/containerRuntime.d.ts.map +1 -1
  61. package/lib/containerRuntime.js +206 -117
  62. package/lib/containerRuntime.js.map +1 -1
  63. package/lib/dataStoreContext.d.ts +33 -4
  64. package/lib/dataStoreContext.d.ts.map +1 -1
  65. package/lib/dataStoreContext.js +45 -17
  66. package/lib/dataStoreContext.js.map +1 -1
  67. package/lib/dataStores.d.ts +14 -10
  68. package/lib/dataStores.d.ts.map +1 -1
  69. package/lib/dataStores.js +76 -44
  70. package/lib/dataStores.js.map +1 -1
  71. package/lib/garbageCollection.d.ts +82 -15
  72. package/lib/garbageCollection.d.ts.map +1 -1
  73. package/lib/garbageCollection.js +361 -28
  74. package/lib/garbageCollection.js.map +1 -1
  75. package/lib/index.d.ts +2 -2
  76. package/lib/index.d.ts.map +1 -1
  77. package/lib/index.js +2 -1
  78. package/lib/index.js.map +1 -1
  79. package/lib/packageVersion.d.ts +1 -1
  80. package/lib/packageVersion.d.ts.map +1 -1
  81. package/lib/packageVersion.js +1 -1
  82. package/lib/packageVersion.js.map +1 -1
  83. package/lib/pendingStateManager.d.ts +0 -1
  84. package/lib/pendingStateManager.d.ts.map +1 -1
  85. package/lib/pendingStateManager.js +0 -36
  86. package/lib/pendingStateManager.js.map +1 -1
  87. package/lib/runningSummarizer.d.ts +3 -2
  88. package/lib/runningSummarizer.d.ts.map +1 -1
  89. package/lib/runningSummarizer.js +6 -6
  90. package/lib/runningSummarizer.js.map +1 -1
  91. package/lib/summarizer.d.ts +23 -3
  92. package/lib/summarizer.d.ts.map +1 -1
  93. package/lib/summarizer.js +135 -45
  94. package/lib/summarizer.js.map +1 -1
  95. package/lib/summarizerTypes.d.ts +3 -10
  96. package/lib/summarizerTypes.d.ts.map +1 -1
  97. package/lib/summarizerTypes.js.map +1 -1
  98. package/lib/summaryFormat.d.ts +10 -1
  99. package/lib/summaryFormat.d.ts.map +1 -1
  100. package/lib/summaryFormat.js +1 -0
  101. package/lib/summaryFormat.js.map +1 -1
  102. package/lib/summaryGenerator.d.ts.map +1 -1
  103. package/lib/summaryGenerator.js +1 -3
  104. package/lib/summaryGenerator.js.map +1 -1
  105. package/lib/summaryManager.d.ts +0 -15
  106. package/lib/summaryManager.d.ts.map +1 -1
  107. package/lib/summaryManager.js +1 -34
  108. package/lib/summaryManager.js.map +1 -1
  109. package/package.json +14 -14
  110. package/src/containerHandleContext.ts +0 -1
  111. package/src/containerRuntime.ts +280 -140
  112. package/src/dataStoreContext.ts +59 -20
  113. package/src/dataStores.ts +116 -54
  114. package/src/garbageCollection.ts +492 -29
  115. package/src/index.ts +20 -2
  116. package/src/packageVersion.ts +1 -1
  117. package/src/pendingStateManager.ts +0 -43
  118. package/src/runningSummarizer.ts +12 -10
  119. package/src/summarizer.ts +154 -53
  120. package/src/summarizerTypes.ts +3 -11
  121. package/src/summaryFormat.ts +11 -1
  122. package/src/summaryGenerator.ts +2 -3
  123. package/src/summaryManager.ts +2 -49
  124. package/dist/localStorageFeatureGates.d.ts +0 -13
  125. package/dist/localStorageFeatureGates.d.ts.map +0 -1
  126. package/dist/localStorageFeatureGates.js +0 -31
  127. package/dist/localStorageFeatureGates.js.map +0 -1
  128. package/lib/localStorageFeatureGates.d.ts +0 -13
  129. package/lib/localStorageFeatureGates.d.ts.map +0 -1
  130. package/lib/localStorageFeatureGates.js +0 -27
  131. package/lib/localStorageFeatureGates.js.map +0 -1
  132. package/src/localStorageFeatureGates.ts +0 -27
@@ -4,13 +4,13 @@
4
4
  * Licensed under the MIT License.
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.ContainerRuntime = exports.agentSchedulerId = exports.ScheduleManager = exports.unpackRuntimeMessage = exports.isRuntimeMessage = exports.ContainerMessageType = void 0;
7
+ exports.ContainerRuntime = exports.getDeviceSpec = exports.agentSchedulerId = exports.ScheduleManager = exports.unpackRuntimeMessage = exports.isRuntimeMessage = exports.ContainerMessageType = void 0;
8
8
  const container_definitions_1 = require("@fluidframework/container-definitions");
9
9
  const common_utils_1 = require("@fluidframework/common-utils");
10
10
  const telemetry_utils_1 = require("@fluidframework/telemetry-utils");
11
+ const driver_definitions_1 = require("@fluidframework/driver-definitions");
11
12
  const driver_utils_1 = require("@fluidframework/driver-utils");
12
13
  const container_utils_1 = require("@fluidframework/container-utils");
13
- const protocol_base_1 = require("@fluidframework/protocol-base");
14
14
  const protocol_definitions_1 = require("@fluidframework/protocol-definitions");
15
15
  const runtime_definitions_1 = require("@fluidframework/runtime-definitions");
16
16
  const runtime_utils_1 = require("@fluidframework/runtime-utils");
@@ -27,7 +27,6 @@ const blobManager_1 = require("./blobManager");
27
27
  const dataStores_1 = require("./dataStores");
28
28
  const summaryFormat_1 = require("./summaryFormat");
29
29
  const summaryCollection_1 = require("./summaryCollection");
30
- const localStorageFeatureGates_1 = require("./localStorageFeatureGates");
31
30
  const orderedClientElection_1 = require("./orderedClientElection");
32
31
  const summarizerClientElection_1 = require("./summarizerClientElection");
33
32
  const throttler_1 = require("./throttler");
@@ -45,6 +44,8 @@ var ContainerMessageType;
45
44
  ContainerMessageType["BlobAttach"] = "blobAttach";
46
45
  // Ties our new clientId to our old one on reconnect
47
46
  ContainerMessageType["Rejoin"] = "rejoin";
47
+ // Sets the alias of a root data store
48
+ ContainerMessageType["Alias"] = "alias";
48
49
  })(ContainerMessageType = exports.ContainerMessageType || (exports.ContainerMessageType = {}));
49
50
  // Consider idle 5s of no activity. And snapshot if a minute has gone by with no snapshot.
50
51
  const IdleDetectionTime = 5000;
@@ -59,12 +60,13 @@ const DefaultSummaryConfiguration = {
59
60
  maxAckWaitTime: 120000,
60
61
  };
61
62
  // Local storage key to set the default flush mode to TurnBased
62
- const turnBasedFlushModeKey = "FluidFlushModeTurnBased";
63
+ const turnBasedFlushModeKey = "Fluid.ContainerRuntime.FlushModeTurnBased";
63
64
  function isRuntimeMessage(message) {
64
65
  switch (message.type) {
65
66
  case ContainerMessageType.FluidDataStoreOp:
66
67
  case ContainerMessageType.ChunkedOp:
67
68
  case ContainerMessageType.Attach:
69
+ case ContainerMessageType.Alias:
68
70
  case ContainerMessageType.BlobAttach:
69
71
  case ContainerMessageType.Rejoin:
70
72
  case protocol_definitions_1.MessageType.Operation:
@@ -312,13 +314,28 @@ exports.ScheduleManager = ScheduleManager;
312
314
  * ContainerRuntime's perspective.
313
315
  */
314
316
  exports.agentSchedulerId = "_scheduler";
317
+ // safely check navigator and get the hardware spec value
318
+ function getDeviceSpec() {
319
+ try {
320
+ if (typeof navigator === "object" && navigator !== null) {
321
+ return {
322
+ deviceMemory: navigator.deviceMemory,
323
+ hardwareConcurrency: navigator.hardwareConcurrency,
324
+ };
325
+ }
326
+ }
327
+ catch (_a) {
328
+ }
329
+ return {};
330
+ }
331
+ exports.getDeviceSpec = getDeviceSpec;
315
332
  /**
316
333
  * Represents the runtime of the container. Contains helper functions/state of the container.
317
334
  * It will define the store level mappings.
318
335
  */
319
336
  class ContainerRuntime extends common_utils_1.TypedEventEmitter {
320
- constructor(context, registry, metadata, electedSummarizerData, chunks, runtimeOptions, containerScope, logger, existing, blobManagerSnapshot, requestHandler, _storage) {
321
- var _a, _b, _c, _d;
337
+ constructor(context, registry, metadata, electedSummarizerData, chunks, dataStoreAliasMap, runtimeOptions, containerScope, logger, existing, blobManagerSnapshot, requestHandler, _storage) {
338
+ var _a, _b, _c, _d, _e;
322
339
  super();
323
340
  this.context = context;
324
341
  this.registry = registry;
@@ -327,14 +344,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
327
344
  this.logger = logger;
328
345
  this.requestHandler = requestHandler;
329
346
  this._storage = _storage;
330
- // back-compat: Used by loader in <= 0.35
331
- /**
332
- * @internal
333
- * @deprecated Back-compat only. Used by the loader in versions earlier than 0.35.
334
- */
335
- this.runtimeVersion = packageVersion_1.pkgVersion;
336
347
  this._orderSequentiallyCalls = 0;
337
- this._flushMode = ContainerRuntime.defaultFlushMode;
338
348
  this.needsFlush = false;
339
349
  this.flushTrigger = false;
340
350
  this.paused = false;
@@ -377,7 +387,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
377
387
  // If we're not the summarizer, and we don't have a summaryManager, we expect that
378
388
  // disableSummaries is turned on. We are throwing instead of returning a failure here,
379
389
  // because it is a misuse of the API rather than an expected failure.
380
- throw new Error(`Can't summarize, disableSummaries: ${this.summariesDisabled()}`);
390
+ throw new container_utils_1.UsageError(`Can't summarize, disableSummaries: ${this.summariesDisabled}`);
381
391
  }
382
392
  };
383
393
  this.enqueueSummarize = (...args) => {
@@ -391,18 +401,47 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
391
401
  // If we're not the summarizer, and we don't have a summaryManager, we expect that
392
402
  // generateSummaries is turned off. We are throwing instead of returning a failure here,
393
403
  // because it is a misuse of the API rather than an expected failure.
394
- throw new Error(`Can't summarize, disableSummaries: ${this.summariesDisabled()}`);
404
+ throw new container_utils_1.UsageError(`Can't summarize, disableSummaries: ${this.summariesDisabled}`);
395
405
  }
396
406
  };
397
407
  this.baseSummaryMessage = metadata === null || metadata === void 0 ? void 0 : metadata.message;
408
+ // If this is an existing container, we get values from metadata.
409
+ // otherwise, we initialize them.
410
+ if (existing) {
411
+ this.createContainerMetadata = {
412
+ createContainerRuntimeVersion: metadata === null || metadata === void 0 ? void 0 : metadata.createContainerRuntimeVersion,
413
+ createContainerTimestamp: metadata === null || metadata === void 0 ? void 0 : metadata.createContainerTimestamp,
414
+ };
415
+ this.summaryCount = metadata === null || metadata === void 0 ? void 0 : metadata.summaryCount;
416
+ }
417
+ else {
418
+ this.createContainerMetadata = {
419
+ createContainerRuntimeVersion: packageVersion_1.pkgVersion,
420
+ createContainerTimestamp: Date.now(),
421
+ };
422
+ }
398
423
  // Default to false (enabled).
399
424
  this.disableIsolatedChannels = (_a = this.runtimeOptions.summaryOptions.disableIsolatedChannels) !== null && _a !== void 0 ? _a : false;
400
425
  this._connected = this.context.connected;
401
426
  this.chunkMap = new Map(chunks);
402
- this.IFluidHandleContext = new containerHandleContext_1.ContainerFluidHandleContext("", this);
403
- this.IFluidSerializer = new runtime_utils_1.FluidSerializer(this.IFluidHandleContext);
404
- this._logger = telemetry_utils_1.ChildLogger.create(this.logger, "ContainerRuntime");
405
- this.garbageCollector = garbageCollection_1.GarbageCollector.create(this, this.runtimeOptions.gcOptions, (unusedRoutes) => this.dataStores.deleteUnusedRoutes(unusedRoutes), this._logger, existing, metadata);
427
+ this.handleContext = new containerHandleContext_1.ContainerFluidHandleContext("", this);
428
+ this.mc = telemetry_utils_1.loggerToMonitoringContext(telemetry_utils_1.ChildLogger.create(this.logger, "ContainerRuntime"));
429
+ this._flushMode =
430
+ ((_b = this.mc.config.getBoolean(turnBasedFlushModeKey)) !== null && _b !== void 0 ? _b : false) ? runtime_definitions_1.FlushMode.TurnBased : runtime_definitions_1.FlushMode.Immediate;
431
+ /**
432
+ * Function that return the current server timestamp. This is used by the garbage collector to set the
433
+ * time when a node becomes unreferenced.
434
+ * We use the timestamp of the last op for current timestamp. However, there can be cases where
435
+ * we don't have an op (on demand summaries for instance). In those cases, we will use the timestamp
436
+ * of this client's connection.
437
+ */
438
+ const getCurrentTimestamp = () => {
439
+ var _a, _b, _c;
440
+ const client = this.clientId !== undefined ? this.getAudience().getMember(this.clientId) : undefined;
441
+ const timestamp = client === null || client === void 0 ? void 0 : client.timestamp;
442
+ return (_c = (_b = (_a = this.deltaManager.lastMessage) === null || _a === void 0 ? void 0 : _a.timestamp) !== null && _b !== void 0 ? _b : timestamp) !== null && _c !== void 0 ? _c : Date.now();
443
+ };
444
+ this.garbageCollector = garbageCollection_1.GarbageCollector.create(this, this.runtimeOptions.gcOptions, (unusedRoutes) => this.dataStores.deleteUnusedRoutes(unusedRoutes), getCurrentTimestamp, context.baseSnapshot, async (id) => driver_utils_1.readAndParse(this.storage, id), this.mc.logger, existing, metadata);
406
445
  const loadedFromSequenceNumber = this.deltaManager.initialSequenceNumber;
407
446
  this.summarizerNode = runtime_utils_1.createRootSummarizerNodeWithGC(telemetry_utils_1.ChildLogger.create(this.logger, "SummarizerNode"),
408
447
  // Summarize function to call when summarize is called. Summarizer node always tracks summary state.
@@ -419,69 +458,58 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
419
458
  throwOnFailure: true,
420
459
  // If GC should not run, let the summarizer node know so that it does not track GC state.
421
460
  gcDisabled: !this.garbageCollector.shouldRunGC,
422
- // The max duration for which objects can be unreferenced before they are eligible for deletion.
423
- maxUnreferencedDurationMs: this.runtimeOptions.gcOptions.maxUnreferencedDurationMs,
424
461
  });
425
462
  if (this.context.baseSnapshot) {
426
463
  this.summarizerNode.loadBaseSummaryWithoutDifferential(this.context.baseSnapshot);
427
464
  }
428
- this.dataStores = new dataStores_1.DataStores(dataStores_1.getSummaryForDatastores(context.baseSnapshot, metadata), this, (attachMsg) => this.submit(ContainerMessageType.Attach, attachMsg), (id, createParam) => (summarizeInternal, getGCDataFn, getInitialGCSummaryDetailsFn) => this.summarizerNode.createChild(summarizeInternal, id, createParam, undefined, getGCDataFn, getInitialGCSummaryDetailsFn), (id) => this.summarizerNode.deleteChild(id), this._logger);
429
- this.blobManager = new blobManager_1.BlobManager(this.IFluidHandleContext, blobManagerSnapshot, () => this.storage, (blobId) => this.submit(ContainerMessageType.BlobAttach, undefined, undefined, { blobId }), this, this.logger);
465
+ this.dataStores = new dataStores_1.DataStores(dataStores_1.getSummaryForDatastores(context.baseSnapshot, metadata), this, (attachMsg) => this.submit(ContainerMessageType.Attach, attachMsg), (id, createParam) => (summarizeInternal, getGCDataFn, getInitialGCSummaryDetailsFn) => this.summarizerNode.createChild(summarizeInternal, id, createParam, undefined, getGCDataFn, getInitialGCSummaryDetailsFn), (id) => this.summarizerNode.deleteChild(id), this.mc.logger, async () => this.garbageCollector.getDataStoreBaseGCDetails(), (id) => this.garbageCollector.nodeChanged(id), new Map(dataStoreAliasMap));
466
+ this.blobManager = new blobManager_1.BlobManager(this.handleContext, blobManagerSnapshot, () => this.storage, (blobId) => this.submit(ContainerMessageType.BlobAttach, undefined, undefined, { blobId }), this, this.logger);
430
467
  this.scheduleManager = new ScheduleManager(context.deltaManager, this, telemetry_utils_1.ChildLogger.create(this.logger, "ScheduleManager"));
431
468
  this.deltaSender = this.deltaManager;
432
469
  this.pendingStateManager = new pendingStateManager_1.PendingStateManager(this, async (type, content) => this.applyStashedOp(type, content), context.pendingLocalState);
433
470
  this.context.quorum.on("removeMember", (clientId) => {
434
471
  this.clearPartialChunks(clientId);
435
472
  });
436
- this.context.quorum.on("addProposal", (proposal) => {
437
- if (proposal.key === "code" || proposal.key === "code2") {
438
- this.emit("codeDetailsProposed", proposal.value, proposal);
439
- }
440
- });
441
473
  this.summaryCollection = new summaryCollection_1.SummaryCollection(this.deltaManager, this.logger);
442
- // Only create a SummaryManager if summaries are enabled and we are not the summarizer client
443
474
  // Map the deprecated generateSummaries flag to disableSummaries.
444
475
  if (this.runtimeOptions.summaryOptions.generateSummaries === false) {
445
476
  this.runtimeOptions.summaryOptions.disableSummaries = true;
446
477
  }
447
- if (this.summariesDisabled()) {
448
- this._logger.sendTelemetryEvent({ eventName: "SummariesDisabled" });
478
+ if (this.summariesDisabled) {
479
+ this.mc.logger.sendTelemetryEvent({ eventName: "SummariesDisabled" });
449
480
  }
450
481
  else {
451
- const maxOpsSinceLastSummary = (_b = this.runtimeOptions.summaryOptions.maxOpsSinceLastSummary) !== null && _b !== void 0 ? _b : 7000;
452
- const defaultAction = () => {
453
- if (this.summaryCollection.opsSinceLastAck > maxOpsSinceLastSummary) {
454
- this.logger.sendErrorEvent({ eventName: "SummaryStatus:Behind" });
455
- // unregister default to no log on every op after falling behind
456
- // and register summary ack handler to re-register this handler
457
- // after successful summary
458
- this.summaryCollection.once(protocol_definitions_1.MessageType.SummaryAck, () => {
459
- this.logger.sendTelemetryEvent({ eventName: "SummaryStatus:CaughtUp" });
460
- // we've caught up, so re-register the default action to monitor for
461
- // falling behind, and unregister ourself
462
- this.summaryCollection.on("default", defaultAction);
463
- });
464
- this.summaryCollection.off("default", defaultAction);
465
- }
466
- };
467
- this.summaryCollection.on("default", defaultAction);
468
482
  const orderedClientLogger = telemetry_utils_1.ChildLogger.create(this.logger, "OrderedClientElection");
469
483
  const orderedClientCollection = new orderedClientElection_1.OrderedClientCollection(orderedClientLogger, this.context.deltaManager, this.context.quorum);
470
484
  const orderedClientElectionForSummarizer = new orderedClientElection_1.OrderedClientElection(orderedClientLogger, orderedClientCollection, electedSummarizerData !== null && electedSummarizerData !== void 0 ? electedSummarizerData : this.context.deltaManager.lastSequenceNumber, summarizerClientElection_1.SummarizerClientElection.isClientEligible);
471
- const summarizerClientElectionEnabled = (_c = localStorageFeatureGates_1.getLocalStorageFeatureGate("summarizerClientElection")) !== null && _c !== void 0 ? _c : ((_d = this.runtimeOptions.summaryOptions) === null || _d === void 0 ? void 0 : _d.summarizerClientElection) === true;
485
+ const summarizerClientElectionEnabled = (_c = this.mc.config.getBoolean("Fluid.ContainerRuntime.summarizerClientElection")) !== null && _c !== void 0 ? _c : ((_d = this.runtimeOptions.summaryOptions) === null || _d === void 0 ? void 0 : _d.summarizerClientElection) === true;
486
+ const maxOpsSinceLastSummary = (_e = this.runtimeOptions.summaryOptions.maxOpsSinceLastSummary) !== null && _e !== void 0 ? _e : 7000;
472
487
  this.summarizerClientElection = new summarizerClientElection_1.SummarizerClientElection(orderedClientLogger, this.summaryCollection, orderedClientElectionForSummarizer, maxOpsSinceLastSummary, summarizerClientElectionEnabled);
473
488
  if (this.context.clientDetails.type === summarizerClientElection_1.summarizerClientType) {
474
- this._summarizer = new summarizer_1.Summarizer("/_summarizer", this /* ISummarizerRuntime */, () => this.summaryConfiguration, this /* ISummarizerInternalsProvider */, this.IFluidHandleContext, this.summaryCollection, async (runtime) => runWhileConnectedCoordinator_1.RunWhileConnectedCoordinator.create(runtime));
489
+ this._summarizer = new summarizer_1.Summarizer("/_summarizer", this /* ISummarizerRuntime */, () => this.summaryConfiguration, this /* ISummarizerInternalsProvider */, this.handleContext, this.summaryCollection, async (runtime) => runWhileConnectedCoordinator_1.RunWhileConnectedCoordinator.create(runtime));
475
490
  }
476
491
  else if (summarizerClientElection_1.SummarizerClientElection.clientDetailsPermitElection(this.context.clientDetails)) {
477
- // Create the SummaryManager and mark the initial state
478
- const requestOptions = {
479
- cache: false,
480
- reconnect: false,
481
- summarizingClient: true,
492
+ // Only create a SummaryManager and SummarizerClientElection
493
+ // if summaries are enabled and we are not the summarizer client.
494
+ const defaultAction = () => {
495
+ if (this.summaryCollection.opsSinceLastAck > maxOpsSinceLastSummary) {
496
+ this.logger.sendErrorEvent({ eventName: "SummaryStatus:Behind" });
497
+ // unregister default to no log on every op after falling behind
498
+ // and register summary ack handler to re-register this handler
499
+ // after successful summary
500
+ this.summaryCollection.once(protocol_definitions_1.MessageType.SummaryAck, () => {
501
+ this.logger.sendTelemetryEvent({ eventName: "SummaryStatus:CaughtUp" });
502
+ // we've caught up, so re-register the default action to monitor for
503
+ // falling behind, and unregister ourself
504
+ this.summaryCollection.on("default", defaultAction);
505
+ });
506
+ this.summaryCollection.off("default", defaultAction);
507
+ }
482
508
  };
509
+ this.summaryCollection.on("default", defaultAction);
510
+ // Create the SummaryManager and mark the initial state
483
511
  this.summaryManager = new summaryManager_1.SummaryManager(this.summarizerClientElection, this, // IConnectedState
484
- this.summaryCollection, this.logger, summaryManager_1.formRequestSummarizerFn(this.context.loader, this.context.deltaManager.lastSequenceNumber, requestOptions), new throttler_1.Throttler(60 * 1000, // 60 sec delay window
512
+ this.summaryCollection, this.logger, this.formRequestSummarizerFn(this.context.loader), new throttler_1.Throttler(60 * 1000, // 60 sec delay window
485
513
  30 * 1000, // 30 sec max delay
486
514
  // throttling function increases exponentially (0ms, 40ms, 80ms, 160ms, etc)
487
515
  throttler_1.formExponentialFn({ coefficient: 20, initialDelay: 0 })), {
@@ -494,7 +522,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
494
522
  this.deltaManager.on("readonly", (readonly) => {
495
523
  // we accumulate ops while being in read-only state.
496
524
  // once user gets write permissions and we have active connection, flush all pending ops.
497
- common_utils_1.assert(readonly === this.deltaManager.readonly, 0x124 /* "inconsistent readonly property/event state" */);
525
+ common_utils_1.assert(readonly === this.deltaManager.readOnlyInfo.readonly, 0x124 /* "inconsistent readonly property/event state" */);
498
526
  // We need to be very careful with when we (re)send pending ops, to ensure that we only send ops
499
527
  // when we either never send an op, or attempted to send it but we know for sure it was not
500
528
  // sequenced by server and will never be sequenced (i.e. was lost)
@@ -513,6 +541,10 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
513
541
  if (context.pendingLocalState !== undefined) {
514
542
  this.deltaManager.on("op", this.onOp);
515
543
  }
544
+ // logging hardware telemetry
545
+ logger.sendTelemetryEvent(Object.assign({ eventName: "DeviceSpec" }, getDeviceSpec()));
546
+ // logging container load stats
547
+ this.logger.sendTelemetryEvent(Object.assign(Object.assign(Object.assign({ eventName: "ContainerLoadStats" }, this.createContainerMetadata), this.dataStores.containerLoadStats), { summaryCount: this.summaryCount, summaryFormatVersion: metadata === null || metadata === void 0 ? void 0 : metadata.summaryFormatVersion, disableIsolatedChannels: metadata === null || metadata === void 0 ? void 0 : metadata.disableIsolatedChannels, gcVersion: metadata === null || metadata === void 0 ? void 0 : metadata.gcFeature }));
516
548
  connectionTelemetry_1.ReportOpPerfTelemetry(this.context.clientId, this.deltaManager, this.logger);
517
549
  }
518
550
  get IContainerRuntime() { return this; }
@@ -526,7 +558,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
526
558
  * @param existing - (optional) When loading from an existing snapshot. Precedes context.existing if provided
527
559
  */
528
560
  static async load(context, registryEntries, requestHandler, runtimeOptions = {}, containerScope = context.scope, existing) {
529
- var _a, _b, _c, _d;
561
+ var _a, _b, _c;
530
562
  // If taggedLogger exists, use it. Otherwise, wrap the vanilla logger:
531
563
  const passLogger = (_a = context.taggedLogger) !== null && _a !== void 0 ? _a : new telemetry_utils_1.TaggedLoggerAdapter(context.logger);
532
564
  const logger = telemetry_utils_1.ChildLogger.create(passLogger, undefined, {
@@ -568,19 +600,22 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
568
600
  return driver_utils_1.readAndParse(storage, blobId);
569
601
  }
570
602
  };
571
- const chunks = (_b = await tryFetchBlob(summaryFormat_1.chunksBlobName)) !== null && _b !== void 0 ? _b : [];
572
- const metadata = await tryFetchBlob(summaryFormat_1.metadataBlobName);
573
- const electedSummarizerData = await tryFetchBlob(summaryFormat_1.electedSummarizerBlobName);
603
+ const [chunks, metadata, electedSummarizerData, aliases] = await Promise.all([
604
+ tryFetchBlob(summaryFormat_1.chunksBlobName),
605
+ tryFetchBlob(summaryFormat_1.metadataBlobName),
606
+ tryFetchBlob(summaryFormat_1.electedSummarizerBlobName),
607
+ tryFetchBlob(summaryFormat_1.aliasBlobName),
608
+ ]);
574
609
  const loadExisting = existing === true || context.existing === true;
575
610
  // read snapshot blobs needed for BlobManager to load
576
- const blobManagerSnapshot = await blobManager_1.BlobManager.load((_c = context.baseSnapshot) === null || _c === void 0 ? void 0 : _c.trees[summaryFormat_1.blobsTreeName], async (id) => {
611
+ const blobManagerSnapshot = await blobManager_1.BlobManager.load((_b = context.baseSnapshot) === null || _b === void 0 ? void 0 : _b.trees[summaryFormat_1.blobsTreeName], async (id) => {
577
612
  // IContainerContext storage api return type still has undefined in 0.39 package version.
578
613
  // So once we release 0.40 container-defn package we can remove this check.
579
614
  common_utils_1.assert(storage !== undefined, 0x256 /* "storage undefined in attached container" */);
580
615
  return driver_utils_1.readAndParse(storage, id);
581
616
  });
582
617
  // Verify summary runtime sequence number matches protocol sequence number.
583
- const runtimeSequenceNumber = (_d = metadata === null || metadata === void 0 ? void 0 : metadata.message) === null || _d === void 0 ? void 0 : _d.sequenceNumber;
618
+ const runtimeSequenceNumber = (_c = metadata === null || metadata === void 0 ? void 0 : metadata.message) === null || _c === void 0 ? void 0 : _c.sequenceNumber;
584
619
  if (runtimeSequenceNumber !== undefined) {
585
620
  const protocolSequenceNumber = context.deltaManager.initialSequenceNumber;
586
621
  // Unless bypass is explicitly set, then take action when sequence numbers mismatch.
@@ -595,13 +630,16 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
595
630
  }
596
631
  }
597
632
  }
598
- const runtime = new ContainerRuntime(context, registry, metadata, electedSummarizerData, chunks, {
633
+ const runtime = new ContainerRuntime(context, registry, metadata, electedSummarizerData, chunks !== null && chunks !== void 0 ? chunks : [], aliases !== null && aliases !== void 0 ? aliases : [], {
599
634
  summaryOptions,
600
635
  gcOptions,
601
636
  loadSequenceNumberVerification,
602
637
  }, containerScope, logger, loadExisting, blobManagerSnapshot, requestHandler, storage);
603
638
  return runtime;
604
639
  }
640
+ /**
641
+ * @deprecated This will be removed in a later release. Deprecated in 0.53
642
+ */
605
643
  get id() {
606
644
  return this.context.id;
607
645
  }
@@ -652,6 +690,9 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
652
690
  get attachState() {
653
691
  return this.context.attachState;
654
692
  }
693
+ get IFluidHandleContext() {
694
+ return this.handleContext;
695
+ }
655
696
  get connected() {
656
697
  return this._connected;
657
698
  }
@@ -665,13 +706,22 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
665
706
  return Object.assign(Object.assign(Object.assign({}, DefaultSummaryConfiguration), (_b = (_a = this.context) === null || _a === void 0 ? void 0 : _a.serviceConfiguration) === null || _b === void 0 ? void 0 : _b.summary), (_c = this.runtimeOptions.summaryOptions) === null || _c === void 0 ? void 0 : _c.summaryConfigOverrides);
666
707
  }
667
708
  get disposed() { return this._disposed; }
668
- static get defaultFlushMode() {
669
- return localStorageFeatureGates_1.getLocalStorageFeatureGate(turnBasedFlushModeKey) ? runtime_definitions_1.FlushMode.TurnBased : runtime_definitions_1.FlushMode.Immediate;
709
+ /**
710
+ * True, if GC data should be written at root of the summary tree.
711
+ * False, if data stores should write GC blobs in their summary tree.
712
+ */
713
+ get writeGCDataAtRoot() {
714
+ return this.garbageCollector.writeDataAtRoot;
670
715
  }
671
716
  get summarizer() {
672
717
  common_utils_1.assert(this._summarizer !== undefined, 0x257 /* "This is not summarizing container" */);
673
718
  return this._summarizer;
674
719
  }
720
+ get summariesDisabled() {
721
+ var _a;
722
+ return this.runtimeOptions.summaryOptions.disableSummaries === true ||
723
+ ((_a = this.runtimeOptions.summaryOptions.summaryConfigOverrides) === null || _a === void 0 ? void 0 : _a.disableSummaries) === true;
724
+ }
675
725
  dispose(error) {
676
726
  var _a;
677
727
  if (this._disposed) {
@@ -785,14 +835,10 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
785
835
  }
786
836
  formMetadata() {
787
837
  var _a;
788
- return {
789
- summaryFormatVersion: 1,
790
- disableIsolatedChannels: this.disableIsolatedChannels || undefined,
791
- gcFeature: this.garbageCollector.gcSummaryFeatureVersion,
838
+ return Object.assign(Object.assign({}, this.createContainerMetadata), { summaryCount: this.summaryCount, summaryFormatVersion: 1, disableIsolatedChannels: this.disableIsolatedChannels || undefined, gcFeature: this.garbageCollector.gcSummaryFeatureVersion,
792
839
  // The last message processed at the time of summary. If there are no messages, nothing has changed from
793
840
  // the base summary we loaded from. So, use the message from its metadata blob.
794
- message: (_a = summaryFormat_1.extractSummaryMetadataMessage(this.deltaManager.lastMessage)) !== null && _a !== void 0 ? _a : this.baseSummaryMessage,
795
- };
841
+ message: (_a = summaryFormat_1.extractSummaryMetadataMessage(this.deltaManager.lastMessage)) !== null && _a !== void 0 ? _a : this.baseSummaryMessage });
796
842
  }
797
843
  /**
798
844
  * Retrieves the runtime for a data store if it's referenced as per the initially summary that it is loaded with.
@@ -819,22 +865,14 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
819
865
  * @deprecated - Use summarize to get summary of the container runtime.
820
866
  */
821
867
  async snapshot() {
822
- if (this.garbageCollector.shouldRunGC) {
823
- await this.collectGarbage({ logger: this.logger, fullGC: true /* fullGC */ });
824
- }
825
- const root = { entries: [] };
826
- const entries = await this.dataStores.snapshot();
827
- if (this.disableIsolatedChannels) {
828
- root.entries = root.entries.concat(entries);
829
- }
830
- else {
831
- root.entries.push(new protocol_base_1.TreeTreeEntry(runtime_definitions_1.channelsTreeName, { entries }));
832
- }
833
- root.entries.push(new protocol_base_1.BlobTreeEntry(summaryFormat_1.metadataBlobName, JSON.stringify(this.formMetadata())));
834
- if (this.chunkMap.size > 0) {
835
- root.entries.push(new protocol_base_1.BlobTreeEntry(summaryFormat_1.chunksBlobName, JSON.stringify([...this.chunkMap])));
836
- }
837
- return root;
868
+ const summaryResult = await this.summarize({
869
+ summaryLogger: this.logger,
870
+ fullTree: true,
871
+ trackState: false,
872
+ runGC: this.garbageCollector.shouldRunGC,
873
+ fullGC: true,
874
+ });
875
+ return runtime_utils_1.convertSummaryTreeToITree(summaryResult.summary);
838
876
  }
839
877
  addContainerBlobsToSummary(summaryTree) {
840
878
  var _a;
@@ -843,6 +881,10 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
843
881
  const content = JSON.stringify([...this.chunkMap]);
844
882
  runtime_utils_1.addBlobToSummary(summaryTree, summaryFormat_1.chunksBlobName, content);
845
883
  }
884
+ const dataStoreAliases = this.dataStores.aliases();
885
+ if (dataStoreAliases.size > 0) {
886
+ runtime_utils_1.addBlobToSummary(summaryTree, summaryFormat_1.aliasBlobName, JSON.stringify([...dataStoreAliases]));
887
+ }
846
888
  if (this.summarizerClientElection) {
847
889
  const electedSummarizerContent = JSON.stringify((_a = this.summarizerClientElection) === null || _a === void 0 ? void 0 : _a.serialize());
848
890
  runtime_utils_1.addBlobToSummary(summaryTree, summaryFormat_1.electedSummarizerBlobName, electedSummarizerContent);
@@ -854,6 +896,12 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
854
896
  const blobsTree = runtime_utils_1.convertToSummaryTree(snapshot, false);
855
897
  runtime_utils_1.addTreeToSummary(summaryTree, summaryFormat_1.blobsTreeName, blobsTree);
856
898
  }
899
+ if (this.writeGCDataAtRoot) {
900
+ const gcSummary = this.garbageCollector.summarize();
901
+ if (gcSummary !== undefined) {
902
+ runtime_utils_1.addTreeToSummary(summaryTree, garbageCollection_1.gcTreeKey, gcSummary);
903
+ }
904
+ }
857
905
  }
858
906
  replayPendingStates() {
859
907
  // We need to be able to send ops to replay states
@@ -888,6 +936,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
888
936
  return this.dataStores.applyStashedOp(op);
889
937
  case ContainerMessageType.Attach:
890
938
  return this.dataStores.applyStashedAttachOp(op);
939
+ case ContainerMessageType.Alias:
891
940
  case ContainerMessageType.BlobAttach:
892
941
  return;
893
942
  case ContainerMessageType.ChunkedOp:
@@ -909,7 +958,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
909
958
  this.replayPendingStates();
910
959
  }
911
960
  this.dataStores.setConnectionState(connected, clientId);
912
- telemetry_utils_1.raiseConnectedEvent(this._logger, this, connected, clientId);
961
+ telemetry_utils_1.raiseConnectedEvent(this.mc.logger, this, connected, clientId);
913
962
  }
914
963
  process(messageArg, local) {
915
964
  var _a;
@@ -943,6 +992,9 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
943
992
  case ContainerMessageType.Attach:
944
993
  this.dataStores.processAttachMessage(message, local || localAck);
945
994
  break;
995
+ case ContainerMessageType.Alias:
996
+ this.processAliasMessage(message, localOpMetadata, local);
997
+ break;
946
998
  case ContainerMessageType.FluidDataStoreOp:
947
999
  // if localAck === true, treat this as a local op because it's one we sent on a previous container
948
1000
  this.dataStores.processFluidDataStoreOp(message, local || localAck, localOpMetadata);
@@ -961,6 +1013,9 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
961
1013
  throw e;
962
1014
  }
963
1015
  }
1016
+ processAliasMessage(message, localOpMetadata, local) {
1017
+ this.dataStores.processAliasMessage(message, localOpMetadata, local);
1018
+ }
964
1019
  processSignal(message, local) {
965
1020
  const envelope = message.content;
966
1021
  const transformed = {
@@ -1010,6 +1065,11 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1010
1065
  return;
1011
1066
  }
1012
1067
  this.needsFlush = false;
1068
+ // Did we disconnect in the middle of turn-based batch?
1069
+ // If so, do nothing, as pending state manager will resubmit it correctly on reconnect.
1070
+ if (!this.canSendOps()) {
1071
+ return;
1072
+ }
1013
1073
  return this.deltaSender.flush();
1014
1074
  }
1015
1075
  orderSequentially(callback) {
@@ -1026,11 +1086,12 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1026
1086
  this.setFlushMode(runtime_definitions_1.FlushMode.TurnBased);
1027
1087
  try {
1028
1088
  this.trackOrderSequentiallyCalls(callback);
1029
- }
1030
- finally {
1031
1089
  this.flush();
1032
1090
  this.setFlushMode(savedFlushMode);
1033
1091
  }
1092
+ catch (error) {
1093
+ this.closeFn(container_utils_1.CreateProcessingError(error, "orderSequentially"));
1094
+ }
1034
1095
  }
1035
1096
  trackOrderSequentiallyCalls(callback) {
1036
1097
  try {
@@ -1186,27 +1247,33 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1186
1247
  * Implementation of IGarbageCollectionRuntime::updateUsedRoutes.
1187
1248
  * After GC has run, called to notify this container's nodes of routes that are used in it.
1188
1249
  * @param usedRoutes - The routes that are used in all nodes in this Container.
1250
+ * @param gcTimestamp - The time when GC was run that generated these used routes. If any node node becomes
1251
+ * unreferenced as part of this GC run, this should be used to update the time when it happens.
1189
1252
  * @returns the statistics of the used state of the data stores.
1190
1253
  */
1191
- updateUsedRoutes(usedRoutes) {
1192
- var _a;
1254
+ updateUsedRoutes(usedRoutes, gcTimestamp) {
1193
1255
  // Update our summarizer node's used routes. Updating used routes in summarizer node before
1194
1256
  // summarizing is required and asserted by the the summarizer node. We are the root and are
1195
1257
  // always referenced, so the used routes is only self-route (empty string).
1196
1258
  this.summarizerNode.updateUsedRoutes([""]);
1197
- return this.dataStores.updateUsedRoutes(usedRoutes, (_a =
1198
- // For now, we use the timestamp of the last op for gcTimestamp. However, there can be cases where
1199
- // we don't have an op (on demand summaries for instance). In those cases, we will use the timestamp
1200
- // of this client's connection - https://github.com/microsoft/FluidFramework/issues/7152.
1201
- this.deltaManager.lastMessage) === null || _a === void 0 ? void 0 : _a.timestamp);
1259
+ return this.dataStores.updateUsedRoutes(usedRoutes, gcTimestamp);
1202
1260
  }
1203
1261
  /**
1204
- * Runs garbage collection and udpates the reference / used state of the nodes in the container.
1262
+ * Runs garbage collection and updates the reference / used state of the nodes in the container.
1205
1263
  * @returns the statistics of the garbage collection run.
1206
1264
  */
1207
1265
  async collectGarbage(options) {
1208
1266
  return this.garbageCollector.collectGarbage(options);
1209
1267
  }
1268
+ /**
1269
+ * Called when a new outbound reference is added to another node. This is used by garbage collection to identify
1270
+ * all references added in the system.
1271
+ * @param srcHandle - The handle of the node that added the reference.
1272
+ * @param outboundHandle - The handle of the outbound node that is referenced.
1273
+ */
1274
+ addedGCOutboundReference(srcHandle, outboundHandle) {
1275
+ this.garbageCollector.addedOutboundReference(srcHandle.absolutePath, outboundHandle.absolutePath);
1276
+ }
1210
1277
  /**
1211
1278
  * Generates the summary tree, uploads it to storage, and then submits the summarize op.
1212
1279
  * This is intended to be called by the summarizer, since it is the implementation of
@@ -1266,6 +1333,13 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1266
1333
  if (!continueResult.continue) {
1267
1334
  return { stage: "base", referenceSequenceNumber: summaryRefSeqNum, error: continueResult.error };
1268
1335
  }
1336
+ // increment summary count
1337
+ if (this.summaryCount !== undefined) {
1338
+ this.summaryCount++;
1339
+ }
1340
+ else {
1341
+ this.summaryCount = 1;
1342
+ }
1269
1343
  const trace = common_utils_1.Trace.start();
1270
1344
  let summarizeResult;
1271
1345
  try {
@@ -1389,10 +1463,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1389
1463
  this.dirtyContainer = dirty;
1390
1464
  if (this.emitDirtyDocumentEvent) {
1391
1465
  this.emit(dirty ? "dirty" : "saved");
1392
- // back-compat: Loader API added in 0.35 only
1393
- if (this.context.updateDirtyContainerState !== undefined) {
1394
- this.context.updateDirtyContainerState(dirty);
1395
- }
1466
+ this.context.updateDirtyContainerState(dirty);
1396
1467
  }
1397
1468
  }
1398
1469
  submitDataStoreOp(id, contents, localOpMetadata = undefined) {
@@ -1473,7 +1544,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1473
1544
  // That might be not what caller hopes to get, but we can look deeper if telemetry tells us it's a problem.
1474
1545
  const middleOfBatch = this.flushMode === runtime_definitions_1.FlushMode.TurnBased && this.needsFlush;
1475
1546
  if (middleOfBatch) {
1476
- this._logger.sendErrorEvent({ eventName: "submitSystemMessageError", type });
1547
+ this.mc.logger.sendErrorEvent({ eventName: "submitSystemMessageError", type });
1477
1548
  }
1478
1549
  return this.context.submitFn(type, contents, middleOfBatch);
1479
1550
  }
@@ -1506,6 +1577,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1506
1577
  this.dataStores.resubmitDataStoreOp(content, localOpMetadata);
1507
1578
  break;
1508
1579
  case ContainerMessageType.Attach:
1580
+ case ContainerMessageType.Alias:
1509
1581
  this.submit(type, content, localOpMetadata);
1510
1582
  break;
1511
1583
  case ContainerMessageType.ChunkedOp:
@@ -1537,7 +1609,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1537
1609
  * @returns downloaded snapshot's reference sequence number
1538
1610
  */
1539
1611
  async refreshLatestSummaryAckFromServer(summaryLogger) {
1540
- const snapshot = await this.fetchSnapshotFromStorage(this.id, summaryLogger, {
1612
+ const snapshot = await this.fetchSnapshotFromStorage(null, summaryLogger, {
1541
1613
  eventName: "RefreshLatestSummaryGetSnapshot",
1542
1614
  fetchLatest: true,
1543
1615
  });
@@ -1566,12 +1638,30 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1566
1638
  return this.pendingStateManager.getLocalState();
1567
1639
  }
1568
1640
  /**
1569
- * @returns true if summaries are explicitly disabled for this ContainerRuntime, false otherwise
1570
- */
1571
- summariesDisabled() {
1572
- var _a;
1573
- return this.runtimeOptions.summaryOptions.disableSummaries === true ||
1574
- ((_a = this.runtimeOptions.summaryOptions.summaryConfigOverrides) === null || _a === void 0 ? void 0 : _a.disableSummaries) === true;
1641
+ * * Forms a function that will request a Summarizer.
1642
+ * @param loaderRouter - the loader acting as an IFluidRouter
1643
+ * */
1644
+ formRequestSummarizerFn(loaderRouter) {
1645
+ return async () => {
1646
+ const request = {
1647
+ headers: {
1648
+ [container_definitions_1.LoaderHeader.cache]: false,
1649
+ [container_definitions_1.LoaderHeader.clientDetails]: {
1650
+ capabilities: { interactive: false },
1651
+ type: summarizerClientElection_1.summarizerClientType,
1652
+ },
1653
+ [driver_definitions_1.DriverHeader.summarizingClient]: true,
1654
+ [container_definitions_1.LoaderHeader.reconnect]: false,
1655
+ },
1656
+ url: "/_summarizer",
1657
+ };
1658
+ const fluidObject = await runtime_utils_1.requestFluidObject(loaderRouter, request);
1659
+ const summarizer = fluidObject.ISummarizer;
1660
+ if (!summarizer) {
1661
+ throw new container_utils_1.UsageError("Fluid object does not implement ISummarizer");
1662
+ }
1663
+ return summarizer;
1664
+ };
1575
1665
  }
1576
1666
  }
1577
1667
  exports.ContainerRuntime = ContainerRuntime;