@fluidframework/container-runtime 0.52.0-44610 → 0.53.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.
- package/dist/containerHandleContext.d.ts +0 -1
- package/dist/containerHandleContext.d.ts.map +1 -1
- package/dist/containerHandleContext.js +0 -1
- package/dist/containerHandleContext.js.map +1 -1
- package/dist/containerRuntime.d.ts +18 -3
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +84 -42
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStoreContext.d.ts +4 -1
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +16 -13
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/dataStores.d.ts +8 -8
- package/dist/dataStores.d.ts.map +1 -1
- package/dist/dataStores.js +20 -37
- package/dist/dataStores.js.map +1 -1
- package/dist/garbageCollection.d.ts +61 -14
- package/dist/garbageCollection.d.ts.map +1 -1
- package/dist/garbageCollection.js +275 -20
- package/dist/garbageCollection.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -2
- package/dist/index.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.d.ts.map +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/pendingStateManager.d.ts +0 -1
- package/dist/pendingStateManager.d.ts.map +1 -1
- package/dist/pendingStateManager.js +0 -36
- package/dist/pendingStateManager.js.map +1 -1
- package/dist/summarizer.d.ts +1 -3
- package/dist/summarizer.d.ts.map +1 -1
- package/dist/summarizer.js +0 -12
- package/dist/summarizer.js.map +1 -1
- package/dist/summarizerTypes.d.ts +2 -2
- package/dist/summarizerTypes.d.ts.map +1 -1
- package/dist/summarizerTypes.js.map +1 -1
- package/dist/summaryFormat.d.ts +9 -1
- package/dist/summaryFormat.d.ts.map +1 -1
- package/dist/summaryFormat.js.map +1 -1
- package/dist/summaryGenerator.d.ts.map +1 -1
- package/dist/summaryGenerator.js +1 -3
- package/dist/summaryGenerator.js.map +1 -1
- package/lib/containerHandleContext.d.ts +0 -1
- package/lib/containerHandleContext.d.ts.map +1 -1
- package/lib/containerHandleContext.js +0 -1
- package/lib/containerHandleContext.js.map +1 -1
- package/lib/containerRuntime.d.ts +18 -3
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +84 -43
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStoreContext.d.ts +4 -1
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +16 -13
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/dataStores.d.ts +8 -8
- package/lib/dataStores.d.ts.map +1 -1
- package/lib/dataStores.js +23 -40
- package/lib/dataStores.js.map +1 -1
- package/lib/garbageCollection.d.ts +61 -14
- package/lib/garbageCollection.d.ts.map +1 -1
- package/lib/garbageCollection.js +276 -21
- package/lib/garbageCollection.js.map +1 -1
- package/lib/index.d.ts +2 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -1
- package/lib/index.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.d.ts.map +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/pendingStateManager.d.ts +0 -1
- package/lib/pendingStateManager.d.ts.map +1 -1
- package/lib/pendingStateManager.js +0 -36
- package/lib/pendingStateManager.js.map +1 -1
- package/lib/summarizer.d.ts +1 -3
- package/lib/summarizer.d.ts.map +1 -1
- package/lib/summarizer.js +0 -12
- package/lib/summarizer.js.map +1 -1
- package/lib/summarizerTypes.d.ts +2 -2
- package/lib/summarizerTypes.d.ts.map +1 -1
- package/lib/summarizerTypes.js.map +1 -1
- package/lib/summaryFormat.d.ts +9 -1
- package/lib/summaryFormat.d.ts.map +1 -1
- package/lib/summaryFormat.js.map +1 -1
- package/lib/summaryGenerator.d.ts.map +1 -1
- package/lib/summaryGenerator.js +1 -3
- package/lib/summaryGenerator.js.map +1 -1
- package/package.json +16 -16
- package/src/containerHandleContext.ts +0 -1
- package/src/containerRuntime.ts +110 -53
- package/src/dataStoreContext.ts +15 -14
- package/src/dataStores.ts +32 -50
- package/src/garbageCollection.ts +390 -18
- package/src/index.ts +20 -2
- package/src/packageVersion.ts +1 -1
- package/src/pendingStateManager.ts +0 -43
- package/src/summarizer.ts +0 -15
- package/src/summarizerTypes.ts +1 -2
- package/src/summaryFormat.ts +10 -1
- package/src/summaryGenerator.ts +2 -3
package/src/dataStoreContext.ts
CHANGED
|
@@ -188,6 +188,11 @@ export abstract class FluidDataStoreContext extends TypedEventEmitter<IFluidData
|
|
|
188
188
|
return this._containerRuntime.disableIsolatedChannels;
|
|
189
189
|
}
|
|
190
190
|
|
|
191
|
+
/** Tells whether GC data will be written at the root of the summary tree. If so, data store should not write it. */
|
|
192
|
+
protected get writeGCDataAtRoot(): boolean {
|
|
193
|
+
return this._containerRuntime.writeGCDataAtRoot;
|
|
194
|
+
}
|
|
195
|
+
|
|
191
196
|
protected registry: IFluidDataStoreRegistry | undefined;
|
|
192
197
|
|
|
193
198
|
protected detachedRuntimeCreation = false;
|
|
@@ -416,8 +421,10 @@ export abstract class FluidDataStoreContext extends TypedEventEmitter<IFluidData
|
|
|
416
421
|
const attributes = createAttributes(pkg, isRootDataStore, this.disableIsolatedChannels);
|
|
417
422
|
addBlobToSummary(summarizeResult, dataStoreAttributesBlobName, JSON.stringify(attributes));
|
|
418
423
|
|
|
419
|
-
// Add GC
|
|
420
|
-
|
|
424
|
+
// Add GC data to the summary if it's not written at the root.
|
|
425
|
+
if (!this.writeGCDataAtRoot) {
|
|
426
|
+
addBlobToSummary(summarizeResult, gcBlobKey, JSON.stringify(this.summarizerNode.getGCSummaryDetails()));
|
|
427
|
+
}
|
|
421
428
|
|
|
422
429
|
// If we are not referenced, mark the summary tree as unreferenced. Also, update unreferenced blob
|
|
423
430
|
// size in the summary stats with the blobs size of this data store.
|
|
@@ -675,6 +682,7 @@ export class RemotedFluidDataStoreContext extends FluidDataStoreContext {
|
|
|
675
682
|
constructor(
|
|
676
683
|
id: string,
|
|
677
684
|
private readonly initSnapshotValue: ISnapshotTree | string | undefined,
|
|
685
|
+
private readonly getBaseSummaryGCDetails: () => Promise<IGarbageCollectionSummaryDetails | undefined>,
|
|
678
686
|
runtime: ContainerRuntime,
|
|
679
687
|
storage: IDocumentStorageService,
|
|
680
688
|
scope: FluidObject,
|
|
@@ -760,16 +768,7 @@ export class RemotedFluidDataStoreContext extends FluidDataStoreContext {
|
|
|
760
768
|
});
|
|
761
769
|
|
|
762
770
|
private readonly gcDetailsInInitialSummaryP = new LazyPromise<IGarbageCollectionSummaryDetails>(async () => {
|
|
763
|
-
|
|
764
|
-
if (!(!this.initSnapshotValue || typeof this.initSnapshotValue === "string")
|
|
765
|
-
&& this.initSnapshotValue.blobs[gcBlobKey] !== undefined) {
|
|
766
|
-
return readAndParse<IGarbageCollectionSummaryDetails>(
|
|
767
|
-
this.storage,
|
|
768
|
-
this.initSnapshotValue.blobs[gcBlobKey],
|
|
769
|
-
);
|
|
770
|
-
} else {
|
|
771
|
-
return {};
|
|
772
|
-
}
|
|
771
|
+
return (await this.getBaseSummaryGCDetails()) ?? {};
|
|
773
772
|
});
|
|
774
773
|
|
|
775
774
|
protected async getInitialSnapshotDetails(): Promise<ISnapshotDetails> {
|
|
@@ -850,8 +849,10 @@ export class LocalFluidDataStoreContextBase extends FluidDataStoreContext {
|
|
|
850
849
|
);
|
|
851
850
|
addBlobToSummary(summarizeResult, dataStoreAttributesBlobName, JSON.stringify(attributes));
|
|
852
851
|
|
|
853
|
-
// Add GC
|
|
854
|
-
|
|
852
|
+
// Add GC data to the summary if it's not written at the root.
|
|
853
|
+
if (!this.writeGCDataAtRoot) {
|
|
854
|
+
addBlobToSummary(summarizeResult, gcBlobKey, JSON.stringify(this.summarizerNode.getGCSummaryDetails()));
|
|
855
|
+
}
|
|
855
856
|
|
|
856
857
|
// Attach message needs the summary in ITree format. Convert the ISummaryTree into an ITree.
|
|
857
858
|
const snapshot = convertSummaryTreeToITree(summarizeResult.summary);
|
package/src/dataStores.ts
CHANGED
|
@@ -8,8 +8,6 @@ import { DataCorruptionError, extractSafePropertiesFromMessage } from "@fluidfra
|
|
|
8
8
|
import {
|
|
9
9
|
ISequencedDocumentMessage,
|
|
10
10
|
ISnapshotTree,
|
|
11
|
-
ITreeEntry,
|
|
12
|
-
SummaryType,
|
|
13
11
|
} from "@fluidframework/protocol-definitions";
|
|
14
12
|
import {
|
|
15
13
|
channelsTreeName,
|
|
@@ -21,6 +19,7 @@ import {
|
|
|
21
19
|
IFluidDataStoreChannel,
|
|
22
20
|
IFluidDataStoreContextDetached,
|
|
23
21
|
IGarbageCollectionData,
|
|
22
|
+
IGarbageCollectionSummaryDetails,
|
|
24
23
|
IInboundSignalMessage,
|
|
25
24
|
InboundAttachMessage,
|
|
26
25
|
ISummarizeResult,
|
|
@@ -28,7 +27,6 @@ import {
|
|
|
28
27
|
} from "@fluidframework/runtime-definitions";
|
|
29
28
|
import {
|
|
30
29
|
convertSnapshotTreeToSummaryTree,
|
|
31
|
-
convertSummaryTreeToITree,
|
|
32
30
|
convertToSummaryTree,
|
|
33
31
|
create404Response,
|
|
34
32
|
responseToException,
|
|
@@ -37,10 +35,9 @@ import {
|
|
|
37
35
|
import { ChildLogger, TelemetryDataTag } from "@fluidframework/telemetry-utils";
|
|
38
36
|
import { AttachState } from "@fluidframework/container-definitions";
|
|
39
37
|
import { BlobCacheStorageService, buildSnapshotTree } from "@fluidframework/driver-utils";
|
|
40
|
-
import { assert, Lazy } from "@fluidframework/common-utils";
|
|
38
|
+
import { assert, Lazy, LazyPromise } from "@fluidframework/common-utils";
|
|
41
39
|
import { v4 as uuid } from "uuid";
|
|
42
|
-
import {
|
|
43
|
-
import { GCDataBuilder, getChildNodesUsedRoutes } from "@fluidframework/garbage-collector";
|
|
40
|
+
import { GCDataBuilder, unpackChildNodesUsedRoutes } from "@fluidframework/garbage-collector";
|
|
44
41
|
import { DataStoreContexts } from "./dataStoreContexts";
|
|
45
42
|
import { ContainerRuntime } from "./containerRuntime";
|
|
46
43
|
import {
|
|
@@ -67,6 +64,13 @@ export class DataStores implements IDisposable {
|
|
|
67
64
|
|
|
68
65
|
private readonly disposeOnce = new Lazy<void>(() => this.contexts.dispose());
|
|
69
66
|
|
|
67
|
+
public readonly containerLoadStats: {
|
|
68
|
+
// number of dataStores during loadContainer
|
|
69
|
+
readonly containerLoadDataStoreCount: number;
|
|
70
|
+
// number of unreferenced dataStores during loadContainer
|
|
71
|
+
readonly referencedDataStoreCount: number;
|
|
72
|
+
};
|
|
73
|
+
|
|
70
74
|
constructor(
|
|
71
75
|
private readonly baseSnapshot: ISnapshotTree | undefined,
|
|
72
76
|
private readonly runtime: ContainerRuntime,
|
|
@@ -75,12 +79,23 @@ export class DataStores implements IDisposable {
|
|
|
75
79
|
(id: string, createParam: CreateChildSummarizerNodeParam) => CreateChildSummarizerNodeFn,
|
|
76
80
|
private readonly deleteChildSummarizerNodeFn: (id: string) => void,
|
|
77
81
|
baseLogger: ITelemetryBaseLogger,
|
|
82
|
+
getDataStoreBaseGCDetails: () => Promise<Map<string, IGarbageCollectionSummaryDetails>>,
|
|
83
|
+
private readonly dataStoreChanged: (id: string) => void,
|
|
78
84
|
private readonly contexts: DataStoreContexts = new DataStoreContexts(baseLogger),
|
|
79
85
|
) {
|
|
80
86
|
this.logger = ChildLogger.create(baseLogger);
|
|
87
|
+
|
|
88
|
+
const baseDataStoresGCDetailsP = new LazyPromise(async () => {
|
|
89
|
+
return getDataStoreBaseGCDetails();
|
|
90
|
+
});
|
|
91
|
+
// Returns the base summary GC details for the data store with the given id.
|
|
92
|
+
const dataStoreBaseGCDetails = async (dataStoreId: string) => {
|
|
93
|
+
const baseGCDetails = await baseDataStoresGCDetailsP;
|
|
94
|
+
return baseGCDetails.get(dataStoreId);
|
|
95
|
+
};
|
|
96
|
+
|
|
81
97
|
// Extract stores stored inside the snapshot
|
|
82
98
|
const fluidDataStores = new Map<string, ISnapshotTree>();
|
|
83
|
-
|
|
84
99
|
if (baseSnapshot) {
|
|
85
100
|
for (const [key, value] of Object.entries(baseSnapshot.trees)) {
|
|
86
101
|
fluidDataStores.set(key, value);
|
|
@@ -101,6 +116,7 @@ export class DataStores implements IDisposable {
|
|
|
101
116
|
dataStoreContext = new RemotedFluidDataStoreContext(
|
|
102
117
|
key,
|
|
103
118
|
value,
|
|
119
|
+
async () => dataStoreBaseGCDetails(key),
|
|
104
120
|
this.runtime,
|
|
105
121
|
this.runtime.storage,
|
|
106
122
|
this.runtime.scope,
|
|
@@ -124,11 +140,10 @@ export class DataStores implements IDisposable {
|
|
|
124
140
|
}
|
|
125
141
|
this.contexts.addBoundOrRemoted(dataStoreContext);
|
|
126
142
|
}
|
|
127
|
-
this.
|
|
128
|
-
|
|
129
|
-
dataStoreCount: fluidDataStores.size,
|
|
143
|
+
this.containerLoadStats = {
|
|
144
|
+
containerLoadDataStoreCount: fluidDataStores.size,
|
|
130
145
|
referencedDataStoreCount: fluidDataStores.size - unreferencedDataStoreCount,
|
|
131
|
-
}
|
|
146
|
+
};
|
|
132
147
|
}
|
|
133
148
|
|
|
134
149
|
public processAttachMessage(message: ISequencedDocumentMessage, local: boolean) {
|
|
@@ -170,6 +185,8 @@ export class DataStores implements IDisposable {
|
|
|
170
185
|
const remotedFluidDataStoreContext = new RemotedFluidDataStoreContext(
|
|
171
186
|
attachMessage.id,
|
|
172
187
|
snapshotTree,
|
|
188
|
+
// New data stores begin with empty GC details since GC hasn't run on them yet.
|
|
189
|
+
async () => { return {}; },
|
|
173
190
|
this.runtime,
|
|
174
191
|
new BlobCacheStorageService(this.runtime.storage, flatBlobs),
|
|
175
192
|
this.runtime.scope,
|
|
@@ -281,6 +298,9 @@ export class DataStores implements IDisposable {
|
|
|
281
298
|
const context = this.contexts.get(envelope.address);
|
|
282
299
|
assert(!!context, 0x162 /* "There should be a store context for the op" */);
|
|
283
300
|
context.process(transformed, local, localMessageMetadata);
|
|
301
|
+
|
|
302
|
+
// Notify that a data store changed. This is used to detect if a deleted data store is being used.
|
|
303
|
+
this.dataStoreChanged(envelope.address);
|
|
284
304
|
}
|
|
285
305
|
|
|
286
306
|
public async getDataStore(id: string, wait: boolean): Promise<FluidDataStoreContext> {
|
|
@@ -339,44 +359,6 @@ export class DataStores implements IDisposable {
|
|
|
339
359
|
}
|
|
340
360
|
}
|
|
341
361
|
|
|
342
|
-
/**
|
|
343
|
-
* Notifies this object to take the snapshot of the container.
|
|
344
|
-
* @deprecated - Use summarize to get summary of the container runtime.
|
|
345
|
-
*/
|
|
346
|
-
public async snapshot(): Promise<ITreeEntry[]> {
|
|
347
|
-
// Iterate over each store and ask it to snapshot
|
|
348
|
-
const fluidDataStoreSnapshotsP = Array.from(this.contexts).map(async ([fluidDataStoreId, value]) => {
|
|
349
|
-
const summaryTree = await value.summarize(true /* fullTree */, false /* trackState */);
|
|
350
|
-
assert(
|
|
351
|
-
summaryTree.summary.type === SummaryType.Tree,
|
|
352
|
-
0x164 /* "summarize should always return a tree when fullTree is true" */);
|
|
353
|
-
// back-compat summary - Remove this once snapshot is removed.
|
|
354
|
-
const snapshot = convertSummaryTreeToITree(summaryTree.summary);
|
|
355
|
-
|
|
356
|
-
// If ID exists then previous commit is still valid
|
|
357
|
-
return {
|
|
358
|
-
fluidDataStoreId,
|
|
359
|
-
snapshot,
|
|
360
|
-
};
|
|
361
|
-
});
|
|
362
|
-
|
|
363
|
-
const entries: ITreeEntry[] = [];
|
|
364
|
-
|
|
365
|
-
// Add in module references to the store snapshots
|
|
366
|
-
const fluidDataStoreSnapshots = await Promise.all(fluidDataStoreSnapshotsP);
|
|
367
|
-
|
|
368
|
-
// Sort for better diffing of snapshots (in replay tool, used to find bugs in snapshotting logic)
|
|
369
|
-
fluidDataStoreSnapshots.sort((a, b) => a?.fluidDataStoreId.localeCompare(b.fluidDataStoreId));
|
|
370
|
-
|
|
371
|
-
for (const fluidDataStoreSnapshot of fluidDataStoreSnapshots) {
|
|
372
|
-
entries.push(new TreeTreeEntry(
|
|
373
|
-
fluidDataStoreSnapshot.fluidDataStoreId,
|
|
374
|
-
fluidDataStoreSnapshot.snapshot,
|
|
375
|
-
));
|
|
376
|
-
}
|
|
377
|
-
return entries;
|
|
378
|
-
}
|
|
379
|
-
|
|
380
362
|
public get size(): number {
|
|
381
363
|
return this.contexts.size;
|
|
382
364
|
}
|
|
@@ -474,7 +456,7 @@ export class DataStores implements IDisposable {
|
|
|
474
456
|
*/
|
|
475
457
|
public updateUsedRoutes(usedRoutes: string[], gcTimestamp?: number): IUsedStateStats {
|
|
476
458
|
// Get a map of data store ids to routes used in it.
|
|
477
|
-
const usedDataStoreRoutes =
|
|
459
|
+
const usedDataStoreRoutes = unpackChildNodesUsedRoutes(usedRoutes);
|
|
478
460
|
|
|
479
461
|
// Verify that the used routes are correct.
|
|
480
462
|
for (const [id] of usedDataStoreRoutes) {
|