@fluidframework/container-runtime 2.0.0-dev-rc.5.0.0.270401 → 2.0.0-dev-rc.5.0.0.271045

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/container-runtime",
3
- "version": "2.0.0-dev-rc.5.0.0.270401",
3
+ "version": "2.0.0-dev-rc.5.0.0.271045",
4
4
  "description": "Fluid container runtime",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": {
@@ -127,18 +127,18 @@
127
127
  "temp-directory": "nyc/.nyc_output"
128
128
  },
129
129
  "dependencies": {
130
- "@fluid-internal/client-utils": "2.0.0-dev-rc.5.0.0.270401",
131
- "@fluidframework/container-definitions": "2.0.0-dev-rc.5.0.0.270401",
132
- "@fluidframework/container-runtime-definitions": "2.0.0-dev-rc.5.0.0.270401",
133
- "@fluidframework/core-interfaces": "2.0.0-dev-rc.5.0.0.270401",
134
- "@fluidframework/core-utils": "2.0.0-dev-rc.5.0.0.270401",
135
- "@fluidframework/datastore": "2.0.0-dev-rc.5.0.0.270401",
136
- "@fluidframework/driver-definitions": "2.0.0-dev-rc.5.0.0.270401",
137
- "@fluidframework/driver-utils": "2.0.0-dev-rc.5.0.0.270401",
138
- "@fluidframework/id-compressor": "2.0.0-dev-rc.5.0.0.270401",
139
- "@fluidframework/runtime-definitions": "2.0.0-dev-rc.5.0.0.270401",
140
- "@fluidframework/runtime-utils": "2.0.0-dev-rc.5.0.0.270401",
141
- "@fluidframework/telemetry-utils": "2.0.0-dev-rc.5.0.0.270401",
130
+ "@fluid-internal/client-utils": "2.0.0-dev-rc.5.0.0.271045",
131
+ "@fluidframework/container-definitions": "2.0.0-dev-rc.5.0.0.271045",
132
+ "@fluidframework/container-runtime-definitions": "2.0.0-dev-rc.5.0.0.271045",
133
+ "@fluidframework/core-interfaces": "2.0.0-dev-rc.5.0.0.271045",
134
+ "@fluidframework/core-utils": "2.0.0-dev-rc.5.0.0.271045",
135
+ "@fluidframework/datastore": "2.0.0-dev-rc.5.0.0.271045",
136
+ "@fluidframework/driver-definitions": "2.0.0-dev-rc.5.0.0.271045",
137
+ "@fluidframework/driver-utils": "2.0.0-dev-rc.5.0.0.271045",
138
+ "@fluidframework/id-compressor": "2.0.0-dev-rc.5.0.0.271045",
139
+ "@fluidframework/runtime-definitions": "2.0.0-dev-rc.5.0.0.271045",
140
+ "@fluidframework/runtime-utils": "2.0.0-dev-rc.5.0.0.271045",
141
+ "@fluidframework/telemetry-utils": "2.0.0-dev-rc.5.0.0.271045",
142
142
  "@tylerbu/sorted-btree-es6": "^1.8.0",
143
143
  "double-ended-queue": "^2.1.0-0",
144
144
  "lz4js": "^0.2.0",
@@ -147,16 +147,16 @@
147
147
  "devDependencies": {
148
148
  "@arethetypeswrong/cli": "^0.15.2",
149
149
  "@biomejs/biome": "^1.7.3",
150
- "@fluid-internal/mocha-test-setup": "2.0.0-dev-rc.5.0.0.270401",
151
- "@fluid-private/stochastic-test-utils": "2.0.0-dev-rc.5.0.0.270401",
152
- "@fluid-private/test-pairwise-generator": "2.0.0-dev-rc.5.0.0.270401",
150
+ "@fluid-internal/mocha-test-setup": "2.0.0-dev-rc.5.0.0.271045",
151
+ "@fluid-private/stochastic-test-utils": "2.0.0-dev-rc.5.0.0.271045",
152
+ "@fluid-private/test-pairwise-generator": "2.0.0-dev-rc.5.0.0.271045",
153
153
  "@fluid-tools/benchmark": "^0.48.0",
154
- "@fluid-tools/build-cli": "^0.39.0-264124",
154
+ "@fluid-tools/build-cli": "^0.39.0",
155
155
  "@fluidframework/build-common": "^2.0.3",
156
- "@fluidframework/build-tools": "^0.39.0-264124",
156
+ "@fluidframework/build-tools": "^0.39.0",
157
157
  "@fluidframework/container-runtime-previous": "npm:@fluidframework/container-runtime@2.0.0-rc.4.0.0",
158
158
  "@fluidframework/eslint-config-fluid": "^5.3.0",
159
- "@fluidframework/test-runtime-utils": "2.0.0-dev-rc.5.0.0.270401",
159
+ "@fluidframework/test-runtime-utils": "2.0.0-dev-rc.5.0.0.271045",
160
160
  "@microsoft/api-extractor": "^7.45.1",
161
161
  "@types/double-ended-queue": "^2.1.0",
162
162
  "@types/mocha": "^9.1.1",
@@ -254,13 +254,16 @@
254
254
  "build:test:cjs": "fluid-tsc commonjs --project ./src/test/tsconfig.cjs.json",
255
255
  "build:test:esm": "tsc --project ./src/test/tsconfig.json",
256
256
  "check:are-the-types-wrong": "attw --pack . --exclude-entrypoints ./internal/test/containerRuntime ./internal/test/deltaScheduler ./internal/test/scheduleManager ./internal/test/blobManager ./internal/test/summary ./internal/test/gc",
257
+ "check:biome": "biome check . --formatter-enabled=true",
258
+ "check:format": "npm run check:prettier",
257
259
  "check:prettier": "prettier --check . --cache --ignore-path ../../../.prettierignore",
258
260
  "check:release-tags": "api-extractor run --local --config ./api-extractor-lint.json",
259
261
  "ci:build:docs": "api-extractor run",
260
262
  "clean": "rimraf --glob dist lib \"*.d.ts\" \"**/*.tsbuildinfo\" \"**/*.build.log\" _api-extractor-temp nyc",
261
263
  "eslint": "eslint --format stylish src",
262
264
  "eslint:fix": "eslint --format stylish src --fix --fix-type problem,suggestion,layout",
263
- "format": "fluid-build --task format .",
265
+ "format": "npm run format:prettier",
266
+ "format:biome": "biome check . --formatter-enabled=true --apply",
264
267
  "format:prettier": "prettier --write . --cache --ignore-path ../../../.prettierignore",
265
268
  "lint": "fluid-build . --task lint",
266
269
  "lint:fix": "fluid-build . --task eslint:fix --task format",
@@ -43,11 +43,13 @@ import {
43
43
  NamedFluidDataStoreRegistryEntries,
44
44
  channelsTreeName,
45
45
  IInboundSignalMessage,
46
+ gcDataBlobKey,
46
47
  } from "@fluidframework/runtime-definitions/internal";
47
48
  import {
48
49
  GCDataBuilder,
49
50
  RequestParser,
50
51
  SummaryTreeBuilder,
52
+ addBlobToSummary,
51
53
  convertSnapshotTreeToSummaryTree,
52
54
  convertSummaryTreeToITree,
53
55
  create404Response,
@@ -241,6 +243,13 @@ export function wrapContextForInnerChannel(
241
243
  return context;
242
244
  }
243
245
 
246
+ /**
247
+ * Returns the type of the given local data store from its package path.
248
+ */
249
+ export function getLocalDataStoreType(localDataStore: LocalFluidDataStoreContext) {
250
+ return localDataStore.packagePath[localDataStore.packagePath.length - 1];
251
+ }
252
+
244
253
  /**
245
254
  * This class encapsulates data store handling. Currently it is only used by the container runtime,
246
255
  * but eventually could be hosted on any channel once we formalize the channel api boundary.
@@ -525,9 +534,13 @@ export class ChannelCollection implements IFluidDataStoreChannel, IDisposable {
525
534
  }
526
535
 
527
536
  /** Package up the context's attach summary etc into an IAttachMessage */
528
- private generateAttachMessage(localContext: IFluidDataStoreContextInternal): IAttachMessage {
529
- const { attachSummary } = localContext.getAttachData(/* includeGCData: */ true);
530
- const type = localContext.packagePath[localContext.packagePath.length - 1];
537
+ private generateAttachMessage(localContext: LocalFluidDataStoreContext): IAttachMessage {
538
+ // Get the attach summary.
539
+ const attachSummary = localContext.getAttachSummary();
540
+
541
+ // Get the GC data and add it to the attach summary.
542
+ const attachGCData = localContext.getAttachGCData();
543
+ addBlobToSummary(attachSummary, gcDataBlobKey, JSON.stringify(attachGCData));
531
544
 
532
545
  // Attach message needs the summary in ITree format. Convert the ISummaryTree into an ITree.
533
546
  const snapshot = convertSummaryTreeToITree(attachSummary.summary);
@@ -535,7 +548,7 @@ export class ChannelCollection implements IFluidDataStoreChannel, IDisposable {
535
548
  return {
536
549
  id: localContext.id,
537
550
  snapshot,
538
- type,
551
+ type: getLocalDataStoreType(localContext),
539
552
  } satisfies IAttachMessage;
540
553
  }
541
554
 
@@ -1126,10 +1139,7 @@ export class ChannelCollection implements IFluidDataStoreChannel, IDisposable {
1126
1139
  .map(([key, value]) => {
1127
1140
  let dataStoreSummary: ISummarizeResult;
1128
1141
  if (value.isLoaded) {
1129
- dataStoreSummary = value.getAttachData(
1130
- /* includeGCCData: */ false,
1131
- telemetryContext,
1132
- ).attachSummary;
1142
+ dataStoreSummary = value.getAttachSummary(telemetryContext);
1133
1143
  } else {
1134
1144
  // If this data store is not yet loaded, then there should be no changes in the snapshot from
1135
1145
  // which it was created as it is detached container. So just use the previous snapshot.
@@ -1148,6 +1158,36 @@ export class ChannelCollection implements IFluidDataStoreChannel, IDisposable {
1148
1158
  return builder.getSummaryTree();
1149
1159
  }
1150
1160
 
1161
+ /**
1162
+ * Gets the GC data. Used when attaching or serializing a detached container.
1163
+ */
1164
+ public getAttachGCData(telemetryContext?: ITelemetryContext): IGarbageCollectionData {
1165
+ const builder = new GCDataBuilder();
1166
+ // Attaching graph of some stores can cause other stores to get bound too.
1167
+ // So keep taking summary until no new stores get bound.
1168
+ let notBoundContextsLength: number;
1169
+ do {
1170
+ notBoundContextsLength = this.contexts.notBoundLength();
1171
+ // Iterate over each data store and ask for its GC data.
1172
+ Array.from(this.contexts)
1173
+ .filter(
1174
+ ([key, _]) =>
1175
+ // Take GC data of bounded data stores only.
1176
+ !this.contexts.isNotBound(key),
1177
+ )
1178
+ .map(([key, value]) => {
1179
+ const contextGCData = value.getAttachGCData(telemetryContext);
1180
+ // Prefix the child's id to the ids of its GC nodes so they can be identified as belonging to the child.
1181
+ // This also gradually builds the id of each node to be a path from the root.
1182
+ builder.prefixAndAddNodes(key, contextGCData.gcNodes);
1183
+ });
1184
+ } while (notBoundContextsLength !== this.contexts.notBoundLength());
1185
+
1186
+ // Get the outbound routes (aliased data stores) and add a GC node for this channel.
1187
+ builder.addNode("/", Array.from(this.aliasedDataStores));
1188
+ return builder.getGCData();
1189
+ }
1190
+
1151
1191
  /**
1152
1192
  * Generates data used for garbage collection. It does the following:
1153
1193
  *
@@ -52,7 +52,6 @@ import {
52
52
  ISummarizerNodeWithGC,
53
53
  SummarizeInternalFn,
54
54
  channelsTreeName,
55
- gcDataBlobKey,
56
55
  IInboundSignalMessage,
57
56
  } from "@fluidframework/runtime-definitions/internal";
58
57
  import {
@@ -115,13 +114,9 @@ export interface ISnapshotDetails {
115
114
  * @internal
116
115
  */
117
116
  export interface IFluidDataStoreContextInternal extends IFluidDataStoreContext {
118
- getAttachData(
119
- includeGCData: boolean,
120
- telemetryContext?: ITelemetryContext,
121
- ): {
122
- attachSummary: ISummaryTreeWithStats;
123
- type: string;
124
- };
117
+ getAttachSummary(telemetryContext?: ITelemetryContext): ISummaryTreeWithStats;
118
+
119
+ getAttachGCData(telemetryContext?: ITelemetryContext): IGarbageCollectionData;
125
120
 
126
121
  getInitialSnapshotDetails(): Promise<ISnapshotDetails>;
127
122
 
@@ -893,18 +888,16 @@ export abstract class FluidDataStoreContext
893
888
  }
894
889
 
895
890
  /**
896
- * Get the data required when attaching this context's DataStore.
891
+ * Get the summary required when attaching this context's DataStore.
897
892
  * Used for both Container Attach and DataStore Attach.
898
- *
899
- * @returns the summary, type, and GC Data for this context's DataStore.
900
893
  */
901
- public abstract getAttachData(
902
- includeGCData: boolean,
903
- telemetryContext?: ITelemetryContext,
904
- ): {
905
- attachSummary: ISummaryTreeWithStats;
906
- type: string;
907
- };
894
+ public abstract getAttachSummary(telemetryContext?: ITelemetryContext): ISummaryTreeWithStats;
895
+
896
+ /**
897
+ * Get the GC Data for the initial state being attached so remote clients can learn of this DataStore's
898
+ * outbound routes.
899
+ */
900
+ public abstract getAttachGCData(telemetryContext?: ITelemetryContext): IGarbageCollectionData;
908
901
 
909
902
  public abstract getInitialSnapshotDetails(): Promise<ISnapshotDetails>;
910
903
 
@@ -1164,12 +1157,16 @@ export class RemoteFluidDataStoreContext extends FluidDataStoreContext {
1164
1157
  }
1165
1158
 
1166
1159
  /**
1167
- * @see FluidDataStoreContext.getAttachData
1160
+ * @see FluidDataStoreContext.getAttachSummary
1161
+ */
1162
+ public getAttachSummary(): ISummaryTreeWithStats {
1163
+ throw new Error("Cannot attach remote store");
1164
+ }
1165
+
1166
+ /**
1167
+ * @see FluidDataStoreContext.getAttachGCData
1168
1168
  */
1169
- public getAttachData(includeGCData: boolean): {
1170
- attachSummary: ISummaryTreeWithStats;
1171
- type: string;
1172
- } {
1169
+ public getAttachGCData(telemetryContext?: ITelemetryContext): IGarbageCollectionData {
1173
1170
  throw new Error("Cannot attach remote store");
1174
1171
  }
1175
1172
  }
@@ -1245,15 +1242,9 @@ export class LocalFluidDataStoreContextBase extends FluidDataStoreContext {
1245
1242
  }
1246
1243
 
1247
1244
  /**
1248
- * @see FluidDataStoreContext.getAttachData
1245
+ * @see FluidDataStoreContext.getAttachSummary
1249
1246
  */
1250
- public getAttachData(
1251
- includeGCData: boolean,
1252
- telemetryContext?: ITelemetryContext,
1253
- ): {
1254
- attachSummary: ISummaryTreeWithStats;
1255
- type: string;
1256
- } {
1247
+ public getAttachSummary(telemetryContext?: ITelemetryContext): ISummaryTreeWithStats {
1257
1248
  assert(
1258
1249
  this.channel !== undefined,
1259
1250
  0x14f /* "There should be a channel when generating attach message" */,
@@ -1271,22 +1262,24 @@ export class LocalFluidDataStoreContextBase extends FluidDataStoreContext {
1271
1262
  // Add data store's attributes to the summary.
1272
1263
  const attributes = createAttributes(this.pkg, this.isInMemoryRoot());
1273
1264
  addBlobToSummary(attachSummary, dataStoreAttributesBlobName, JSON.stringify(attributes));
1274
- if (includeGCData) {
1275
- const gcData = this.channel.getAttachGCData?.(telemetryContext);
1276
- if (gcData !== undefined) {
1277
- addBlobToSummary(attachSummary, gcDataBlobKey, JSON.stringify(gcData));
1278
- }
1279
- }
1280
1265
 
1281
1266
  // Add loadingGroupId to the summary
1282
1267
  if (this.loadingGroupId !== undefined) {
1283
1268
  attachSummary.summary.groupId = this.loadingGroupId;
1284
1269
  }
1285
1270
 
1286
- return {
1287
- attachSummary,
1288
- type: this.pkg[this.pkg.length - 1],
1289
- };
1271
+ return attachSummary;
1272
+ }
1273
+
1274
+ /**
1275
+ * @see FluidDataStoreContext.getAttachGCData
1276
+ */
1277
+ public getAttachGCData(telemetryContext?: ITelemetryContext): IGarbageCollectionData {
1278
+ assert(
1279
+ this.channel !== undefined,
1280
+ "There should be a channel when generating attach GC data",
1281
+ );
1282
+ return this.channel.getAttachGCData(telemetryContext);
1290
1283
  }
1291
1284
 
1292
1285
  private readonly initialSnapshotDetailsP = new LazyPromise<ISnapshotDetails>(async () => {
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/container-runtime";
9
- export const pkgVersion = "2.0.0-dev-rc.5.0.0.270401";
9
+ export const pkgVersion = "2.0.0-dev-rc.5.0.0.271045";