@fluidframework/container-runtime 2.0.0-dev-rc.5.0.0.271262 → 2.0.0-dev-rc.5.0.0.272251
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/api-extractor/api-extractor-lint-bundle.json +5 -0
- package/api-extractor/api-extractor-lint-legacy.cjs.json +5 -0
- package/api-extractor/api-extractor-lint-legacy.esm.json +5 -0
- package/api-extractor/api-extractor-lint-public.cjs.json +5 -0
- package/api-extractor/api-extractor-lint-public.esm.json +5 -0
- package/api-report/container-runtime.alpha.api.md +1 -1
- package/container-runtime.test-files.tar +0 -0
- package/dist/batchTracker.js +1 -5
- package/dist/batchTracker.js.map +1 -1
- package/dist/blobManager.js +14 -39
- package/dist/blobManager.js.map +1 -1
- package/dist/channelCollection.d.ts +12 -2
- package/dist/channelCollection.d.ts.map +1 -1
- package/dist/channelCollection.js +95 -110
- package/dist/channelCollection.js.map +1 -1
- package/dist/connectionTelemetry.js +14 -32
- package/dist/connectionTelemetry.js.map +1 -1
- package/dist/containerHandleContext.js +0 -4
- package/dist/containerHandleContext.js.map +1 -1
- package/dist/containerRuntime.d.ts +2 -1
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +51 -142
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStore.js +1 -9
- package/dist/dataStore.js.map +1 -1
- package/dist/dataStoreContext.d.ts +2 -1
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +102 -143
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/dataStoreContexts.js +28 -29
- package/dist/dataStoreContexts.js.map +1 -1
- package/dist/dataStoreRegistry.js +0 -1
- package/dist/dataStoreRegistry.js.map +1 -1
- package/dist/deltaManagerProxies.js +28 -33
- package/dist/deltaManagerProxies.js.map +1 -1
- package/dist/deltaScheduler.js +9 -13
- package/dist/deltaScheduler.js.map +1 -1
- package/dist/error.js +1 -2
- package/dist/error.js.map +1 -1
- package/dist/gc/garbageCollection.d.ts +4 -2
- package/dist/gc/garbageCollection.d.ts.map +1 -1
- package/dist/gc/garbageCollection.js +25 -43
- package/dist/gc/garbageCollection.js.map +1 -1
- package/dist/gc/gcDefinitions.d.ts +7 -4
- package/dist/gc/gcDefinitions.d.ts.map +1 -1
- package/dist/gc/gcDefinitions.js.map +1 -1
- package/dist/gc/gcSummaryStateTracker.js +14 -19
- package/dist/gc/gcSummaryStateTracker.js.map +1 -1
- package/dist/gc/gcTelemetry.d.ts +1 -1
- package/dist/gc/gcTelemetry.d.ts.map +1 -1
- package/dist/gc/gcTelemetry.js +5 -17
- package/dist/gc/gcTelemetry.js.map +1 -1
- package/dist/gc/gcUnreferencedStateTracker.js +1 -12
- package/dist/gc/gcUnreferencedStateTracker.js.map +1 -1
- package/dist/opLifecycle/batchManager.js +3 -5
- package/dist/opLifecycle/batchManager.js.map +1 -1
- package/dist/opLifecycle/opCompressor.js +0 -1
- package/dist/opLifecycle/opCompressor.js.map +1 -1
- package/dist/opLifecycle/opDecompressor.js +4 -6
- package/dist/opLifecycle/opDecompressor.js.map +1 -1
- package/dist/opLifecycle/opGroupingManager.js +1 -3
- package/dist/opLifecycle/opGroupingManager.js.map +1 -1
- package/dist/opLifecycle/opSplitter.js +0 -6
- package/dist/opLifecycle/opSplitter.js.map +1 -1
- package/dist/opLifecycle/outbox.js +10 -15
- package/dist/opLifecycle/outbox.js.map +1 -1
- package/dist/opLifecycle/remoteMessageProcessor.js +0 -3
- package/dist/opLifecycle/remoteMessageProcessor.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/pendingStateManager.js +14 -20
- package/dist/pendingStateManager.js.map +1 -1
- package/dist/scheduleManager.js +4 -15
- package/dist/scheduleManager.js.map +1 -1
- package/dist/storageServiceWithAttachBlobs.js +0 -1
- package/dist/storageServiceWithAttachBlobs.js.map +1 -1
- package/dist/summary/documentSchema.js +1 -17
- package/dist/summary/documentSchema.js.map +1 -1
- package/dist/summary/orderedClientElection.js +11 -19
- package/dist/summary/orderedClientElection.js.map +1 -1
- package/dist/summary/runWhileConnectedCoordinator.js +2 -4
- package/dist/summary/runWhileConnectedCoordinator.js.map +1 -1
- package/dist/summary/runningSummarizer.js +38 -56
- package/dist/summary/runningSummarizer.js.map +1 -1
- package/dist/summary/summarizer.js +8 -17
- package/dist/summary/summarizer.js.map +1 -1
- package/dist/summary/summarizerClientElection.js +7 -18
- package/dist/summary/summarizerClientElection.js.map +1 -1
- package/dist/summary/summarizerHeuristics.js +25 -30
- package/dist/summary/summarizerHeuristics.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNode.js +3 -12
- package/dist/summary/summarizerNode/summarizerNode.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeUtils.js +0 -2
- package/dist/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeWithGc.js +6 -20
- package/dist/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
- package/dist/summary/summaryCollection.js +11 -23
- package/dist/summary/summaryCollection.js.map +1 -1
- package/dist/summary/summaryGenerator.js +5 -12
- package/dist/summary/summaryGenerator.js.map +1 -1
- package/dist/summary/summaryManager.js +48 -58
- package/dist/summary/summaryManager.js.map +1 -1
- package/dist/throttler.js +1 -4
- package/dist/throttler.js.map +1 -1
- package/lib/batchTracker.js +1 -5
- package/lib/batchTracker.js.map +1 -1
- package/lib/blobManager.js +14 -39
- package/lib/blobManager.js.map +1 -1
- package/lib/channelCollection.d.ts +12 -2
- package/lib/channelCollection.d.ts.map +1 -1
- package/lib/channelCollection.js +95 -110
- package/lib/channelCollection.js.map +1 -1
- package/lib/connectionTelemetry.js +14 -32
- package/lib/connectionTelemetry.js.map +1 -1
- package/lib/containerHandleContext.js +0 -4
- package/lib/containerHandleContext.js.map +1 -1
- package/lib/containerRuntime.d.ts +2 -1
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +52 -143
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStore.js +1 -9
- package/lib/dataStore.js.map +1 -1
- package/lib/dataStoreContext.d.ts +2 -1
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +102 -143
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/dataStoreContexts.js +28 -29
- package/lib/dataStoreContexts.js.map +1 -1
- package/lib/dataStoreRegistry.js +0 -1
- package/lib/dataStoreRegistry.js.map +1 -1
- package/lib/deltaManagerProxies.js +28 -33
- package/lib/deltaManagerProxies.js.map +1 -1
- package/lib/deltaScheduler.js +9 -13
- package/lib/deltaScheduler.js.map +1 -1
- package/lib/error.js +1 -2
- package/lib/error.js.map +1 -1
- package/lib/gc/garbageCollection.d.ts +4 -2
- package/lib/gc/garbageCollection.d.ts.map +1 -1
- package/lib/gc/garbageCollection.js +25 -43
- package/lib/gc/garbageCollection.js.map +1 -1
- package/lib/gc/gcDefinitions.d.ts +7 -4
- package/lib/gc/gcDefinitions.d.ts.map +1 -1
- package/lib/gc/gcDefinitions.js.map +1 -1
- package/lib/gc/gcSummaryStateTracker.js +14 -19
- package/lib/gc/gcSummaryStateTracker.js.map +1 -1
- package/lib/gc/gcTelemetry.d.ts +1 -1
- package/lib/gc/gcTelemetry.d.ts.map +1 -1
- package/lib/gc/gcTelemetry.js +5 -17
- package/lib/gc/gcTelemetry.js.map +1 -1
- package/lib/gc/gcUnreferencedStateTracker.js +1 -12
- package/lib/gc/gcUnreferencedStateTracker.js.map +1 -1
- package/lib/opLifecycle/batchManager.js +3 -5
- package/lib/opLifecycle/batchManager.js.map +1 -1
- package/lib/opLifecycle/opCompressor.js +0 -1
- package/lib/opLifecycle/opCompressor.js.map +1 -1
- package/lib/opLifecycle/opDecompressor.js +4 -6
- package/lib/opLifecycle/opDecompressor.js.map +1 -1
- package/lib/opLifecycle/opGroupingManager.js +1 -3
- package/lib/opLifecycle/opGroupingManager.js.map +1 -1
- package/lib/opLifecycle/opSplitter.js +0 -6
- package/lib/opLifecycle/opSplitter.js.map +1 -1
- package/lib/opLifecycle/outbox.js +10 -15
- package/lib/opLifecycle/outbox.js.map +1 -1
- package/lib/opLifecycle/remoteMessageProcessor.js +0 -3
- package/lib/opLifecycle/remoteMessageProcessor.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/pendingStateManager.js +14 -20
- package/lib/pendingStateManager.js.map +1 -1
- package/lib/scheduleManager.js +4 -15
- package/lib/scheduleManager.js.map +1 -1
- package/lib/storageServiceWithAttachBlobs.js +0 -1
- package/lib/storageServiceWithAttachBlobs.js.map +1 -1
- package/lib/summary/documentSchema.js +1 -17
- package/lib/summary/documentSchema.js.map +1 -1
- package/lib/summary/orderedClientElection.js +11 -19
- package/lib/summary/orderedClientElection.js.map +1 -1
- package/lib/summary/runWhileConnectedCoordinator.js +2 -4
- package/lib/summary/runWhileConnectedCoordinator.js.map +1 -1
- package/lib/summary/runningSummarizer.js +38 -56
- package/lib/summary/runningSummarizer.js.map +1 -1
- package/lib/summary/summarizer.js +8 -17
- package/lib/summary/summarizer.js.map +1 -1
- package/lib/summary/summarizerClientElection.js +7 -18
- package/lib/summary/summarizerClientElection.js.map +1 -1
- package/lib/summary/summarizerHeuristics.js +25 -30
- package/lib/summary/summarizerHeuristics.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNode.js +3 -12
- package/lib/summary/summarizerNode/summarizerNode.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeUtils.js +0 -2
- package/lib/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeWithGc.js +6 -20
- package/lib/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
- package/lib/summary/summaryCollection.js +11 -23
- package/lib/summary/summaryCollection.js.map +1 -1
- package/lib/summary/summaryGenerator.js +5 -12
- package/lib/summary/summaryGenerator.js.map +1 -1
- package/lib/summary/summaryManager.js +48 -58
- package/lib/summary/summaryManager.js.map +1 -1
- package/lib/throttler.js +1 -4
- package/lib/throttler.js.map +1 -1
- package/package.json +27 -18
- package/src/channelCollection.ts +133 -123
- package/src/containerRuntime.ts +31 -4
- package/src/dataStoreContext.ts +3 -2
- package/src/gc/garbageCollection.ts +24 -7
- package/src/gc/gcDefinitions.ts +16 -4
- package/src/gc/gcTelemetry.ts +1 -7
- package/src/packageVersion.ts +1 -1
- package/tsdoc.json +4 -0
package/lib/channelCollection.js
CHANGED
|
@@ -152,28 +152,21 @@ export function getLocalDataStoreType(localDataStore) {
|
|
|
152
152
|
* @internal
|
|
153
153
|
*/
|
|
154
154
|
export class ChannelCollection {
|
|
155
|
-
baseSnapshot;
|
|
156
|
-
parentContext;
|
|
157
|
-
gcNodeUpdated;
|
|
158
|
-
isDataStoreDeleted;
|
|
159
|
-
aliasMap;
|
|
160
|
-
// Stores tracked by the Domain
|
|
161
|
-
pendingAttach = new Map();
|
|
162
|
-
// 0.24 back-compat attachingBeforeSummary
|
|
163
|
-
attachOpFiredForDataStore = new Set();
|
|
164
|
-
mc;
|
|
165
|
-
disposeOnce = new Lazy(() => this.contexts.dispose());
|
|
166
|
-
entryPoint;
|
|
167
|
-
containerLoadStats;
|
|
168
|
-
pendingAliasMap = new Map();
|
|
169
|
-
contexts;
|
|
170
|
-
aliasedDataStores;
|
|
171
155
|
constructor(baseSnapshot, parentContext, baseLogger, gcNodeUpdated, isDataStoreDeleted, aliasMap, provideEntryPoint) {
|
|
172
156
|
this.baseSnapshot = baseSnapshot;
|
|
173
157
|
this.parentContext = parentContext;
|
|
174
158
|
this.gcNodeUpdated = gcNodeUpdated;
|
|
175
159
|
this.isDataStoreDeleted = isDataStoreDeleted;
|
|
176
160
|
this.aliasMap = aliasMap;
|
|
161
|
+
// Stores tracked by the Domain
|
|
162
|
+
this.pendingAttach = new Map();
|
|
163
|
+
// 0.24 back-compat attachingBeforeSummary
|
|
164
|
+
this.attachOpFiredForDataStore = new Set();
|
|
165
|
+
this.disposeOnce = new Lazy(() => this.contexts.dispose());
|
|
166
|
+
this.pendingAliasMap = new Map();
|
|
167
|
+
/** For sampling. Only log once per container */
|
|
168
|
+
this.shouldSendAttachLog = true;
|
|
169
|
+
this.dispose = () => this.disposeOnce.value;
|
|
177
170
|
this.mc = createChildMonitoringContext({ logger: baseLogger });
|
|
178
171
|
this.contexts = new DataStoreContexts(baseLogger);
|
|
179
172
|
this.entryPoint = new FluidObjectHandle(new LazyPromise(async () => provideEntryPoint(this)), "", this.parentContext.IFluidHandleContext);
|
|
@@ -250,8 +243,6 @@ export class ChannelCollection {
|
|
|
250
243
|
const pendingAliasPromise = this.pendingAliases.get(maybeAlias);
|
|
251
244
|
return pendingAliasPromise ?? "Success";
|
|
252
245
|
}
|
|
253
|
-
/** For sampling. Only log once per container */
|
|
254
|
-
shouldSendAttachLog = true;
|
|
255
246
|
wrapContextForInnerChannel(id) {
|
|
256
247
|
return wrapContextForInnerChannel(id, this.parentContext);
|
|
257
248
|
}
|
|
@@ -269,7 +260,7 @@ export class ChannelCollection {
|
|
|
269
260
|
const foundGCData = processAttachMessageGCData(attachMessage.snapshot, (nodeId, toPath) => {
|
|
270
261
|
// nodeId is the relative path under the node being attached. Always starts with "/", but no trailing "/" after an id
|
|
271
262
|
const fromPath = `/${attachMessage.id}${nodeId === "/" ? "" : nodeId}`;
|
|
272
|
-
this.parentContext.addedGCOutboundRoute(fromPath, toPath);
|
|
263
|
+
this.parentContext.addedGCOutboundRoute(fromPath, toPath, message.timestamp);
|
|
273
264
|
});
|
|
274
265
|
// Only log once per container to avoid noise/cost.
|
|
275
266
|
// Allows longitudinal tracking of various state (e.g. foundGCData), and some sampled details
|
|
@@ -341,12 +332,12 @@ export class ChannelCollection {
|
|
|
341
332
|
});
|
|
342
333
|
}
|
|
343
334
|
const resolve = localOpMetadata;
|
|
344
|
-
const aliasResult = this.processAliasMessageCore(aliasMessage.internalId, aliasMessage.alias);
|
|
335
|
+
const aliasResult = this.processAliasMessageCore(aliasMessage.internalId, aliasMessage.alias, message.timestamp);
|
|
345
336
|
if (local) {
|
|
346
337
|
resolve(aliasResult);
|
|
347
338
|
}
|
|
348
339
|
}
|
|
349
|
-
processAliasMessageCore(internalId, alias) {
|
|
340
|
+
processAliasMessageCore(internalId, alias, messageTimestampMs) {
|
|
350
341
|
if (this.alreadyProcessed(alias)) {
|
|
351
342
|
return false;
|
|
352
343
|
}
|
|
@@ -363,7 +354,11 @@ export class ChannelCollection {
|
|
|
363
354
|
});
|
|
364
355
|
return false;
|
|
365
356
|
}
|
|
366
|
-
this.
|
|
357
|
+
// If message timestamp doesn't exist, this is called in a detached container. Don't notify GC in that case
|
|
358
|
+
// because it doesn't run in detached container and doesn't need to know about this route.
|
|
359
|
+
if (messageTimestampMs) {
|
|
360
|
+
this.parentContext.addedGCOutboundRoute("/", `/${internalId}`, messageTimestampMs);
|
|
361
|
+
}
|
|
367
362
|
this.aliasMap.set(alias, context.id);
|
|
368
363
|
this.aliasedDataStores.add(context.id);
|
|
369
364
|
context.setInMemoryRoot();
|
|
@@ -474,7 +469,6 @@ export class ChannelCollection {
|
|
|
474
469
|
get disposed() {
|
|
475
470
|
return this.disposeOnce.evaluated;
|
|
476
471
|
}
|
|
477
|
-
dispose = () => this.disposeOnce.value;
|
|
478
472
|
reSubmit(type, content, localOpMetadata) {
|
|
479
473
|
switch (type) {
|
|
480
474
|
case ContainerMessageType.Attach:
|
|
@@ -597,7 +591,7 @@ export class ChannelCollection {
|
|
|
597
591
|
};
|
|
598
592
|
this.processChannelOp(envelope.address, transformed, local, localMessageMetadata);
|
|
599
593
|
// Notify GC of any outbound references that were added by this op.
|
|
600
|
-
detectOutboundReferences(envelope.address, transformed.contents, (fromPath, toPath) => this.parentContext.addedGCOutboundRoute(fromPath, toPath));
|
|
594
|
+
detectOutboundReferences(envelope.address, transformed.contents, (fromPath, toPath) => this.parentContext.addedGCOutboundRoute(fromPath, toPath, message.timestamp));
|
|
601
595
|
break;
|
|
602
596
|
}
|
|
603
597
|
default:
|
|
@@ -770,61 +764,24 @@ export class ChannelCollection {
|
|
|
770
764
|
get size() {
|
|
771
765
|
return this.contexts.size;
|
|
772
766
|
}
|
|
773
|
-
async summarize(fullTree, trackState, telemetryContext) {
|
|
774
|
-
const summaryBuilder = new SummaryTreeBuilder();
|
|
775
|
-
// Iterate over each store and ask it to snapshot
|
|
776
|
-
await Promise.all(Array.from(this.contexts)
|
|
777
|
-
.filter(([_, context]) => {
|
|
778
|
-
// Summarizer works only with clients with no local changes. A data store in attaching
|
|
779
|
-
// state indicates an op was sent to attach a local data store, and the the attach op
|
|
780
|
-
// had not yet round tripped back to the client.
|
|
781
|
-
if (context.attachState === AttachState.Attaching) {
|
|
782
|
-
// Formerly assert 0x588
|
|
783
|
-
const error = DataProcessingError.create("Local data store detected in attaching state during summarize", "summarize");
|
|
784
|
-
throw error;
|
|
785
|
-
}
|
|
786
|
-
return context.attachState === AttachState.Attached;
|
|
787
|
-
})
|
|
788
|
-
.map(async ([contextId, context]) => {
|
|
789
|
-
const contextSummary = await context.summarize(fullTree, trackState, telemetryContext);
|
|
790
|
-
summaryBuilder.addWithStats(contextId, contextSummary);
|
|
791
|
-
}));
|
|
792
|
-
return summaryBuilder.getSummaryTree();
|
|
793
|
-
}
|
|
794
767
|
/**
|
|
795
768
|
* Create a summary. Used when attaching or serializing a detached container.
|
|
796
769
|
*/
|
|
797
770
|
getAttachSummary(telemetryContext) {
|
|
798
771
|
const builder = new SummaryTreeBuilder();
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
.
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
builderTree[key] ||
|
|
813
|
-
this.attachOpFiredForDataStore.has(key)))
|
|
814
|
-
.map(([key, value]) => {
|
|
815
|
-
let dataStoreSummary;
|
|
816
|
-
if (value.isLoaded) {
|
|
817
|
-
dataStoreSummary = value.getAttachSummary(telemetryContext);
|
|
818
|
-
}
|
|
819
|
-
else {
|
|
820
|
-
// If this data store is not yet loaded, then there should be no changes in the snapshot from
|
|
821
|
-
// which it was created as it is detached container. So just use the previous snapshot.
|
|
822
|
-
assert(!!this.baseSnapshot, 0x166 /* "BaseSnapshot should be there as detached container loaded from snapshot" */);
|
|
823
|
-
dataStoreSummary = convertSnapshotTreeToSummaryTree(getSnapshotTree(this.baseSnapshot).trees[key]);
|
|
824
|
-
}
|
|
825
|
-
builder.addWithStats(key, dataStoreSummary);
|
|
826
|
-
});
|
|
827
|
-
} while (notBoundContextsLength !== this.contexts.notBoundLength());
|
|
772
|
+
this.visitLocalBoundContextsDuringAttach((contextId, context) => {
|
|
773
|
+
let dataStoreSummary;
|
|
774
|
+
if (context.isLoaded) {
|
|
775
|
+
dataStoreSummary = context.getAttachSummary(telemetryContext);
|
|
776
|
+
}
|
|
777
|
+
else {
|
|
778
|
+
// If this data store is not yet loaded, then there should be no changes in the snapshot from
|
|
779
|
+
// which it was created as it is detached container. So just use the previous snapshot.
|
|
780
|
+
assert(!!this.baseSnapshot, 0x166 /* "BaseSnapshot should be there as detached container loaded from snapshot" */);
|
|
781
|
+
dataStoreSummary = convertSnapshotTreeToSummaryTree(getSnapshotTree(this.baseSnapshot).trees[contextId]);
|
|
782
|
+
}
|
|
783
|
+
builder.addWithStats(contextId, dataStoreSummary);
|
|
784
|
+
});
|
|
828
785
|
return builder.getSummaryTree();
|
|
829
786
|
}
|
|
830
787
|
/**
|
|
@@ -832,27 +789,70 @@ export class ChannelCollection {
|
|
|
832
789
|
*/
|
|
833
790
|
getAttachGCData(telemetryContext) {
|
|
834
791
|
const builder = new GCDataBuilder();
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
Array.from(this.contexts)
|
|
842
|
-
.filter(([key, _]) =>
|
|
843
|
-
// Take GC data of bounded data stores only.
|
|
844
|
-
!this.contexts.isNotBound(key))
|
|
845
|
-
.map(([key, value]) => {
|
|
846
|
-
const contextGCData = value.getAttachGCData(telemetryContext);
|
|
847
|
-
// Prefix the child's id to the ids of its GC nodes so they can be identified as belonging to the child.
|
|
848
|
-
// This also gradually builds the id of each node to be a path from the root.
|
|
849
|
-
builder.prefixAndAddNodes(key, contextGCData.gcNodes);
|
|
850
|
-
});
|
|
851
|
-
} while (notBoundContextsLength !== this.contexts.notBoundLength());
|
|
792
|
+
this.visitLocalBoundContextsDuringAttach((contextId, context) => {
|
|
793
|
+
const contextGCData = context.getAttachGCData(telemetryContext);
|
|
794
|
+
// Prefix the child's id to the ids of its GC nodes so they can be identified as belonging to the child.
|
|
795
|
+
// This also gradually builds the id of each node to be a path from the root.
|
|
796
|
+
builder.prefixAndAddNodes(contextId, contextGCData.gcNodes);
|
|
797
|
+
});
|
|
852
798
|
// Get the outbound routes (aliased data stores) and add a GC node for this channel.
|
|
853
799
|
builder.addNode("/", Array.from(this.aliasedDataStores));
|
|
854
800
|
return builder.getGCData();
|
|
855
801
|
}
|
|
802
|
+
/**
|
|
803
|
+
* Helper method for preparing to attach this channel.
|
|
804
|
+
* Runs the callback for each bound context to incorporate its data however the caller specifies
|
|
805
|
+
*/
|
|
806
|
+
visitLocalBoundContextsDuringAttach(visitor) {
|
|
807
|
+
const visitedContexts = new Set();
|
|
808
|
+
let visitedLength = -1;
|
|
809
|
+
let notBoundContextsLength = -1;
|
|
810
|
+
while (visitedLength !== visitedContexts.size &&
|
|
811
|
+
notBoundContextsLength !== this.contexts.notBoundLength()) {
|
|
812
|
+
// detect changes in the visitedContexts set, as on visiting a context
|
|
813
|
+
// it could could make contexts available by removing other contexts
|
|
814
|
+
// from the not bound context list, so we need to ensure those get processed as well.
|
|
815
|
+
// only once the loop can run with no new contexts added to the visitedContexts set do we
|
|
816
|
+
// know for sure all possible contexts have been visited.
|
|
817
|
+
visitedLength = visitedContexts.size;
|
|
818
|
+
notBoundContextsLength = this.contexts.notBoundLength();
|
|
819
|
+
for (const [contextId, context] of this.contexts) {
|
|
820
|
+
if (!(visitedContexts.has(contextId) ||
|
|
821
|
+
this.contexts.isNotBound(contextId) ||
|
|
822
|
+
this.attachOpFiredForDataStore.has(contextId))) {
|
|
823
|
+
visitor(contextId, context);
|
|
824
|
+
visitedContexts.add(contextId);
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
/**
|
|
830
|
+
* Helper method for preparing to summarize this channel.
|
|
831
|
+
* Runs the callback for each bound context to incorporate its data however the caller specifies
|
|
832
|
+
*/
|
|
833
|
+
async visitContextsDuringSummary(visitor) {
|
|
834
|
+
for (const [contextId, context] of this.contexts) {
|
|
835
|
+
// Summarizer client and hence GC works only with clients with no local changes. A data store in
|
|
836
|
+
// attaching state indicates an op was sent to attach a local data store, and the the attach op
|
|
837
|
+
// had not yet round tripped back to the client.
|
|
838
|
+
// Formerly assert 0x589
|
|
839
|
+
if (context.attachState === AttachState.Attaching) {
|
|
840
|
+
const error = DataProcessingError.create("Local data store detected in attaching state", "summarize/getGCData");
|
|
841
|
+
throw error;
|
|
842
|
+
}
|
|
843
|
+
if (context.attachState === AttachState.Attached) {
|
|
844
|
+
await visitor(contextId, context);
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
async summarize(fullTree, trackState, telemetryContext) {
|
|
849
|
+
const summaryBuilder = new SummaryTreeBuilder();
|
|
850
|
+
await this.visitContextsDuringSummary(async (contextId, context) => {
|
|
851
|
+
const contextSummary = await context.summarize(fullTree, trackState, telemetryContext);
|
|
852
|
+
summaryBuilder.addWithStats(contextId, contextSummary);
|
|
853
|
+
});
|
|
854
|
+
return summaryBuilder.getSummaryTree();
|
|
855
|
+
}
|
|
856
856
|
/**
|
|
857
857
|
* Generates data used for garbage collection. It does the following:
|
|
858
858
|
*
|
|
@@ -868,25 +868,12 @@ export class ChannelCollection {
|
|
|
868
868
|
*/
|
|
869
869
|
async getGCData(fullGC = false) {
|
|
870
870
|
const builder = new GCDataBuilder();
|
|
871
|
-
|
|
872
|
-
await Promise.all(Array.from(this.contexts)
|
|
873
|
-
.filter(([_, context]) => {
|
|
874
|
-
// Summarizer client and hence GC works only with clients with no local changes. A data store in
|
|
875
|
-
// attaching state indicates an op was sent to attach a local data store, and the the attach op
|
|
876
|
-
// had not yet round tripped back to the client.
|
|
877
|
-
// Formerly assert 0x589
|
|
878
|
-
if (context.attachState === AttachState.Attaching) {
|
|
879
|
-
const error = DataProcessingError.create("Local data store detected in attaching state while running GC", "getGCData");
|
|
880
|
-
throw error;
|
|
881
|
-
}
|
|
882
|
-
return context.attachState === AttachState.Attached;
|
|
883
|
-
})
|
|
884
|
-
.map(async ([contextId, context]) => {
|
|
871
|
+
await this.visitContextsDuringSummary(async (contextId, context) => {
|
|
885
872
|
const contextGCData = await context.getGCData(fullGC);
|
|
886
873
|
// Prefix the child's id to the ids of its GC nodes so they can be identified as belonging to the child.
|
|
887
874
|
// This also gradually builds the id of each node to be a path from the root.
|
|
888
875
|
builder.prefixAndAddNodes(contextId, contextGCData.gcNodes);
|
|
889
|
-
})
|
|
876
|
+
});
|
|
890
877
|
// Get the outbound routes and add a GC node for this channel.
|
|
891
878
|
builder.addNode("/", await this.getOutboundRoutes());
|
|
892
879
|
return builder.getGCData();
|
|
@@ -1063,6 +1050,7 @@ export class ChannelCollection {
|
|
|
1063
1050
|
packagePath: details.pkg,
|
|
1064
1051
|
request,
|
|
1065
1052
|
headerData,
|
|
1053
|
+
timestampMs: undefined, // This will be added by the parent context if needed.
|
|
1066
1054
|
});
|
|
1067
1055
|
const dataStore = await dataStoreContext.realize();
|
|
1068
1056
|
const subRequest = requestParser.createSubRequest(1);
|
|
@@ -1129,15 +1117,12 @@ export function detectOutboundReferences(address, contents, addedOutboundReferen
|
|
|
1129
1117
|
}
|
|
1130
1118
|
/** @internal */
|
|
1131
1119
|
export class ChannelCollectionFactory {
|
|
1132
|
-
provideEntryPoint;
|
|
1133
|
-
ctor;
|
|
1134
|
-
type = "ChannelCollectionChannel";
|
|
1135
|
-
IFluidDataStoreRegistry;
|
|
1136
1120
|
constructor(registryEntries,
|
|
1137
1121
|
// ADO:7302 We need a better type here
|
|
1138
1122
|
provideEntryPoint, ctor) {
|
|
1139
1123
|
this.provideEntryPoint = provideEntryPoint;
|
|
1140
1124
|
this.ctor = ctor;
|
|
1125
|
+
this.type = "ChannelCollectionChannel";
|
|
1141
1126
|
this.IFluidDataStoreRegistry = new FluidDataStoreRegistry(registryEntries);
|
|
1142
1127
|
}
|
|
1143
1128
|
get IFluidDataStoreFactory() {
|