@fluidframework/container-runtime 2.0.0-internal.6.4.0 → 2.0.0-internal.7.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (237) hide show
  1. package/CHANGELOG.md +111 -0
  2. package/api-extractor.json +13 -1
  3. package/api-report/container-runtime.api.md +799 -0
  4. package/dist/blobManager.d.ts +1 -1
  5. package/dist/blobManager.d.ts.map +1 -1
  6. package/dist/blobManager.js +7 -7
  7. package/dist/blobManager.js.map +1 -1
  8. package/dist/connectionTelemetry.d.ts.map +1 -1
  9. package/dist/connectionTelemetry.js +75 -42
  10. package/dist/connectionTelemetry.js.map +1 -1
  11. package/dist/container-runtime-alpha.d.ts +1554 -0
  12. package/dist/container-runtime-beta.d.ts +1554 -0
  13. package/dist/container-runtime-public.d.ts +1554 -0
  14. package/dist/container-runtime.d.ts +1611 -0
  15. package/dist/containerHandleContext.js +3 -3
  16. package/dist/containerHandleContext.js.map +1 -1
  17. package/dist/containerRuntime.d.ts +28 -24
  18. package/dist/containerRuntime.d.ts.map +1 -1
  19. package/dist/containerRuntime.js +277 -256
  20. package/dist/containerRuntime.js.map +1 -1
  21. package/dist/dataStore.js +9 -9
  22. package/dist/dataStore.js.map +1 -1
  23. package/dist/dataStoreContext.d.ts +1 -3
  24. package/dist/dataStoreContext.d.ts.map +1 -1
  25. package/dist/dataStoreContext.js +54 -58
  26. package/dist/dataStoreContext.js.map +1 -1
  27. package/dist/dataStoreRegistry.js +3 -3
  28. package/dist/dataStoreRegistry.js.map +1 -1
  29. package/dist/deltaManagerProxyBase.js +4 -4
  30. package/dist/deltaManagerProxyBase.js.map +1 -1
  31. package/dist/deltaManagerSummarizerProxy.js +6 -6
  32. package/dist/deltaManagerSummarizerProxy.js.map +1 -1
  33. package/dist/deltaScheduler.js.map +1 -1
  34. package/dist/error.d.ts.map +1 -1
  35. package/dist/error.js.map +1 -1
  36. package/dist/gc/garbageCollection.js +13 -13
  37. package/dist/gc/garbageCollection.js.map +1 -1
  38. package/dist/gc/gcDefinitions.d.ts +4 -15
  39. package/dist/gc/gcDefinitions.d.ts.map +1 -1
  40. package/dist/gc/gcDefinitions.js.map +1 -1
  41. package/dist/gc/gcTelemetry.d.ts +1 -1
  42. package/dist/gc/gcTelemetry.d.ts.map +1 -1
  43. package/dist/gc/gcUnreferencedStateTracker.js +3 -3
  44. package/dist/gc/gcUnreferencedStateTracker.js.map +1 -1
  45. package/dist/id-compressor/appendOnlySortedMap.js.map +1 -1
  46. package/dist/id-compressor/idCompressor.js.map +1 -1
  47. package/dist/id-compressor/identifiers.d.ts +3 -3
  48. package/dist/id-compressor/identifiers.d.ts.map +1 -1
  49. package/dist/index.d.ts +1 -1
  50. package/dist/index.d.ts.map +1 -1
  51. package/dist/index.js +2 -1
  52. package/dist/index.js.map +1 -1
  53. package/dist/messageTypes.d.ts +17 -17
  54. package/dist/messageTypes.d.ts.map +1 -1
  55. package/dist/messageTypes.js +1 -1
  56. package/dist/messageTypes.js.map +1 -1
  57. package/dist/opLifecycle/batchManager.js +6 -6
  58. package/dist/opLifecycle/batchManager.js.map +1 -1
  59. package/dist/opLifecycle/definitions.d.ts +2 -2
  60. package/dist/opLifecycle/definitions.d.ts.map +1 -1
  61. package/dist/opLifecycle/outbox.d.ts.map +1 -1
  62. package/dist/opLifecycle/outbox.js +7 -2
  63. package/dist/opLifecycle/outbox.js.map +1 -1
  64. package/dist/packageVersion.d.ts +1 -1
  65. package/dist/packageVersion.js +1 -1
  66. package/dist/packageVersion.js.map +1 -1
  67. package/dist/pendingStateManager.d.ts +3 -19
  68. package/dist/pendingStateManager.d.ts.map +1 -1
  69. package/dist/pendingStateManager.js +23 -40
  70. package/dist/pendingStateManager.js.map +1 -1
  71. package/dist/scheduleManager.js +6 -2
  72. package/dist/scheduleManager.js.map +1 -1
  73. package/dist/summary/orderedClientElection.d.ts +3 -3
  74. package/dist/summary/orderedClientElection.d.ts.map +1 -1
  75. package/dist/summary/orderedClientElection.js +54 -54
  76. package/dist/summary/orderedClientElection.js.map +1 -1
  77. package/dist/summary/runWhileConnectedCoordinator.js +6 -6
  78. package/dist/summary/runWhileConnectedCoordinator.js.map +1 -1
  79. package/dist/summary/runningSummarizer.js +37 -37
  80. package/dist/summary/runningSummarizer.js.map +1 -1
  81. package/dist/summary/summarizer.d.ts +1 -0
  82. package/dist/summary/summarizer.d.ts.map +1 -1
  83. package/dist/summary/summarizer.js +17 -8
  84. package/dist/summary/summarizer.js.map +1 -1
  85. package/dist/summary/summarizerClientElection.js +6 -6
  86. package/dist/summary/summarizerClientElection.js.map +1 -1
  87. package/dist/summary/summarizerHeuristics.js +9 -9
  88. package/dist/summary/summarizerHeuristics.js.map +1 -1
  89. package/dist/summary/summarizerNode/summarizerNode.js +7 -7
  90. package/dist/summary/summarizerNode/summarizerNode.js.map +1 -1
  91. package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts +1 -1
  92. package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
  93. package/dist/summary/summarizerNode/summarizerNodeUtils.js +3 -3
  94. package/dist/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
  95. package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts +2 -2
  96. package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
  97. package/dist/summary/summarizerTypes.d.ts +12 -12
  98. package/dist/summary/summarizerTypes.d.ts.map +1 -1
  99. package/dist/summary/summaryCollection.d.ts +2 -2
  100. package/dist/summary/summaryCollection.d.ts.map +1 -1
  101. package/dist/summary/summaryCollection.js +22 -21
  102. package/dist/summary/summaryCollection.js.map +1 -1
  103. package/dist/summary/summaryFormat.d.ts +5 -5
  104. package/dist/summary/summaryFormat.d.ts.map +1 -1
  105. package/dist/summary/summaryGenerator.d.ts +3 -3
  106. package/dist/summary/summaryGenerator.d.ts.map +1 -1
  107. package/dist/summary/summaryGenerator.js.map +1 -1
  108. package/dist/summary/summaryManager.d.ts +2 -2
  109. package/dist/summary/summaryManager.d.ts.map +1 -1
  110. package/dist/summary/summaryManager.js +10 -10
  111. package/dist/summary/summaryManager.js.map +1 -1
  112. package/dist/throttler.js +16 -16
  113. package/dist/throttler.js.map +1 -1
  114. package/dist/tsdoc-metadata.json +1 -1
  115. package/lib/blobManager.d.ts +1 -1
  116. package/lib/blobManager.d.ts.map +1 -1
  117. package/lib/blobManager.js +7 -7
  118. package/lib/blobManager.js.map +1 -1
  119. package/lib/connectionTelemetry.d.ts.map +1 -1
  120. package/lib/connectionTelemetry.js +76 -43
  121. package/lib/connectionTelemetry.js.map +1 -1
  122. package/lib/containerHandleContext.js +3 -3
  123. package/lib/containerHandleContext.js.map +1 -1
  124. package/lib/containerRuntime.d.ts +28 -24
  125. package/lib/containerRuntime.d.ts.map +1 -1
  126. package/lib/containerRuntime.js +268 -252
  127. package/lib/containerRuntime.js.map +1 -1
  128. package/lib/dataStore.js +9 -9
  129. package/lib/dataStore.js.map +1 -1
  130. package/lib/dataStoreContext.d.ts +1 -3
  131. package/lib/dataStoreContext.d.ts.map +1 -1
  132. package/lib/dataStoreContext.js +54 -58
  133. package/lib/dataStoreContext.js.map +1 -1
  134. package/lib/dataStoreRegistry.js +3 -3
  135. package/lib/dataStoreRegistry.js.map +1 -1
  136. package/lib/deltaManagerProxyBase.js +4 -4
  137. package/lib/deltaManagerProxyBase.js.map +1 -1
  138. package/lib/deltaManagerSummarizerProxy.js +6 -6
  139. package/lib/deltaManagerSummarizerProxy.js.map +1 -1
  140. package/lib/deltaScheduler.js.map +1 -1
  141. package/lib/error.d.ts.map +1 -1
  142. package/lib/error.js.map +1 -1
  143. package/lib/gc/garbageCollection.js +13 -13
  144. package/lib/gc/garbageCollection.js.map +1 -1
  145. package/lib/gc/gcDefinitions.d.ts +4 -15
  146. package/lib/gc/gcDefinitions.d.ts.map +1 -1
  147. package/lib/gc/gcDefinitions.js.map +1 -1
  148. package/lib/gc/gcTelemetry.d.ts +1 -1
  149. package/lib/gc/gcTelemetry.d.ts.map +1 -1
  150. package/lib/gc/gcUnreferencedStateTracker.js +3 -3
  151. package/lib/gc/gcUnreferencedStateTracker.js.map +1 -1
  152. package/lib/id-compressor/appendOnlySortedMap.js.map +1 -1
  153. package/lib/id-compressor/idCompressor.js.map +1 -1
  154. package/lib/id-compressor/identifiers.d.ts +3 -3
  155. package/lib/id-compressor/identifiers.d.ts.map +1 -1
  156. package/lib/index.d.ts +1 -1
  157. package/lib/index.d.ts.map +1 -1
  158. package/lib/index.js +1 -1
  159. package/lib/index.js.map +1 -1
  160. package/lib/messageTypes.d.ts +17 -17
  161. package/lib/messageTypes.d.ts.map +1 -1
  162. package/lib/opLifecycle/batchManager.js +6 -6
  163. package/lib/opLifecycle/batchManager.js.map +1 -1
  164. package/lib/opLifecycle/definitions.d.ts +2 -2
  165. package/lib/opLifecycle/definitions.d.ts.map +1 -1
  166. package/lib/opLifecycle/outbox.d.ts.map +1 -1
  167. package/lib/opLifecycle/outbox.js +7 -2
  168. package/lib/opLifecycle/outbox.js.map +1 -1
  169. package/lib/packageVersion.d.ts +1 -1
  170. package/lib/packageVersion.js +1 -1
  171. package/lib/packageVersion.js.map +1 -1
  172. package/lib/pendingStateManager.d.ts +3 -19
  173. package/lib/pendingStateManager.d.ts.map +1 -1
  174. package/lib/pendingStateManager.js +23 -40
  175. package/lib/pendingStateManager.js.map +1 -1
  176. package/lib/scheduleManager.js +6 -2
  177. package/lib/scheduleManager.js.map +1 -1
  178. package/lib/summary/orderedClientElection.d.ts +3 -3
  179. package/lib/summary/orderedClientElection.d.ts.map +1 -1
  180. package/lib/summary/orderedClientElection.js +54 -54
  181. package/lib/summary/orderedClientElection.js.map +1 -1
  182. package/lib/summary/runWhileConnectedCoordinator.js +6 -6
  183. package/lib/summary/runWhileConnectedCoordinator.js.map +1 -1
  184. package/lib/summary/runningSummarizer.js +37 -37
  185. package/lib/summary/runningSummarizer.js.map +1 -1
  186. package/lib/summary/summarizer.d.ts +1 -0
  187. package/lib/summary/summarizer.d.ts.map +1 -1
  188. package/lib/summary/summarizer.js +18 -9
  189. package/lib/summary/summarizer.js.map +1 -1
  190. package/lib/summary/summarizerClientElection.js +6 -6
  191. package/lib/summary/summarizerClientElection.js.map +1 -1
  192. package/lib/summary/summarizerHeuristics.js +9 -9
  193. package/lib/summary/summarizerHeuristics.js.map +1 -1
  194. package/lib/summary/summarizerNode/summarizerNode.js +7 -7
  195. package/lib/summary/summarizerNode/summarizerNode.js.map +1 -1
  196. package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts +1 -1
  197. package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
  198. package/lib/summary/summarizerNode/summarizerNodeUtils.js +3 -3
  199. package/lib/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
  200. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts +2 -2
  201. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
  202. package/lib/summary/summarizerTypes.d.ts +12 -12
  203. package/lib/summary/summarizerTypes.d.ts.map +1 -1
  204. package/lib/summary/summaryCollection.d.ts +2 -2
  205. package/lib/summary/summaryCollection.d.ts.map +1 -1
  206. package/lib/summary/summaryCollection.js +22 -21
  207. package/lib/summary/summaryCollection.js.map +1 -1
  208. package/lib/summary/summaryFormat.d.ts +5 -5
  209. package/lib/summary/summaryFormat.d.ts.map +1 -1
  210. package/lib/summary/summaryGenerator.d.ts +3 -3
  211. package/lib/summary/summaryGenerator.d.ts.map +1 -1
  212. package/lib/summary/summaryGenerator.js.map +1 -1
  213. package/lib/summary/summaryManager.d.ts +2 -2
  214. package/lib/summary/summaryManager.d.ts.map +1 -1
  215. package/lib/summary/summaryManager.js +9 -9
  216. package/lib/summary/summaryManager.js.map +1 -1
  217. package/lib/throttler.js +16 -16
  218. package/lib/throttler.js.map +1 -1
  219. package/package.json +27 -27
  220. package/src/blobManager.ts +1 -1
  221. package/src/connectionTelemetry.ts +97 -52
  222. package/src/containerRuntime.ts +96 -73
  223. package/src/dataStore.ts +1 -1
  224. package/src/dataStoreContext.ts +1 -6
  225. package/src/error.ts +4 -1
  226. package/src/gc/gcDefinitions.ts +3 -15
  227. package/src/gc/gcEarlyAdoption.md +1 -1
  228. package/src/index.ts +1 -0
  229. package/src/opLifecycle/README.md +53 -28
  230. package/src/opLifecycle/outbox.ts +3 -0
  231. package/src/packageVersion.ts +1 -1
  232. package/src/pendingStateManager.ts +8 -46
  233. package/src/scheduleManager.ts +2 -0
  234. package/src/summary/summarizer.ts +20 -7
  235. package/src/summary/summaryCollection.ts +1 -0
  236. package/src/summary/summaryGenerator.ts +3 -3
  237. package/src/summary/summaryManager.ts +2 -2
@@ -8,7 +8,7 @@ import { DriverHeader, FetchSource, } from "@fluidframework/driver-definitions";
8
8
  import { readAndParse } from "@fluidframework/driver-utils";
9
9
  import { MessageType, SummaryType, } from "@fluidframework/protocol-definitions";
10
10
  import { FlushMode, FlushModeExperimental, gcTreeKey, channelsTreeName, } from "@fluidframework/runtime-definitions";
11
- import { addBlobToSummary, addSummarizeResultToSummary, addTreeToSummary, RequestParser, create404Response, exceptionToResponse, GCDataBuilder, requestFluidObject, seqFromTree, calculateStats, TelemetryContext, } from "@fluidframework/runtime-utils";
11
+ import { addBlobToSummary, addSummarizeResultToSummary, addTreeToSummary, RequestParser, create404Response, exceptionToResponse, GCDataBuilder, seqFromTree, calculateStats, TelemetryContext, responseToException, } from "@fluidframework/runtime-utils";
12
12
  import { v4 as uuid } from "uuid";
13
13
  import { ContainerFluidHandleContext } from "./containerHandleContext";
14
14
  import { FluidDataStoreRegistry } from "./dataStoreRegistry";
@@ -164,20 +164,274 @@ export const makeLegacySendBatchFn = (submitFn, deltaManager) => (batch) => {
164
164
  }
165
165
  deltaManager.flush();
166
166
  };
167
+ const summarizerRequestUrl = "_summarizer";
168
+ /**
169
+ * Create and retrieve the summmarizer
170
+ */
171
+ async function createSummarizer(loader, url) {
172
+ const request = {
173
+ headers: {
174
+ [LoaderHeader.cache]: false,
175
+ [LoaderHeader.clientDetails]: {
176
+ capabilities: { interactive: false },
177
+ type: summarizerClientType,
178
+ },
179
+ [DriverHeader.summarizingClient]: true,
180
+ [LoaderHeader.reconnect]: false,
181
+ },
182
+ url,
183
+ };
184
+ const resolvedContainer = await loader.resolve(request);
185
+ let fluidObject;
186
+ // Older containers may not have the "getEntryPoint" API
187
+ // ! This check will need to stay until LTS of loader moves past 2.0.0-internal.7.0.0
188
+ if (resolvedContainer.getEntryPoint !== undefined) {
189
+ fluidObject = await resolvedContainer.getEntryPoint();
190
+ }
191
+ else {
192
+ const response = await resolvedContainer.request({ url: `/${summarizerRequestUrl}` });
193
+ if (response.status !== 200 || response.mimeType !== "fluid/object") {
194
+ throw responseToException(response, request);
195
+ }
196
+ fluidObject = response.value;
197
+ }
198
+ if (fluidObject?.ISummarizer === undefined) {
199
+ throw new UsageError("Fluid object does not implement ISummarizer");
200
+ }
201
+ return fluidObject.ISummarizer;
202
+ }
203
+ /**
204
+ * This function is not supported publicly and exists for e2e testing
205
+ */
206
+ export async function TEST_requestSummarizer(loader, url) {
207
+ return createSummarizer(loader, url);
208
+ }
167
209
  /**
168
210
  * Represents the runtime of the container. Contains helper functions/state of the container.
169
211
  * It will define the store level mappings.
170
212
  */
171
213
  export class ContainerRuntime extends TypedEventEmitter {
214
+ /**
215
+ * @deprecated - Will be removed in future major release. Migrate all usage of IFluidRouter to the "entryPoint" pattern. Refer to Removing-IFluidRouter.md
216
+ */
217
+ get IFluidRouter() {
218
+ return this;
219
+ }
220
+ /**
221
+ * @deprecated - use loadRuntime instead.
222
+ * Load the stores from a snapshot and returns the runtime.
223
+ * @param context - Context of the container.
224
+ * @param registryEntries - Mapping to the stores.
225
+ * @param requestHandler - Request handlers for the container runtime
226
+ * @param runtimeOptions - Additional options to be passed to the runtime
227
+ * @param existing - (optional) When loading from an existing snapshot. Precedes context.existing if provided
228
+ * @param containerRuntimeCtor - (optional) Constructor to use to create the ContainerRuntime instance. This
229
+ * allows mixin classes to leverage this method to define their own async initializer.
230
+ */
231
+ static async load(context, registryEntries, requestHandler, runtimeOptions = {}, containerScope = context.scope, existing, containerRuntimeCtor = ContainerRuntime) {
232
+ let existingFlag = true;
233
+ if (!existing) {
234
+ existingFlag = false;
235
+ }
236
+ return this.loadRuntime({
237
+ context,
238
+ registryEntries,
239
+ existing: existingFlag,
240
+ runtimeOptions,
241
+ containerScope,
242
+ containerRuntimeCtor,
243
+ requestHandler,
244
+ provideEntryPoint: () => {
245
+ throw new UsageError("ContainerRuntime.load is deprecated and should no longer be used");
246
+ },
247
+ });
248
+ }
249
+ /**
250
+ * Load the stores from a snapshot and returns the runtime.
251
+ * @param params - An object housing the runtime properties:
252
+ * - context - Context of the container.
253
+ * - registryEntries - Mapping from data store types to their corresponding factories.
254
+ * - existing - Pass 'true' if loading from an existing snapshot.
255
+ * - requestHandler - (optional) Request handler for the request() method of the container runtime.
256
+ * Only relevant for back-compat while we remove the request() method and move fully to entryPoint as the main pattern.
257
+ * - runtimeOptions - Additional options to be passed to the runtime
258
+ * - containerScope - runtime services provided with context
259
+ * - containerRuntimeCtor - Constructor to use to create the ContainerRuntime instance.
260
+ * This allows mixin classes to leverage this method to define their own async initializer.
261
+ * - provideEntryPoint - Promise that resolves to an object which will act as entryPoint for the Container.
262
+ * This object should provide all the functionality that the Container is expected to provide to the loader layer.
263
+ */
264
+ static async loadRuntime(params) {
265
+ const { context, registryEntries, existing, requestHandler, provideEntryPoint, runtimeOptions = {}, containerScope = {}, containerRuntimeCtor = ContainerRuntime, } = params;
266
+ // If taggedLogger exists, use it. Otherwise, wrap the vanilla logger:
267
+ // back-compat: Remove the TaggedLoggerAdapter fallback once all the host are using loader > 0.45
268
+ const backCompatContext = context;
269
+ const passLogger = backCompatContext.taggedLogger ??
270
+ // eslint-disable-next-line import/no-deprecated
271
+ new TaggedLoggerAdapter(backCompatContext.logger);
272
+ const logger = createChildLogger({
273
+ logger: passLogger,
274
+ properties: {
275
+ all: {
276
+ runtimeVersion: pkgVersion,
277
+ },
278
+ },
279
+ });
280
+ const { summaryOptions = {}, gcOptions = {}, loadSequenceNumberVerification = "close", flushMode = defaultFlushMode, compressionOptions = defaultCompressionConfig, maxBatchSizeInBytes = defaultMaxBatchSizeInBytes, enableRuntimeIdCompressor = false, chunkSizeInBytes = defaultChunkSizeInBytes, enableOpReentryCheck = false, enableGroupedBatching = false, } = runtimeOptions;
281
+ const registry = new FluidDataStoreRegistry(registryEntries);
282
+ const tryFetchBlob = async (blobName) => {
283
+ const blobId = context.baseSnapshot?.blobs[blobName];
284
+ if (context.baseSnapshot && blobId) {
285
+ // IContainerContext storage api return type still has undefined in 0.39 package version.
286
+ // So once we release 0.40 container-defn package we can remove this check.
287
+ assert(context.storage !== undefined, 0x1f5 /* "Attached state should have storage" */);
288
+ return readAndParse(context.storage, blobId);
289
+ }
290
+ };
291
+ const [chunks, metadata, electedSummarizerData, aliases, serializedIdCompressor] = await Promise.all([
292
+ tryFetchBlob(chunksBlobName),
293
+ tryFetchBlob(metadataBlobName),
294
+ tryFetchBlob(electedSummarizerBlobName),
295
+ tryFetchBlob(aliasBlobName),
296
+ tryFetchBlob(idCompressorBlobName),
297
+ ]);
298
+ // read snapshot blobs needed for BlobManager to load
299
+ const blobManagerSnapshot = await BlobManager.load(context.baseSnapshot?.trees[blobsTreeName], async (id) => {
300
+ // IContainerContext storage api return type still has undefined in 0.39 package version.
301
+ // So once we release 0.40 container-defn package we can remove this check.
302
+ assert(context.storage !== undefined, 0x256 /* "storage undefined in attached container" */);
303
+ return readAndParse(context.storage, id);
304
+ });
305
+ // Verify summary runtime sequence number matches protocol sequence number.
306
+ const runtimeSequenceNumber = metadata?.message?.sequenceNumber;
307
+ // When we load with pending state, we reuse an old snapshot so we don't expect these numbers to match
308
+ if (!context.pendingLocalState && runtimeSequenceNumber !== undefined) {
309
+ const protocolSequenceNumber = context.deltaManager.initialSequenceNumber;
310
+ // Unless bypass is explicitly set, then take action when sequence numbers mismatch.
311
+ if (loadSequenceNumberVerification !== "bypass" &&
312
+ runtimeSequenceNumber !== protocolSequenceNumber) {
313
+ // "Load from summary, runtime metadata sequenceNumber !== initialSequenceNumber"
314
+ const error = new DataCorruptionError(
315
+ // pre-0.58 error message: SummaryMetadataMismatch
316
+ "Summary metadata mismatch", { runtimeVersion: pkgVersion, runtimeSequenceNumber, protocolSequenceNumber });
317
+ if (loadSequenceNumberVerification === "log") {
318
+ logger.sendErrorEvent({ eventName: "SequenceNumberMismatch" }, error);
319
+ }
320
+ else {
321
+ context.closeFn(error);
322
+ }
323
+ }
324
+ }
325
+ const idCompressorEnabled = metadata?.idCompressorEnabled ?? runtimeOptions.enableRuntimeIdCompressor ?? false;
326
+ let idCompressor;
327
+ if (idCompressorEnabled) {
328
+ const { IdCompressor, createSessionId } = await import("./id-compressor");
329
+ idCompressor =
330
+ serializedIdCompressor !== undefined
331
+ ? IdCompressor.deserialize(serializedIdCompressor, createSessionId())
332
+ : IdCompressor.create(logger);
333
+ }
334
+ const runtime = new containerRuntimeCtor(context, registry, metadata, electedSummarizerData, chunks ?? [], aliases ?? [], {
335
+ summaryOptions,
336
+ gcOptions,
337
+ loadSequenceNumberVerification,
338
+ flushMode,
339
+ compressionOptions,
340
+ maxBatchSizeInBytes,
341
+ chunkSizeInBytes,
342
+ enableRuntimeIdCompressor,
343
+ enableOpReentryCheck,
344
+ enableGroupedBatching,
345
+ }, containerScope, logger, existing, blobManagerSnapshot, context.storage, idCompressor, provideEntryPoint, requestHandler, undefined);
346
+ // Apply stashed ops with a reference sequence number equal to the sequence number of the snapshot,
347
+ // or zero. This must be done before Container replays saved ops.
348
+ await runtime.pendingStateManager.applyStashedOpsAt(runtimeSequenceNumber ?? 0);
349
+ // Initialize the base state of the runtime before it's returned.
350
+ await runtime.initializeBaseState();
351
+ return runtime;
352
+ }
353
+ get clientId() {
354
+ return this._getClientId();
355
+ }
356
+ get storage() {
357
+ return this._storage;
358
+ }
359
+ get flushMode() {
360
+ return this._flushMode;
361
+ }
362
+ get scope() {
363
+ return this.containerScope;
364
+ }
365
+ get IFluidDataStoreRegistry() {
366
+ return this.registry;
367
+ }
368
+ get attachState() {
369
+ return this._getAttachState();
370
+ }
371
+ get IFluidHandleContext() {
372
+ return this.handleContext;
373
+ }
374
+ /**
375
+ * Invokes the given callback and expects that no ops are submitted
376
+ * until execution finishes. If an op is submitted, an error will be raised.
377
+ *
378
+ * Can be disabled by feature gate `Fluid.ContainerRuntime.DisableOpReentryCheck`
379
+ *
380
+ * @param callback - the callback to be invoked
381
+ */
382
+ ensureNoDataModelChanges(callback) {
383
+ this.ensureNoDataModelChangesCalls++;
384
+ try {
385
+ return callback();
386
+ }
387
+ finally {
388
+ this.ensureNoDataModelChangesCalls--;
389
+ }
390
+ }
391
+ get connected() {
392
+ return this._connected;
393
+ }
394
+ /** clientId of parent (non-summarizing) container that owns summarizer container */
395
+ get summarizerClientId() {
396
+ return this.summarizerClientElection?.electedClientId;
397
+ }
398
+ get disposed() {
399
+ return this._disposed;
400
+ }
401
+ get summarizer() {
402
+ assert(this._summarizer !== undefined, 0x257 /* "This is not summarizing container" */);
403
+ return this._summarizer;
404
+ }
405
+ isSummariesDisabled() {
406
+ return this.summaryConfiguration.state === "disabled";
407
+ }
408
+ isHeuristicsDisabled() {
409
+ return this.summaryConfiguration.state === "disableHeuristics";
410
+ }
411
+ getMaxOpsSinceLastSummary() {
412
+ return this.summaryConfiguration.state !== "disabled"
413
+ ? this.summaryConfiguration.maxOpsSinceLastSummary
414
+ : 0;
415
+ }
416
+ getInitialSummarizerDelayMs() {
417
+ // back-compat: initialSummarizerDelayMs was moved from ISummaryRuntimeOptions
418
+ // to ISummaryConfiguration in 0.60.
419
+ if (this.runtimeOptions.summaryOptions.initialSummarizerDelayMs !== undefined) {
420
+ return this.runtimeOptions.summaryOptions.initialSummarizerDelayMs;
421
+ }
422
+ return this.summaryConfiguration.state !== "disabled"
423
+ ? this.summaryConfiguration.initialSummarizerDelayMs
424
+ : 0;
425
+ }
172
426
  /**
173
427
  * @internal
174
428
  */
175
- constructor(context, registry, metadata, electedSummarizerData, chunks, dataStoreAliasMap, runtimeOptions, containerScope, logger, existing, blobManagerSnapshot, _storage, idCompressor, requestHandler, summaryConfiguration = {
429
+ constructor(context, registry, metadata, electedSummarizerData, chunks, dataStoreAliasMap, runtimeOptions, containerScope, logger, existing, blobManagerSnapshot, _storage, idCompressor, provideEntryPoint, requestHandler, summaryConfiguration = {
176
430
  // the defaults
177
431
  ...DefaultSummaryConfiguration,
178
432
  // the runtime configuration overrides
179
433
  ...runtimeOptions.summaryOptions?.summaryConfigOverrides,
180
- }, initializeEntryPoint) {
434
+ }) {
181
435
  super();
182
436
  this.registry = registry;
183
437
  this.runtimeOptions = runtimeOptions;
@@ -469,7 +723,7 @@ export class ContainerRuntime extends TypedEventEmitter {
469
723
  this.summaryCollection.on("default", defaultAction);
470
724
  // Create the SummaryManager and mark the initial state
471
725
  this.summaryManager = new SummaryManager(this.summarizerClientElection, this, // IConnectedState
472
- this.summaryCollection, this.logger, this.formRequestSummarizerFn(loader), new Throttler(60 * 1000, // 60 sec delay window
726
+ this.summaryCollection, this.logger, this.formCreateSummarizerFn(loader), new Throttler(60 * 1000, // 60 sec delay window
473
727
  30 * 1000, // 30 sec max delay
474
728
  // throttling function increases exponentially (0ms, 40ms, 80ms, 160ms, etc)
475
729
  formExponentialFn({ coefficient: 20, initialDelay: 0 })), {
@@ -514,233 +768,9 @@ export class ContainerRuntime extends TypedEventEmitter {
514
768
  assert(this._summarizer !== undefined, 0x5bf /* Summarizer object is undefined in a summarizer client */);
515
769
  return this._summarizer;
516
770
  }
517
- return initializeEntryPoint?.(this);
771
+ return provideEntryPoint(this);
518
772
  });
519
773
  }
520
- /**
521
- * @deprecated - Will be removed in future major release. Migrate all usage of IFluidRouter to the "entryPoint" pattern. Refer to Removing-IFluidRouter.md
522
- */
523
- get IFluidRouter() {
524
- return this;
525
- }
526
- /**
527
- * @deprecated - use loadRuntime instead.
528
- * Load the stores from a snapshot and returns the runtime.
529
- * @param context - Context of the container.
530
- * @param registryEntries - Mapping to the stores.
531
- * @param requestHandler - Request handlers for the container runtime
532
- * @param runtimeOptions - Additional options to be passed to the runtime
533
- * @param existing - (optional) When loading from an existing snapshot. Precedes context.existing if provided
534
- * @param containerRuntimeCtor - (optional) Constructor to use to create the ContainerRuntime instance. This
535
- * allows mixin classes to leverage this method to define their own async initializer.
536
- */
537
- static async load(context, registryEntries, requestHandler, runtimeOptions = {}, containerScope = context.scope, existing, containerRuntimeCtor = ContainerRuntime) {
538
- let existingFlag = true;
539
- if (!existing) {
540
- existingFlag = false;
541
- }
542
- return this.loadRuntime({
543
- context,
544
- registryEntries,
545
- existing: existingFlag,
546
- requestHandler,
547
- runtimeOptions,
548
- containerScope,
549
- containerRuntimeCtor,
550
- });
551
- }
552
- /**
553
- * Load the stores from a snapshot and returns the runtime.
554
- * @param params - An object housing the runtime properties:
555
- * - context - Context of the container.
556
- * - registryEntries - Mapping from data store types to their corresponding factories.
557
- * - existing - Pass 'true' if loading from an existing snapshot.
558
- * - requestHandler - (optional) Request handler for the request() method of the container runtime.
559
- * Only relevant for back-compat while we remove the request() method and move fully to entryPoint as the main pattern.
560
- * - runtimeOptions - Additional options to be passed to the runtime
561
- * - containerScope - runtime services provided with context
562
- * - containerRuntimeCtor - Constructor to use to create the ContainerRuntime instance.
563
- * This allows mixin classes to leverage this method to define their own async initializer.
564
- * - initializeEntryPoint - Promise that resolves to an object which will act as entryPoint for the Container.
565
- * This object should provide all the functionality that the Container is expected to provide to the loader layer.
566
- */
567
- static async loadRuntime(params) {
568
- const { context, registryEntries, existing, requestHandler, runtimeOptions = {}, containerScope = {}, containerRuntimeCtor = ContainerRuntime, } = params;
569
- const initializeEntryPoint = params.initializeEntryPoint ??
570
- (async (containerRuntime) => ({
571
- get IFluidRouter() {
572
- return this;
573
- },
574
- async request(req) {
575
- return containerRuntime.request(req);
576
- },
577
- }));
578
- // If taggedLogger exists, use it. Otherwise, wrap the vanilla logger:
579
- // back-compat: Remove the TaggedLoggerAdapter fallback once all the host are using loader > 0.45
580
- const backCompatContext = context;
581
- const passLogger = backCompatContext.taggedLogger ??
582
- // eslint-disable-next-line import/no-deprecated
583
- new TaggedLoggerAdapter(backCompatContext.logger);
584
- const logger = createChildLogger({
585
- logger: passLogger,
586
- properties: {
587
- all: {
588
- runtimeVersion: pkgVersion,
589
- },
590
- },
591
- });
592
- const { summaryOptions = {}, gcOptions = {}, loadSequenceNumberVerification = "close", flushMode = defaultFlushMode, compressionOptions = defaultCompressionConfig, maxBatchSizeInBytes = defaultMaxBatchSizeInBytes, enableRuntimeIdCompressor = false, chunkSizeInBytes = defaultChunkSizeInBytes, enableOpReentryCheck = false, enableGroupedBatching = false, } = runtimeOptions;
593
- const registry = new FluidDataStoreRegistry(registryEntries);
594
- const tryFetchBlob = async (blobName) => {
595
- const blobId = context.baseSnapshot?.blobs[blobName];
596
- if (context.baseSnapshot && blobId) {
597
- // IContainerContext storage api return type still has undefined in 0.39 package version.
598
- // So once we release 0.40 container-defn package we can remove this check.
599
- assert(context.storage !== undefined, 0x1f5 /* "Attached state should have storage" */);
600
- return readAndParse(context.storage, blobId);
601
- }
602
- };
603
- const [chunks, metadata, electedSummarizerData, aliases, serializedIdCompressor] = await Promise.all([
604
- tryFetchBlob(chunksBlobName),
605
- tryFetchBlob(metadataBlobName),
606
- tryFetchBlob(electedSummarizerBlobName),
607
- tryFetchBlob(aliasBlobName),
608
- tryFetchBlob(idCompressorBlobName),
609
- ]);
610
- // read snapshot blobs needed for BlobManager to load
611
- const blobManagerSnapshot = await BlobManager.load(context.baseSnapshot?.trees[blobsTreeName], async (id) => {
612
- // IContainerContext storage api return type still has undefined in 0.39 package version.
613
- // So once we release 0.40 container-defn package we can remove this check.
614
- assert(context.storage !== undefined, 0x256 /* "storage undefined in attached container" */);
615
- return readAndParse(context.storage, id);
616
- });
617
- // Verify summary runtime sequence number matches protocol sequence number.
618
- const runtimeSequenceNumber = metadata?.message?.sequenceNumber;
619
- // When we load with pending state, we reuse an old snapshot so we don't expect these numbers to match
620
- if (!context.pendingLocalState && runtimeSequenceNumber !== undefined) {
621
- const protocolSequenceNumber = context.deltaManager.initialSequenceNumber;
622
- // Unless bypass is explicitly set, then take action when sequence numbers mismatch.
623
- if (loadSequenceNumberVerification !== "bypass" &&
624
- runtimeSequenceNumber !== protocolSequenceNumber) {
625
- // "Load from summary, runtime metadata sequenceNumber !== initialSequenceNumber"
626
- const error = new DataCorruptionError(
627
- // pre-0.58 error message: SummaryMetadataMismatch
628
- "Summary metadata mismatch", { runtimeVersion: pkgVersion, runtimeSequenceNumber, protocolSequenceNumber });
629
- if (loadSequenceNumberVerification === "log") {
630
- logger.sendErrorEvent({ eventName: "SequenceNumberMismatch" }, error);
631
- }
632
- else {
633
- context.closeFn(error);
634
- }
635
- }
636
- }
637
- const idCompressorEnabled = metadata?.idCompressorEnabled ?? runtimeOptions.enableRuntimeIdCompressor ?? false;
638
- let idCompressor;
639
- if (idCompressorEnabled) {
640
- const { IdCompressor, createSessionId } = await import("./id-compressor");
641
- idCompressor =
642
- serializedIdCompressor !== undefined
643
- ? IdCompressor.deserialize(serializedIdCompressor, createSessionId())
644
- : IdCompressor.create(logger);
645
- }
646
- const runtime = new containerRuntimeCtor(context, registry, metadata, electedSummarizerData, chunks ?? [], aliases ?? [], {
647
- summaryOptions,
648
- gcOptions,
649
- loadSequenceNumberVerification,
650
- flushMode,
651
- compressionOptions,
652
- maxBatchSizeInBytes,
653
- chunkSizeInBytes,
654
- enableRuntimeIdCompressor,
655
- enableOpReentryCheck,
656
- enableGroupedBatching,
657
- }, containerScope, logger, existing, blobManagerSnapshot, context.storage, idCompressor, requestHandler, undefined, // summaryConfiguration
658
- initializeEntryPoint);
659
- // Apply stashed ops with a reference sequence number equal to the sequence number of the snapshot,
660
- // or zero. This must be done before Container replays saved ops.
661
- await runtime.pendingStateManager.applyStashedOpsAt(runtimeSequenceNumber ?? 0);
662
- // Initialize the base state of the runtime before it's returned.
663
- await runtime.initializeBaseState();
664
- return runtime;
665
- }
666
- get clientId() {
667
- return this._getClientId();
668
- }
669
- get storage() {
670
- return this._storage;
671
- }
672
- /** @deprecated - The functionality is no longer exposed publicly */
673
- get reSubmitFn() {
674
- return (type, contents, localOpMetadata, opMetadata) => this.reSubmitCore({ type, contents }, localOpMetadata, opMetadata);
675
- // Note: compatDetails is not included in this deprecated API
676
- }
677
- get flushMode() {
678
- return this._flushMode;
679
- }
680
- get scope() {
681
- return this.containerScope;
682
- }
683
- get IFluidDataStoreRegistry() {
684
- return this.registry;
685
- }
686
- get attachState() {
687
- return this._getAttachState();
688
- }
689
- get IFluidHandleContext() {
690
- return this.handleContext;
691
- }
692
- /**
693
- * Invokes the given callback and expects that no ops are submitted
694
- * until execution finishes. If an op is submitted, an error will be raised.
695
- *
696
- * Can be disabled by feature gate `Fluid.ContainerRuntime.DisableOpReentryCheck`
697
- *
698
- * @param callback - the callback to be invoked
699
- */
700
- ensureNoDataModelChanges(callback) {
701
- this.ensureNoDataModelChangesCalls++;
702
- try {
703
- return callback();
704
- }
705
- finally {
706
- this.ensureNoDataModelChangesCalls--;
707
- }
708
- }
709
- get connected() {
710
- return this._connected;
711
- }
712
- /** clientId of parent (non-summarizing) container that owns summarizer container */
713
- get summarizerClientId() {
714
- return this.summarizerClientElection?.electedClientId;
715
- }
716
- get disposed() {
717
- return this._disposed;
718
- }
719
- get summarizer() {
720
- assert(this._summarizer !== undefined, 0x257 /* "This is not summarizing container" */);
721
- return this._summarizer;
722
- }
723
- isSummariesDisabled() {
724
- return this.summaryConfiguration.state === "disabled";
725
- }
726
- isHeuristicsDisabled() {
727
- return this.summaryConfiguration.state === "disableHeuristics";
728
- }
729
- getMaxOpsSinceLastSummary() {
730
- return this.summaryConfiguration.state !== "disabled"
731
- ? this.summaryConfiguration.maxOpsSinceLastSummary
732
- : 0;
733
- }
734
- getInitialSummarizerDelayMs() {
735
- // back-compat: initialSummarizerDelayMs was moved from ISummaryRuntimeOptions
736
- // to ISummaryConfiguration in 0.60.
737
- if (this.runtimeOptions.summaryOptions.initialSummarizerDelayMs !== undefined) {
738
- return this.runtimeOptions.summaryOptions.initialSummarizerDelayMs;
739
- }
740
- return this.summaryConfiguration.state !== "disabled"
741
- ? this.summaryConfiguration.initialSummarizerDelayMs
742
- : 0;
743
- }
744
774
  /**
745
775
  * Initializes the state from the base snapshot this container runtime loaded from.
746
776
  */
@@ -777,7 +807,7 @@ export class ContainerRuntime extends TypedEventEmitter {
777
807
  try {
778
808
  const parser = RequestParser.create(request);
779
809
  const id = parser.pathParts[0];
780
- if (id === "_summarizer" && parser.pathParts.length === 1) {
810
+ if (id === summarizerRequestUrl && parser.pathParts.length === 1) {
781
811
  if (this._summarizer !== undefined) {
782
812
  return {
783
813
  status: 200,
@@ -788,6 +818,7 @@ export class ContainerRuntime extends TypedEventEmitter {
788
818
  return create404Response(request);
789
819
  }
790
820
  if (this.requestHandler !== undefined) {
821
+ // eslint-disable-next-line @typescript-eslint/return-await -- Adding an await here causes test failures
791
822
  return this.requestHandler(parser, this);
792
823
  }
793
824
  return create404Response(request);
@@ -805,6 +836,7 @@ export class ContainerRuntime extends TypedEventEmitter {
805
836
  const requestParser = RequestParser.create(request);
806
837
  const id = requestParser.pathParts[0];
807
838
  if (id === "_channels") {
839
+ // eslint-disable-next-line @typescript-eslint/return-await -- Adding an await here causes test failures
808
840
  return this.resolveHandle(requestParser.createSubRequest(1));
809
841
  }
810
842
  if (id === BlobManager.basePath && requestParser.isLeaf(2)) {
@@ -823,6 +855,7 @@ export class ContainerRuntime extends TypedEventEmitter {
823
855
  // We always expect createSubRequest to include a leading slash, but asserting here to protect against
824
856
  // unintentionally modifying the url if that changes.
825
857
  assert(subRequest.url.startsWith("/"), 0x126 /* "Expected createSubRequest url to include a leading slash" */);
858
+ // eslint-disable-next-line @typescript-eslint/return-await -- Adding an await here causes test failures
826
859
  return dataStore.request(subRequest);
827
860
  }
828
861
  return create404Response(request);
@@ -1283,6 +1316,7 @@ export class ContainerRuntime extends TypedEventEmitter {
1283
1316
  * @param wait - True if you want to wait for it.
1284
1317
  * @deprecated - Use getAliasedDataStoreEntryPoint instead to get an aliased data store's entry point.
1285
1318
  */
1319
+ // eslint-disable-next-line import/no-deprecated
1286
1320
  async getRootDataStore(id, wait = true) {
1287
1321
  return this.getRootDataStoreChannel(id, wait);
1288
1322
  }
@@ -2466,29 +2500,11 @@ export class ContainerRuntime extends TypedEventEmitter {
2466
2500
  }
2467
2501
  }
2468
2502
  /**
2469
- * * Forms a function that will request a Summarizer.
2470
- * @param loaderRouter - the loader acting as an IFluidRouter
2471
- * */
2472
- formRequestSummarizerFn(loaderRouter) {
2503
+ * Forms a function that will create and retrieve a Summarizer.
2504
+ */
2505
+ formCreateSummarizerFn(loader) {
2473
2506
  return async () => {
2474
- const request = {
2475
- headers: {
2476
- [LoaderHeader.cache]: false,
2477
- [LoaderHeader.clientDetails]: {
2478
- capabilities: { interactive: false },
2479
- type: summarizerClientType,
2480
- },
2481
- [DriverHeader.summarizingClient]: true,
2482
- [LoaderHeader.reconnect]: false,
2483
- },
2484
- url: "/_summarizer",
2485
- };
2486
- const fluidObject = await requestFluidObject(loaderRouter, request);
2487
- const summarizer = fluidObject.ISummarizer;
2488
- if (!summarizer) {
2489
- throw new UsageError("Fluid object does not implement ISummarizer");
2490
- }
2491
- return summarizer;
2507
+ return createSummarizer(loader, `/${summarizerRequestUrl}`);
2492
2508
  };
2493
2509
  }
2494
2510
  validateSummaryHeuristicConfiguration(configuration) {