@fluidframework/container-runtime 2.0.0-internal.3.2.2 → 2.0.0-internal.3.3.1

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 (161) hide show
  1. package/dist/containerRuntime.d.ts +32 -53
  2. package/dist/containerRuntime.d.ts.map +1 -1
  3. package/dist/containerRuntime.js +40 -18
  4. package/dist/containerRuntime.js.map +1 -1
  5. package/dist/dataStores.d.ts.map +1 -1
  6. package/dist/dataStores.js +8 -3
  7. package/dist/dataStores.js.map +1 -1
  8. package/dist/deltaManagerSummarizerProxy.d.ts +19 -0
  9. package/dist/deltaManagerSummarizerProxy.d.ts.map +1 -0
  10. package/dist/deltaManagerSummarizerProxy.js +40 -0
  11. package/dist/deltaManagerSummarizerProxy.js.map +1 -0
  12. package/dist/gc/garbageCollection.d.ts +2 -33
  13. package/dist/gc/garbageCollection.d.ts.map +1 -1
  14. package/dist/gc/garbageCollection.js +36 -181
  15. package/dist/gc/garbageCollection.js.map +1 -1
  16. package/dist/gc/gcConfigs.d.ts +22 -0
  17. package/dist/gc/gcConfigs.d.ts.map +1 -0
  18. package/dist/gc/gcConfigs.js +138 -0
  19. package/dist/gc/gcConfigs.js.map +1 -0
  20. package/dist/gc/gcDefinitions.d.ts +101 -3
  21. package/dist/gc/gcDefinitions.d.ts.map +1 -1
  22. package/dist/gc/gcDefinitions.js +8 -3
  23. package/dist/gc/gcDefinitions.js.map +1 -1
  24. package/dist/gc/gcHelpers.d.ts +12 -1
  25. package/dist/gc/gcHelpers.d.ts.map +1 -1
  26. package/dist/gc/gcHelpers.js +55 -1
  27. package/dist/gc/gcHelpers.js.map +1 -1
  28. package/dist/gc/gcSummaryStateTracker.d.ts +1 -2
  29. package/dist/gc/gcSummaryStateTracker.d.ts.map +1 -1
  30. package/dist/gc/gcSummaryStateTracker.js +28 -37
  31. package/dist/gc/gcSummaryStateTracker.js.map +1 -1
  32. package/dist/gc/index.d.ts +3 -2
  33. package/dist/gc/index.d.ts.map +1 -1
  34. package/dist/gc/index.js +2 -1
  35. package/dist/gc/index.js.map +1 -1
  36. package/dist/index.d.ts +2 -2
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js.map +1 -1
  39. package/dist/opLifecycle/batchManager.d.ts +9 -0
  40. package/dist/opLifecycle/batchManager.d.ts.map +1 -1
  41. package/dist/opLifecycle/batchManager.js +19 -2
  42. package/dist/opLifecycle/batchManager.js.map +1 -1
  43. package/dist/opLifecycle/index.d.ts +1 -1
  44. package/dist/opLifecycle/index.d.ts.map +1 -1
  45. package/dist/opLifecycle/index.js +2 -1
  46. package/dist/opLifecycle/index.js.map +1 -1
  47. package/dist/opLifecycle/opCompressor.d.ts.map +1 -1
  48. package/dist/opLifecycle/opCompressor.js +24 -10
  49. package/dist/opLifecycle/opCompressor.js.map +1 -1
  50. package/dist/opLifecycle/opSplitter.d.ts +14 -2
  51. package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
  52. package/dist/opLifecycle/opSplitter.js +35 -18
  53. package/dist/opLifecycle/opSplitter.js.map +1 -1
  54. package/dist/opLifecycle/outbox.d.ts.map +1 -1
  55. package/dist/opLifecycle/outbox.js +25 -19
  56. package/dist/opLifecycle/outbox.js.map +1 -1
  57. package/dist/packageVersion.d.ts +1 -1
  58. package/dist/packageVersion.js +1 -1
  59. package/dist/packageVersion.js.map +1 -1
  60. package/dist/storageServiceWithAttachBlobs.d.ts +17 -0
  61. package/dist/storageServiceWithAttachBlobs.d.ts.map +1 -0
  62. package/dist/storageServiceWithAttachBlobs.js +32 -0
  63. package/dist/storageServiceWithAttachBlobs.js.map +1 -0
  64. package/dist/summary/runWhileConnectedCoordinator.d.ts +3 -2
  65. package/dist/summary/runWhileConnectedCoordinator.d.ts.map +1 -1
  66. package/dist/summary/runWhileConnectedCoordinator.js +5 -4
  67. package/dist/summary/runWhileConnectedCoordinator.js.map +1 -1
  68. package/dist/summary/summarizerTypes.d.ts +2 -0
  69. package/dist/summary/summarizerTypes.d.ts.map +1 -1
  70. package/dist/summary/summarizerTypes.js.map +1 -1
  71. package/lib/containerRuntime.d.ts +32 -53
  72. package/lib/containerRuntime.d.ts.map +1 -1
  73. package/lib/containerRuntime.js +41 -19
  74. package/lib/containerRuntime.js.map +1 -1
  75. package/lib/dataStores.d.ts.map +1 -1
  76. package/lib/dataStores.js +9 -4
  77. package/lib/dataStores.js.map +1 -1
  78. package/lib/deltaManagerSummarizerProxy.d.ts +19 -0
  79. package/lib/deltaManagerSummarizerProxy.d.ts.map +1 -0
  80. package/lib/deltaManagerSummarizerProxy.js +36 -0
  81. package/lib/deltaManagerSummarizerProxy.js.map +1 -0
  82. package/lib/gc/garbageCollection.d.ts +2 -33
  83. package/lib/gc/garbageCollection.d.ts.map +1 -1
  84. package/lib/gc/garbageCollection.js +39 -184
  85. package/lib/gc/garbageCollection.js.map +1 -1
  86. package/lib/gc/gcConfigs.d.ts +22 -0
  87. package/lib/gc/gcConfigs.d.ts.map +1 -0
  88. package/lib/gc/gcConfigs.js +134 -0
  89. package/lib/gc/gcConfigs.js.map +1 -0
  90. package/lib/gc/gcDefinitions.d.ts +101 -3
  91. package/lib/gc/gcDefinitions.d.ts.map +1 -1
  92. package/lib/gc/gcDefinitions.js +7 -2
  93. package/lib/gc/gcDefinitions.js.map +1 -1
  94. package/lib/gc/gcHelpers.d.ts +12 -1
  95. package/lib/gc/gcHelpers.d.ts.map +1 -1
  96. package/lib/gc/gcHelpers.js +53 -0
  97. package/lib/gc/gcHelpers.js.map +1 -1
  98. package/lib/gc/gcSummaryStateTracker.d.ts +1 -2
  99. package/lib/gc/gcSummaryStateTracker.d.ts.map +1 -1
  100. package/lib/gc/gcSummaryStateTracker.js +28 -37
  101. package/lib/gc/gcSummaryStateTracker.js.map +1 -1
  102. package/lib/gc/index.d.ts +3 -2
  103. package/lib/gc/index.d.ts.map +1 -1
  104. package/lib/gc/index.js +1 -1
  105. package/lib/gc/index.js.map +1 -1
  106. package/lib/index.d.ts +2 -2
  107. package/lib/index.d.ts.map +1 -1
  108. package/lib/index.js.map +1 -1
  109. package/lib/opLifecycle/batchManager.d.ts +9 -0
  110. package/lib/opLifecycle/batchManager.d.ts.map +1 -1
  111. package/lib/opLifecycle/batchManager.js +17 -1
  112. package/lib/opLifecycle/batchManager.js.map +1 -1
  113. package/lib/opLifecycle/index.d.ts +1 -1
  114. package/lib/opLifecycle/index.d.ts.map +1 -1
  115. package/lib/opLifecycle/index.js +1 -1
  116. package/lib/opLifecycle/index.js.map +1 -1
  117. package/lib/opLifecycle/opCompressor.d.ts.map +1 -1
  118. package/lib/opLifecycle/opCompressor.js +25 -11
  119. package/lib/opLifecycle/opCompressor.js.map +1 -1
  120. package/lib/opLifecycle/opSplitter.d.ts +14 -2
  121. package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
  122. package/lib/opLifecycle/opSplitter.js +35 -18
  123. package/lib/opLifecycle/opSplitter.js.map +1 -1
  124. package/lib/opLifecycle/outbox.d.ts.map +1 -1
  125. package/lib/opLifecycle/outbox.js +26 -20
  126. package/lib/opLifecycle/outbox.js.map +1 -1
  127. package/lib/packageVersion.d.ts +1 -1
  128. package/lib/packageVersion.js +1 -1
  129. package/lib/packageVersion.js.map +1 -1
  130. package/lib/storageServiceWithAttachBlobs.d.ts +17 -0
  131. package/lib/storageServiceWithAttachBlobs.d.ts.map +1 -0
  132. package/lib/storageServiceWithAttachBlobs.js +28 -0
  133. package/lib/storageServiceWithAttachBlobs.js.map +1 -0
  134. package/lib/summary/runWhileConnectedCoordinator.d.ts +3 -2
  135. package/lib/summary/runWhileConnectedCoordinator.d.ts.map +1 -1
  136. package/lib/summary/runWhileConnectedCoordinator.js +5 -4
  137. package/lib/summary/runWhileConnectedCoordinator.js.map +1 -1
  138. package/lib/summary/summarizerTypes.d.ts +2 -0
  139. package/lib/summary/summarizerTypes.d.ts.map +1 -1
  140. package/lib/summary/summarizerTypes.js.map +1 -1
  141. package/package.json +20 -31
  142. package/src/containerRuntime.ts +71 -74
  143. package/src/dataStores.ts +9 -4
  144. package/src/deltaManagerSummarizerProxy.ts +46 -0
  145. package/src/gc/garbageCollection.ts +50 -290
  146. package/src/gc/gcConfigs.ts +177 -0
  147. package/src/gc/gcDefinitions.ts +110 -4
  148. package/src/gc/gcHelpers.ts +78 -1
  149. package/src/gc/gcSummaryStateTracker.ts +35 -42
  150. package/src/gc/index.ts +8 -2
  151. package/src/index.ts +1 -2
  152. package/src/opLifecycle/README.md +2 -2
  153. package/src/opLifecycle/batchManager.ts +19 -1
  154. package/src/opLifecycle/index.ts +1 -1
  155. package/src/opLifecycle/opCompressor.ts +31 -12
  156. package/src/opLifecycle/opSplitter.ts +44 -20
  157. package/src/opLifecycle/outbox.ts +32 -20
  158. package/src/packageVersion.ts +1 -1
  159. package/src/storageServiceWithAttachBlobs.ts +38 -0
  160. package/src/summary/runWhileConnectedCoordinator.ts +7 -7
  161. package/src/summary/summarizerTypes.ts +2 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/container-runtime",
3
- "version": "2.0.0-internal.3.2.2",
3
+ "version": "2.0.0-internal.3.3.1",
4
4
  "description": "Fluid container runtime",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": {
@@ -37,32 +37,32 @@
37
37
  "dependencies": {
38
38
  "@fluidframework/common-definitions": "^0.20.1",
39
39
  "@fluidframework/common-utils": "^1.1.1",
40
- "@fluidframework/container-definitions": ">=2.0.0-internal.3.2.2 <2.0.0-internal.4.0.0",
41
- "@fluidframework/container-runtime-definitions": ">=2.0.0-internal.3.2.2 <2.0.0-internal.4.0.0",
42
- "@fluidframework/container-utils": ">=2.0.0-internal.3.2.2 <2.0.0-internal.4.0.0",
43
- "@fluidframework/core-interfaces": ">=2.0.0-internal.3.2.2 <2.0.0-internal.4.0.0",
44
- "@fluidframework/datastore": ">=2.0.0-internal.3.2.2 <2.0.0-internal.4.0.0",
45
- "@fluidframework/driver-definitions": ">=2.0.0-internal.3.2.2 <2.0.0-internal.4.0.0",
46
- "@fluidframework/driver-utils": ">=2.0.0-internal.3.2.2 <2.0.0-internal.4.0.0",
47
- "@fluidframework/garbage-collector": ">=2.0.0-internal.3.2.2 <2.0.0-internal.4.0.0",
48
- "@fluidframework/protocol-base": "^0.1038.2000",
40
+ "@fluidframework/container-definitions": ">=2.0.0-internal.3.3.1 <2.0.0-internal.4.0.0",
41
+ "@fluidframework/container-runtime-definitions": ">=2.0.0-internal.3.3.1 <2.0.0-internal.4.0.0",
42
+ "@fluidframework/container-utils": ">=2.0.0-internal.3.3.1 <2.0.0-internal.4.0.0",
43
+ "@fluidframework/core-interfaces": ">=2.0.0-internal.3.3.1 <2.0.0-internal.4.0.0",
44
+ "@fluidframework/datastore": ">=2.0.0-internal.3.3.1 <2.0.0-internal.4.0.0",
45
+ "@fluidframework/driver-definitions": ">=2.0.0-internal.3.3.1 <2.0.0-internal.4.0.0",
46
+ "@fluidframework/driver-utils": ">=2.0.0-internal.3.3.1 <2.0.0-internal.4.0.0",
47
+ "@fluidframework/garbage-collector": ">=2.0.0-internal.3.3.1 <2.0.0-internal.4.0.0",
48
+ "@fluidframework/protocol-base": "^0.1038.3000",
49
49
  "@fluidframework/protocol-definitions": "^1.1.0",
50
- "@fluidframework/runtime-definitions": ">=2.0.0-internal.3.2.2 <2.0.0-internal.4.0.0",
51
- "@fluidframework/runtime-utils": ">=2.0.0-internal.3.2.2 <2.0.0-internal.4.0.0",
52
- "@fluidframework/telemetry-utils": ">=2.0.0-internal.3.2.2 <2.0.0-internal.4.0.0",
50
+ "@fluidframework/runtime-definitions": ">=2.0.0-internal.3.3.1 <2.0.0-internal.4.0.0",
51
+ "@fluidframework/runtime-utils": ">=2.0.0-internal.3.3.1 <2.0.0-internal.4.0.0",
52
+ "@fluidframework/telemetry-utils": ">=2.0.0-internal.3.3.1 <2.0.0-internal.4.0.0",
53
53
  "double-ended-queue": "^2.1.0-0",
54
54
  "events": "^3.1.0",
55
55
  "lz4js": "^0.2.0",
56
56
  "uuid": "^8.3.1"
57
57
  },
58
58
  "devDependencies": {
59
- "@fluid-tools/build-cli": "^0.10.0",
59
+ "@fluid-tools/build-cli": "^0.12.0",
60
60
  "@fluidframework/build-common": "^1.1.0",
61
- "@fluidframework/build-tools": "^0.10.0",
62
- "@fluidframework/container-runtime-previous": "npm:@fluidframework/container-runtime@2.0.0-internal.3.1.0",
61
+ "@fluidframework/build-tools": "^0.12.0",
62
+ "@fluidframework/container-runtime-previous": "npm:@fluidframework/container-runtime@2.0.0-internal.3.2.0",
63
63
  "@fluidframework/eslint-config-fluid": "^2.0.0",
64
- "@fluidframework/mocha-test-setup": ">=2.0.0-internal.3.2.2 <2.0.0-internal.4.0.0",
65
- "@fluidframework/test-runtime-utils": ">=2.0.0-internal.3.2.2 <2.0.0-internal.4.0.0",
64
+ "@fluidframework/mocha-test-setup": ">=2.0.0-internal.3.3.1 <2.0.0-internal.4.0.0",
65
+ "@fluidframework/test-runtime-utils": ">=2.0.0-internal.3.3.1 <2.0.0-internal.4.0.0",
66
66
  "@microsoft/api-extractor": "^7.22.2",
67
67
  "@rushstack/eslint-config": "^2.5.1",
68
68
  "@types/double-ended-queue": "^2.1.0",
@@ -82,18 +82,7 @@
82
82
  "typescript": "~4.5.5"
83
83
  },
84
84
  "typeValidation": {
85
- "version": "2.0.0-internal.3.2.0",
86
- "previousVersionStyle": "~previousMinor",
87
- "baselineRange": ">=2.0.0-internal.3.1.0 <2.0.0-internal.3.2.0",
88
- "baselineVersion": "2.0.0-internal.3.1.0",
89
- "broken": {
90
- "EnumDeclaration_RuntimeHeaders": {
91
- "forwardCompat": false
92
- },
93
- "ClassDeclaration_ContainerRuntime": {
94
- "forwardCompat": false
95
- }
96
- }
85
+ "broken": {}
97
86
  },
98
87
  "scripts": {
99
88
  "build": "npm run build:genver && concurrently npm:build:compile npm:lint && npm run build:docs",
@@ -120,7 +109,7 @@
120
109
  "test:mocha:verbose": "cross-env FLUID_TEST_VERBOSE=1 npm run test:mocha",
121
110
  "tsc": "tsc",
122
111
  "tsc:watch": "tsc --watch",
123
- "typetests:gen": "flub generate typetests --generate --dir .",
112
+ "typetests:gen": "fluid-type-test-generator",
124
113
  "typetests:prepare": "flub generate typetests --prepare --dir . --pin"
125
114
  }
126
115
  }
@@ -31,7 +31,13 @@ import {
31
31
  IContainerRuntime,
32
32
  IContainerRuntimeEvents,
33
33
  } from "@fluidframework/container-runtime-definitions";
34
- import { assert, Trace, TypedEventEmitter, unreachableCase } from "@fluidframework/common-utils";
34
+ import {
35
+ assert,
36
+ LazyPromise,
37
+ Trace,
38
+ TypedEventEmitter,
39
+ unreachableCase,
40
+ } from "@fluidframework/common-utils";
35
41
  import {
36
42
  ChildLogger,
37
43
  raiseConnectedEvent,
@@ -147,8 +153,8 @@ import {
147
153
  GarbageCollector,
148
154
  GCNodeType,
149
155
  gcTombstoneGenerationOptionName,
150
- IGarbageCollectionRuntime,
151
156
  IGarbageCollector,
157
+ IGCRuntimeOptions,
152
158
  IGCStats,
153
159
  shouldAllowGcTombstoneEnforcement,
154
160
  } from "./gc";
@@ -168,6 +174,7 @@ import {
168
174
  OpSplitter,
169
175
  RemoteMessageProcessor,
170
176
  } from "./opLifecycle";
177
+ import { DeltaManagerSummarizerProxy } from "./deltaManagerSummarizerProxy";
171
178
 
172
179
  export enum ContainerMessageType {
173
180
  // An op to be delivered to store
@@ -312,54 +319,6 @@ export const DefaultSummaryConfiguration: ISummaryConfiguration = {
312
319
  nonRuntimeHeuristicThreshold: 20,
313
320
  };
314
321
 
315
- export interface IGCRuntimeOptions {
316
- /**
317
- * Flag that if true, will enable running garbage collection (GC) for a new container.
318
- *
319
- * GC has mark phase and sweep phase. In mark phase, unreferenced objects are identified
320
- * and marked as such in the summary. This option enables the mark phase.
321
- * In sweep phase, unreferenced objects are eventually deleted from the container if they meet certain conditions.
322
- * Sweep phase can be enabled via the "sweepAllowed" option.
323
- *
324
- * Note: This setting is persisted in the container's summary and cannot be changed.
325
- */
326
- gcAllowed?: boolean;
327
-
328
- /**
329
- * Flag that if true, enables GC's sweep phase for a new container.
330
- *
331
- * This will allow GC to eventually delete unreferenced objects from the container.
332
- * This flag should only be set to true if "gcAllowed" is true.
333
- *
334
- * Note: This setting is persisted in the container's summary and cannot be changed.
335
- */
336
- sweepAllowed?: boolean;
337
-
338
- /**
339
- * Flag that if true, will disable garbage collection for the session.
340
- * Can be used to disable running GC on containers where it is allowed via the gcAllowed option.
341
- */
342
- disableGC?: boolean;
343
-
344
- /**
345
- * Flag that will bypass optimizations and generate GC data for all nodes irrespective of whether a node
346
- * changed or not.
347
- */
348
- runFullGC?: boolean;
349
-
350
- /**
351
- * Maximum session duration for a new container. If not present, a default value will be used.
352
- *
353
- * Note: This setting is persisted in the container's summary and cannot be changed.
354
- */
355
- sessionExpiryTimeoutMs?: number;
356
-
357
- /**
358
- * Allows additional GC options to be passed.
359
- */
360
- [key: string]: any;
361
- }
362
-
363
322
  export interface ISummaryRuntimeOptions {
364
323
  /** Override summary configurations set by the server. */
365
324
  summaryConfigOverrides?: ISummaryConfiguration;
@@ -433,7 +392,8 @@ export interface IContainerRuntimeOptions {
433
392
  readonly maxBatchSizeInBytes?: number;
434
393
  /**
435
394
  * If the op payload needs to be chunked in order to work around the maximum size of the batch, this value represents
436
- * how large the individual chunks will be. This is only supported when compression is enabled.
395
+ * how large the individual chunks will be. This is only supported when compression is enabled. If after compression, the
396
+ * batch size exceeds this value, it will be chunked into smaller ops of this size.
437
397
  *
438
398
  * If unspecified, if a batch exceeds `maxBatchSizeInBytes` after compression, the container will close with an instance
439
399
  * of `GenericError` with the `BatchTooLarge` message.
@@ -598,12 +558,7 @@ export function getDeviceSpec() {
598
558
  */
599
559
  export class ContainerRuntime
600
560
  extends TypedEventEmitter<IContainerRuntimeEvents>
601
- implements
602
- IContainerRuntime,
603
- IGarbageCollectionRuntime,
604
- IRuntime,
605
- ISummarizerRuntime,
606
- ISummarizerInternalsProvider
561
+ implements IContainerRuntime, IRuntime, ISummarizerRuntime, ISummarizerInternalsProvider
607
562
  {
608
563
  public get IContainerRuntime() {
609
564
  return this;
@@ -651,13 +606,16 @@ export class ContainerRuntime
651
606
  * Load the stores from a snapshot and returns the runtime.
652
607
  * @param params - An object housing the runtime properties:
653
608
  * - context - Context of the container.
654
- * - registryEntries - Mapping to the stores.
655
- * - existing - When loading from an existing snapshot
656
- * - requestHandler - Request handlers for the container runtime
609
+ * - registryEntries - Mapping from data store types to their corresponding factories.
610
+ * - existing - Pass 'true' if loading from an existing snapshot.
611
+ * - requestHandler - (optional) Request handler for the request() method of the container runtime.
612
+ * Only relevant for back-compat while we remove the request() method and move fully to entryPoint as the main pattern.
657
613
  * - runtimeOptions - Additional options to be passed to the runtime
658
614
  * - containerScope - runtime services provided with context
659
615
  * - containerRuntimeCtor - Constructor to use to create the ContainerRuntime instance.
660
616
  * This allows mixin classes to leverage this method to define their own async initializer.
617
+ * - initializeEntryPoint - Promise that resolves to an object which will act as entryPoint for the Container.
618
+ * This object should provide all the functionality that the Container is expected to provide to the loader layer.
661
619
  */
662
620
  public static async loadRuntime(params: {
663
621
  context: IContainerContext;
@@ -667,6 +625,7 @@ export class ContainerRuntime
667
625
  runtimeOptions?: IContainerRuntimeOptions;
668
626
  containerScope?: FluidObject;
669
627
  containerRuntimeCtor?: typeof ContainerRuntime;
628
+ initializeEntryPoint?: (containerRuntime: IContainerRuntime) => Promise<FluidObject>;
670
629
  }): Promise<ContainerRuntime> {
671
630
  const {
672
631
  context,
@@ -676,6 +635,7 @@ export class ContainerRuntime
676
635
  runtimeOptions = {},
677
636
  containerScope = {},
678
637
  containerRuntimeCtor = ContainerRuntime,
638
+ initializeEntryPoint,
679
639
  } = params;
680
640
 
681
641
  // If taggedLogger exists, use it. Otherwise, wrap the vanilla logger:
@@ -800,6 +760,8 @@ export class ContainerRuntime
800
760
  blobManagerSnapshot,
801
761
  storage,
802
762
  requestHandler,
763
+ undefined, // summaryConfiguration
764
+ initializeEntryPoint,
803
765
  );
804
766
 
805
767
  if (pendingRuntimeState) {
@@ -826,10 +788,6 @@ export class ContainerRuntime
826
788
  return this.context.clientDetails;
827
789
  }
828
790
 
829
- public get deltaManager(): IDeltaManager<ISequencedDocumentMessage, IDocumentMessage> {
830
- return this.context.deltaManager;
831
- }
832
-
833
791
  public get storage(): IDocumentStorageService {
834
792
  return this._storage;
835
793
  }
@@ -878,6 +836,19 @@ export class ContainerRuntime
878
836
  }
879
837
  private readonly handleContext: ContainerFluidHandleContext;
880
838
 
839
+ /**
840
+ * This is a proxy to the delta manager provided by the container context (innerDeltaManager). It restricts certain
841
+ * accesses such as sets "read-only" mode for the summarizer client. This is the default delta manager that should
842
+ * be used unless the innerDeltaManager is required.
843
+ */
844
+ public readonly deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>;
845
+ /**
846
+ * The delta manager provided by the container context. By default, using the default delta manager (proxy)
847
+ * should be sufficient. This should be used only if necessary. For example, for validating and propagating connected
848
+ * events which requires access to the actual real only info, this is needed.
849
+ */
850
+ private readonly innerDeltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>;
851
+
881
852
  // internal logger for ContainerRuntime. Use this.logger for stores, summaries, etc.
882
853
  private readonly mc: MonitoringContext;
883
854
 
@@ -976,7 +947,6 @@ export class ContainerRuntime
976
947
  private readonly blobManager: BlobManager;
977
948
  private readonly pendingStateManager: PendingStateManager;
978
949
  private readonly outbox: Outbox;
979
-
980
950
  private readonly garbageCollector: IGarbageCollector;
981
951
 
982
952
  private readonly dataStores: DataStores;
@@ -1057,9 +1027,13 @@ export class ContainerRuntime
1057
1027
  // the runtime configuration overrides
1058
1028
  ...runtimeOptions.summaryOptions?.summaryConfigOverrides,
1059
1029
  },
1030
+ initializeEntryPoint?: (containerRuntime: IContainerRuntime) => Promise<FluidObject>,
1060
1031
  ) {
1061
1032
  super();
1062
1033
 
1034
+ this.innerDeltaManager = context.deltaManager;
1035
+ this.deltaManager = new DeltaManagerSummarizerProxy(context.deltaManager);
1036
+
1063
1037
  let loadSummaryNumber: number;
1064
1038
  // Get the container creation metadata. For new container, we initialize these. For existing containers,
1065
1039
  // get the values from the metadata blob.
@@ -1180,7 +1154,9 @@ export class ContainerRuntime
1180
1154
  getLastSummaryTimestampMs: () => this.messageAtLastSummary?.timestamp,
1181
1155
  readAndParseBlob: async <T>(id: string) => readAndParse<T>(this.storage, id),
1182
1156
  getContainerDiagnosticId: () => this.context.id,
1183
- activeConnection: () => this.deltaManager.active,
1157
+ // GC runs in summarizer client and needs access to the real (non-proxy) active information. The proxy
1158
+ // delta manager would always return false for summarizer client.
1159
+ activeConnection: () => this.innerDeltaManager.active,
1184
1160
  });
1185
1161
 
1186
1162
  const loadedFromSequenceNumber = this.deltaManager.initialSequenceNumber;
@@ -1349,7 +1325,12 @@ export class ContainerRuntime
1349
1325
  this.handleContext,
1350
1326
  this.summaryCollection,
1351
1327
  async (runtime: IConnectableRuntime) =>
1352
- RunWhileConnectedCoordinator.create(runtime),
1328
+ RunWhileConnectedCoordinator.create(
1329
+ runtime,
1330
+ // Summarization runs in summarizer client and needs access to the real (non-proxy) active
1331
+ // information. The proxy delta manager would always return false for summarizer client.
1332
+ () => this.innerDeltaManager.active,
1333
+ ),
1353
1334
  );
1354
1335
  } else if (
1355
1336
  SummarizerClientElection.clientDetailsPermitElection(this.context.clientDetails)
@@ -1399,8 +1380,9 @@ export class ContainerRuntime
1399
1380
  this.deltaManager.on("readonly", (readonly: boolean) => {
1400
1381
  // we accumulate ops while being in read-only state.
1401
1382
  // once user gets write permissions and we have active connection, flush all pending ops.
1383
+ // Note that the inner (non-proxy) delta manager is needed here to get the readonly information.
1402
1384
  assert(
1403
- readonly === this.deltaManager.readOnlyInfo.readonly,
1385
+ readonly === this.innerDeltaManager.readOnlyInfo.readonly,
1404
1386
  0x124 /* "inconsistent readonly property/event state" */,
1405
1387
  );
1406
1388
 
@@ -1450,6 +1432,8 @@ export class ContainerRuntime
1450
1432
 
1451
1433
  ReportOpPerfTelemetry(this.context.clientId, this.deltaManager, this.logger);
1452
1434
  BindBatchTracker(this, this.logger);
1435
+
1436
+ this.entryPoint = new LazyPromise(async () => initializeEntryPoint?.(this));
1453
1437
  }
1454
1438
 
1455
1439
  /**
@@ -1569,6 +1553,14 @@ export class ContainerRuntime
1569
1553
  }
1570
1554
  }
1571
1555
 
1556
+ /**
1557
+ * {@inheritDoc @fluidframework/container-definitions#IRuntime.getEntryPoint}
1558
+ */
1559
+ public async getEntryPoint?(): Promise<FluidObject | undefined> {
1560
+ return this.entryPoint;
1561
+ }
1562
+ private readonly entryPoint: LazyPromise<FluidObject | undefined>;
1563
+
1572
1564
  private internalId(maybeAlias: string): string {
1573
1565
  return this.dataStores.aliases.get(maybeAlias) ?? maybeAlias;
1574
1566
  }
@@ -1760,8 +1752,9 @@ export class ContainerRuntime
1760
1752
  // If attachment blobs were added while disconnected, we need to delay
1761
1753
  // propagation of the "connected" event until we have uploaded them to
1762
1754
  // ensure we don't submit ops referencing a blob that has not been uploaded
1755
+ // Note that the inner (non-proxy) delta manager is needed here to get the readonly information.
1763
1756
  const connecting =
1764
- connected && !this._connected && !this.deltaManager.readOnlyInfo.readonly;
1757
+ connected && !this._connected && !this.innerDeltaManager.readOnlyInfo.readonly;
1765
1758
  if (connecting && this.blobManager.hasPendingOfflineUploads) {
1766
1759
  assert(
1767
1760
  !this.delayConnectClientId,
@@ -2126,7 +2119,9 @@ export class ContainerRuntime
2126
2119
  }
2127
2120
 
2128
2121
  private canSendOps() {
2129
- return this.connected && !this.deltaManager.readOnlyInfo.readonly;
2122
+ // Note that the real (non-proxy) delta manager is needed here to get the readonly info. This is because
2123
+ // container runtime's ability to send ops depend on the actual readonly state of the delta manager.
2124
+ return this.connected && !this.innerDeltaManager.readOnlyInfo.readonly;
2130
2125
  }
2131
2126
 
2132
2127
  /**
@@ -2358,10 +2353,10 @@ export class ContainerRuntime
2358
2353
  }
2359
2354
 
2360
2355
  /**
2361
- * Implementation of IGarbageCollectionRuntime::updateStateBeforeGC.
2362
2356
  * Before GC runs, called by the garbage collector to update any pending GC state. This is mainly used to notify
2363
2357
  * the garbage collector of references detected since the last GC run. Most references are notified immediately
2364
2358
  * but there can be some for which async operation is required (such as detecting new root data stores).
2359
+ * @see IGarbageCollectionRuntime.updateStateBeforeGC
2365
2360
  */
2366
2361
  public async updateStateBeforeGC() {
2367
2362
  return this.dataStores.updateStateBeforeGC();
@@ -2372,9 +2367,9 @@ export class ContainerRuntime
2372
2367
  }
2373
2368
 
2374
2369
  /**
2375
- * Implementation of IGarbageCollectionRuntime::getGCData.
2376
2370
  * Generates and returns the GC data for this container.
2377
2371
  * @param fullGC - true to bypass optimizations and force full generation of GC data.
2372
+ * @see IGarbageCollectionRuntime.getGCData
2378
2373
  */
2379
2374
  public async getGCData(fullGC?: boolean): Promise<IGarbageCollectionData> {
2380
2375
  const builder = new GCDataBuilder();
@@ -2387,9 +2382,9 @@ export class ContainerRuntime
2387
2382
  }
2388
2383
 
2389
2384
  /**
2390
- * Implementation of IGarbageCollectionRuntime::updateUsedRoutes.
2391
2385
  * After GC has run, called to notify this container's nodes of routes that are used in it.
2392
2386
  * @param usedRoutes - The routes that are used in all nodes in this Container.
2387
+ * @see IGarbageCollectionRuntime.updateUsedRoutes
2393
2388
  */
2394
2389
  public updateUsedRoutes(usedRoutes: string[]) {
2395
2390
  // Update our summarizer node's used routes. Updating used routes in summarizer node before
@@ -2853,7 +2848,9 @@ export class ContainerRuntime
2853
2848
 
2854
2849
  const serializedContent = JSON.stringify({ type, contents });
2855
2850
 
2856
- if (this.deltaManager.readOnlyInfo.readonly) {
2851
+ // Note that the real (non-proxy) delta manager is used here to get the readonly info. This is because
2852
+ // container runtime's ability to submit ops depend on the actual readonly state of the delta manager.
2853
+ if (this.innerDeltaManager.readOnlyInfo.readonly) {
2857
2854
  this.logger.sendTelemetryEvent({
2858
2855
  eventName: "SubmitOpInReadonly",
2859
2856
  connected: this.connected,
package/src/dataStores.ts CHANGED
@@ -43,7 +43,7 @@ import {
43
43
  TelemetryDataTag,
44
44
  } from "@fluidframework/telemetry-utils";
45
45
  import { AttachState } from "@fluidframework/container-definitions";
46
- import { BlobCacheStorageService, buildSnapshotTree } from "@fluidframework/driver-utils";
46
+ import { buildSnapshotTree } from "@fluidframework/driver-utils";
47
47
  import { assert, Lazy } from "@fluidframework/common-utils";
48
48
  import { v4 as uuid } from "uuid";
49
49
  import { GCDataBuilder, unpackChildNodesUsedRoutes } from "@fluidframework/garbage-collector";
@@ -61,6 +61,7 @@ import {
61
61
  createAttributesBlob,
62
62
  LocalDetachedFluidDataStoreContext,
63
63
  } from "./dataStoreContext";
64
+ import { StorageServiceWithAttachBlobs } from "./storageServiceWithAttachBlobs";
64
65
  import { IDataStoreAliasMessage, isDataStoreAliasMessage } from "./dataStore";
65
66
  import {
66
67
  GCNodeType,
@@ -245,10 +246,10 @@ export class DataStores implements IDisposable {
245
246
  throw error;
246
247
  }
247
248
 
248
- const flatBlobs = new Map<string, ArrayBufferLike>();
249
+ const flatAttachBlobs = new Map<string, ArrayBufferLike>();
249
250
  let snapshotTree: ISnapshotTree | undefined;
250
251
  if (attachMessage.snapshot) {
251
- snapshotTree = buildSnapshotTree(attachMessage.snapshot.entries, flatBlobs);
252
+ snapshotTree = buildSnapshotTree(attachMessage.snapshot.entries, flatAttachBlobs);
252
253
  }
253
254
 
254
255
  // Include the type of attach message which is the pkg of the store to be
@@ -258,7 +259,7 @@ export class DataStores implements IDisposable {
258
259
  id: attachMessage.id,
259
260
  snapshotTree,
260
261
  runtime: this.runtime,
261
- storage: new BlobCacheStorageService(this.runtime.storage, flatBlobs),
262
+ storage: new StorageServiceWithAttachBlobs(this.runtime.storage, flatAttachBlobs),
262
263
  scope: this.runtime.scope,
263
264
  createSummarizerNodeFn: this.getCreateChildSummarizerNodeFn(attachMessage.id, {
264
265
  type: CreateSummarizerNodeSource.FromAttach,
@@ -576,6 +577,10 @@ export class DataStores implements IDisposable {
576
577
  eventName: "SetConnectionStateError",
577
578
  clientId,
578
579
  fluidDataStore,
580
+ details: JSON.stringify({
581
+ runtimeConnected: this.runtime.connected,
582
+ connected,
583
+ }),
579
584
  },
580
585
  error,
581
586
  );
@@ -0,0 +1,46 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import { IDeltaManager, ReadOnlyInfo } from "@fluidframework/container-definitions";
7
+ import { DeltaManagerProxyBase } from "@fluidframework/container-utils";
8
+ import { IDocumentMessage, ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
9
+ import { summarizerClientType } from "./summary";
10
+
11
+ /**
12
+ * Proxy to the real IDeltaManager for restricting certain access to layers below container runtime in summarizer clients:
13
+ * - Summarizer client should be read-only to layers below the container runtime to restrict local changes.
14
+ * - Summarizer client should not be active to layers below the container runtime to restrict local changes.
15
+ */
16
+ export class DeltaManagerSummarizerProxy
17
+ extends DeltaManagerProxyBase
18
+ implements IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>
19
+ {
20
+ public get active(): boolean {
21
+ // Summarize clients should not be active. There shouldn't be any local changes (writes) in the summarizer
22
+ // except for the SummarizeOp which is generated by the runtime.
23
+ return !this.isSummarizerClient && this.deltaManager.active;
24
+ }
25
+
26
+ public get readOnlyInfo(): ReadOnlyInfo {
27
+ // Summarizer clients should be read-only as far as the runtime and layers below are concerned. There shouldn't
28
+ // be any local changes (writes) in the summarizer except for the summarize op which is generated by the runtime.
29
+ if (this.isSummarizerClient) {
30
+ return {
31
+ readonly: true,
32
+ forced: false,
33
+ permissions: undefined,
34
+ storageOnly: false,
35
+ };
36
+ }
37
+ return this.deltaManager.readOnlyInfo;
38
+ }
39
+
40
+ private readonly isSummarizerClient: boolean;
41
+
42
+ constructor(deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>) {
43
+ super(deltaManager);
44
+ this.isSummarizerClient = this.deltaManager.clientDetails.type === summarizerClientType;
45
+ }
46
+ }