@fluidframework/container-runtime 2.0.0-dev-rc.5.0.0.271717 → 2.0.0-dev-rc.5.0.0.272889
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-extractor.json +1 -1
- package/api-report/container-runtime.alpha.api.md +1 -1
- package/container-runtime.test-files.tar +0 -0
- package/dist/batchTracker.d.ts.map +1 -1
- package/dist/batchTracker.js.map +1 -1
- package/dist/blobManager.d.ts.map +1 -1
- 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 +86 -90
- package/dist/channelCollection.js.map +1 -1
- package/dist/connectionTelemetry.d.ts.map +1 -1
- package/dist/connectionTelemetry.js.map +1 -1
- package/dist/containerRuntime.d.ts +2 -1
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +29 -9
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStoreContext.d.ts +2 -1
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +5 -3
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/dataStoreContexts.d.ts.map +1 -1
- package/dist/dataStoreContexts.js.map +1 -1
- package/dist/deltaManagerProxies.d.ts.map +1 -1
- package/dist/deltaManagerProxies.js.map +1 -1
- package/dist/deltaScheduler.d.ts.map +1 -1
- package/dist/deltaScheduler.js +1 -3
- package/dist/deltaScheduler.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 +12 -8
- package/dist/gc/garbageCollection.js.map +1 -1
- package/dist/gc/gcConfigs.js +1 -1
- package/dist/gc/gcConfigs.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/gcHelpers.d.ts.map +1 -1
- package/dist/gc/gcHelpers.js.map +1 -1
- package/dist/gc/gcSummaryStateTracker.d.ts.map +1 -1
- 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 +1 -7
- package/dist/gc/gcTelemetry.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/messageTypes.d.ts +5 -21
- package/dist/messageTypes.d.ts.map +1 -1
- package/dist/messageTypes.js.map +1 -1
- package/dist/opLifecycle/index.d.ts +1 -1
- package/dist/opLifecycle/index.d.ts.map +1 -1
- package/dist/opLifecycle/index.js.map +1 -1
- package/dist/opLifecycle/opDecompressor.d.ts.map +1 -1
- package/dist/opLifecycle/opDecompressor.js +1 -2
- package/dist/opLifecycle/opDecompressor.js.map +1 -1
- package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -1
- package/dist/opLifecycle/opGroupingManager.js.map +1 -1
- package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
- package/dist/opLifecycle/opSplitter.js +1 -1
- package/dist/opLifecycle/opSplitter.js.map +1 -1
- package/dist/opLifecycle/outbox.d.ts.map +1 -1
- package/dist/opLifecycle/outbox.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.d.ts.map +1 -1
- package/dist/pendingStateManager.js +1 -1
- package/dist/pendingStateManager.js.map +1 -1
- package/dist/summary/documentSchema.d.ts.map +1 -1
- package/dist/summary/documentSchema.js +1 -2
- package/dist/summary/documentSchema.js.map +1 -1
- package/dist/summary/index.d.ts +1 -1
- package/dist/summary/index.d.ts.map +1 -1
- package/dist/summary/index.js.map +1 -1
- package/dist/summary/orderedClientElection.d.ts.map +1 -1
- package/dist/summary/orderedClientElection.js.map +1 -1
- package/dist/summary/runningSummarizer.d.ts.map +1 -1
- package/dist/summary/runningSummarizer.js +1 -2
- package/dist/summary/runningSummarizer.js.map +1 -1
- package/dist/summary/summarizerClientElection.d.ts.map +1 -1
- package/dist/summary/summarizerClientElection.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
- package/dist/summary/summarizerNode/summarizerNode.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeWithGc.js +4 -1
- package/dist/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
- package/dist/summary/summarizerTypes.d.ts.map +1 -1
- package/dist/summary/summarizerTypes.js.map +1 -1
- package/dist/summary/summaryCollection.d.ts.map +1 -1
- package/dist/summary/summaryCollection.js.map +1 -1
- package/dist/summary/summaryFormat.d.ts.map +1 -1
- package/dist/summary/summaryFormat.js.map +1 -1
- package/dist/summary/summaryGenerator.d.ts.map +1 -1
- package/dist/summary/summaryGenerator.js +1 -2
- package/dist/summary/summaryGenerator.js.map +1 -1
- package/dist/summary/summaryManager.d.ts.map +1 -1
- package/dist/summary/summaryManager.js +1 -2
- package/dist/summary/summaryManager.js.map +1 -1
- package/dist/throttler.d.ts.map +1 -1
- package/dist/throttler.js +3 -1
- package/dist/throttler.js.map +1 -1
- package/lib/batchTracker.d.ts.map +1 -1
- package/lib/batchTracker.js +1 -1
- package/lib/batchTracker.js.map +1 -1
- package/lib/blobManager.d.ts.map +1 -1
- package/lib/blobManager.js +1 -1
- 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 +86 -90
- package/lib/channelCollection.js.map +1 -1
- package/lib/connectionTelemetry.d.ts.map +1 -1
- package/lib/connectionTelemetry.js.map +1 -1
- package/lib/containerRuntime.d.ts +2 -1
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +32 -12
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStoreContext.d.ts +2 -1
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +5 -3
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/dataStoreContexts.d.ts.map +1 -1
- package/lib/dataStoreContexts.js +1 -1
- package/lib/dataStoreContexts.js.map +1 -1
- package/lib/deltaManagerProxies.d.ts.map +1 -1
- package/lib/deltaManagerProxies.js.map +1 -1
- package/lib/deltaScheduler.d.ts.map +1 -1
- package/lib/deltaScheduler.js +1 -3
- package/lib/deltaScheduler.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 +13 -9
- package/lib/gc/garbageCollection.js.map +1 -1
- package/lib/gc/gcConfigs.js +1 -1
- package/lib/gc/gcConfigs.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/gcHelpers.d.ts.map +1 -1
- package/lib/gc/gcHelpers.js.map +1 -1
- package/lib/gc/gcSummaryStateTracker.d.ts.map +1 -1
- 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 +1 -7
- package/lib/gc/gcTelemetry.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib/messageTypes.d.ts +5 -21
- package/lib/messageTypes.d.ts.map +1 -1
- package/lib/messageTypes.js.map +1 -1
- package/lib/opLifecycle/index.d.ts +1 -1
- package/lib/opLifecycle/index.d.ts.map +1 -1
- package/lib/opLifecycle/index.js +1 -1
- package/lib/opLifecycle/index.js.map +1 -1
- package/lib/opLifecycle/opDecompressor.d.ts.map +1 -1
- package/lib/opLifecycle/opDecompressor.js +1 -2
- package/lib/opLifecycle/opDecompressor.js.map +1 -1
- package/lib/opLifecycle/opGroupingManager.d.ts.map +1 -1
- package/lib/opLifecycle/opGroupingManager.js.map +1 -1
- package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
- package/lib/opLifecycle/opSplitter.js +1 -1
- package/lib/opLifecycle/opSplitter.js.map +1 -1
- package/lib/opLifecycle/outbox.d.ts.map +1 -1
- package/lib/opLifecycle/outbox.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.d.ts.map +1 -1
- package/lib/pendingStateManager.js +1 -1
- package/lib/pendingStateManager.js.map +1 -1
- package/lib/summary/documentSchema.d.ts.map +1 -1
- package/lib/summary/documentSchema.js +1 -2
- package/lib/summary/documentSchema.js.map +1 -1
- package/lib/summary/index.d.ts +1 -1
- package/lib/summary/index.d.ts.map +1 -1
- package/lib/summary/index.js +1 -1
- package/lib/summary/index.js.map +1 -1
- package/lib/summary/orderedClientElection.d.ts.map +1 -1
- package/lib/summary/orderedClientElection.js.map +1 -1
- package/lib/summary/runningSummarizer.d.ts.map +1 -1
- package/lib/summary/runningSummarizer.js +1 -2
- package/lib/summary/runningSummarizer.js.map +1 -1
- package/lib/summary/summarizerClientElection.d.ts.map +1 -1
- package/lib/summary/summarizerClientElection.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNode.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeWithGc.js +4 -1
- package/lib/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
- package/lib/summary/summarizerTypes.d.ts.map +1 -1
- package/lib/summary/summarizerTypes.js.map +1 -1
- package/lib/summary/summaryCollection.d.ts.map +1 -1
- package/lib/summary/summaryCollection.js.map +1 -1
- package/lib/summary/summaryFormat.d.ts.map +1 -1
- package/lib/summary/summaryFormat.js.map +1 -1
- package/lib/summary/summaryGenerator.d.ts.map +1 -1
- package/lib/summary/summaryGenerator.js +1 -2
- package/lib/summary/summaryGenerator.js.map +1 -1
- package/lib/summary/summaryManager.d.ts.map +1 -1
- package/lib/summary/summaryManager.js +1 -2
- package/lib/summary/summaryManager.js.map +1 -1
- package/lib/throttler.d.ts.map +1 -1
- package/lib/throttler.js +3 -1
- package/lib/throttler.js.map +1 -1
- package/package.json +33 -20
- package/src/batchTracker.ts +4 -1
- package/src/blobManager.ts +14 -16
- package/src/channelCollection.ts +139 -132
- package/src/connectionTelemetry.ts +3 -8
- package/src/containerRuntime.ts +72 -44
- package/src/dataStoreContext.ts +34 -11
- package/src/dataStoreContexts.ts +7 -2
- package/src/deltaManagerProxies.ts +12 -3
- package/src/deltaScheduler.ts +1 -3
- package/src/gc/garbageCollection.ts +47 -31
- package/src/gc/gcConfigs.ts +7 -3
- package/src/gc/gcDefinitions.ts +16 -4
- package/src/gc/gcHelpers.ts +6 -2
- package/src/gc/gcSummaryStateTracker.ts +4 -1
- package/src/gc/gcTelemetry.ts +2 -9
- package/src/index.ts +0 -1
- package/src/messageTypes.ts +7 -23
- package/src/opLifecycle/index.ts +5 -1
- package/src/opLifecycle/opDecompressor.ts +2 -6
- package/src/opLifecycle/opGroupingManager.ts +1 -4
- package/src/opLifecycle/opSplitter.ts +9 -3
- package/src/opLifecycle/outbox.ts +1 -4
- package/src/packageVersion.ts +1 -1
- package/src/pendingStateManager.ts +4 -2
- package/src/summary/documentSchema.ts +4 -7
- package/src/summary/index.ts +4 -1
- package/src/summary/orderedClientElection.ts +17 -10
- package/src/summary/runningSummarizer.ts +20 -9
- package/src/summary/summarizerClientElection.ts +2 -1
- package/src/summary/summarizerNode/summarizerNode.ts +6 -4
- package/src/summary/summarizerNode/summarizerNodeUtils.ts +7 -2
- package/src/summary/summarizerNode/summarizerNodeWithGc.ts +10 -6
- package/src/summary/summarizerTypes.ts +9 -2
- package/src/summary/summaryCollection.ts +4 -1
- package/src/summary/summaryFormat.ts +8 -3
- package/src/summary/summaryGenerator.ts +4 -9
- package/src/summary/summaryManager.ts +6 -9
- package/src/throttler.ts +3 -1
- package/tsdoc.json +4 -0
package/src/dataStoreContext.ts
CHANGED
|
@@ -94,7 +94,10 @@ function createAttributes(
|
|
|
94
94
|
isRootDataStore,
|
|
95
95
|
};
|
|
96
96
|
}
|
|
97
|
-
export function createAttributesBlob(
|
|
97
|
+
export function createAttributesBlob(
|
|
98
|
+
pkg: readonly string[],
|
|
99
|
+
isRootDataStore: boolean,
|
|
100
|
+
): ITreeEntry {
|
|
98
101
|
const attributes = createAttributes(pkg, isRootDataStore);
|
|
99
102
|
return new BlobTreeEntry(dataStoreAttributesBlobName, JSON.stringify(attributes));
|
|
100
103
|
}
|
|
@@ -157,7 +160,8 @@ export interface ILocalFluidDataStoreContextProps extends IFluidDataStoreContext
|
|
|
157
160
|
* Properties necessary for creating a local FluidDataStoreContext
|
|
158
161
|
* @internal
|
|
159
162
|
*/
|
|
160
|
-
export interface ILocalDetachedFluidDataStoreContextProps
|
|
163
|
+
export interface ILocalDetachedFluidDataStoreContextProps
|
|
164
|
+
extends ILocalFluidDataStoreContextProps {
|
|
161
165
|
readonly channelToDataStoreFn: (channel: IFluidDataStoreChannel) => IDataStore;
|
|
162
166
|
}
|
|
163
167
|
|
|
@@ -431,7 +435,9 @@ export abstract class FluidDataStoreContext
|
|
|
431
435
|
this._tombstoned = tombstone;
|
|
432
436
|
}
|
|
433
437
|
|
|
434
|
-
public abstract setAttachState(
|
|
438
|
+
public abstract setAttachState(
|
|
439
|
+
attachState: AttachState.Attaching | AttachState.Attached,
|
|
440
|
+
): void;
|
|
435
441
|
|
|
436
442
|
private rejectDeferredRealize(
|
|
437
443
|
reason: string,
|
|
@@ -448,7 +454,10 @@ export abstract class FluidDataStoreContext
|
|
|
448
454
|
}
|
|
449
455
|
|
|
450
456
|
public async realize(): Promise<IFluidDataStoreChannel> {
|
|
451
|
-
assert(
|
|
457
|
+
assert(
|
|
458
|
+
!this.detachedRuntimeCreation,
|
|
459
|
+
0x13d /* "Detached runtime creation on realize()" */,
|
|
460
|
+
);
|
|
452
461
|
if (!this.channelP) {
|
|
453
462
|
this.channelP = this.realizeCore(this.existing).catch((error) => {
|
|
454
463
|
const errorWrapped = DataProcessingError.wrapIfUnrecognized(
|
|
@@ -719,9 +728,10 @@ export abstract class FluidDataStoreContext
|
|
|
719
728
|
*
|
|
720
729
|
* @param fromPath - The absolute path of the node that added the reference.
|
|
721
730
|
* @param toPath - The absolute path of the outbound node that is referenced.
|
|
731
|
+
* @param messageTimestampMs - The timestamp of the message that added the reference.
|
|
722
732
|
*/
|
|
723
|
-
public addedGCOutboundRoute(fromPath: string, toPath: string) {
|
|
724
|
-
this.parentContext.addedGCOutboundRoute(fromPath, toPath);
|
|
733
|
+
public addedGCOutboundRoute(fromPath: string, toPath: string, messageTimestampMs?: number) {
|
|
734
|
+
this.parentContext.addedGCOutboundRoute(fromPath, toPath, messageTimestampMs);
|
|
725
735
|
}
|
|
726
736
|
|
|
727
737
|
/**
|
|
@@ -891,13 +901,17 @@ export abstract class FluidDataStoreContext
|
|
|
891
901
|
* Get the summary required when attaching this context's DataStore.
|
|
892
902
|
* Used for both Container Attach and DataStore Attach.
|
|
893
903
|
*/
|
|
894
|
-
public abstract getAttachSummary(
|
|
904
|
+
public abstract getAttachSummary(
|
|
905
|
+
telemetryContext?: ITelemetryContext,
|
|
906
|
+
): ISummaryTreeWithStats;
|
|
895
907
|
|
|
896
908
|
/**
|
|
897
909
|
* Get the GC Data for the initial state being attached so remote clients can learn of this DataStore's
|
|
898
910
|
* outbound routes.
|
|
899
911
|
*/
|
|
900
|
-
public abstract getAttachGCData(
|
|
912
|
+
public abstract getAttachGCData(
|
|
913
|
+
telemetryContext?: ITelemetryContext,
|
|
914
|
+
): IGarbageCollectionData;
|
|
901
915
|
|
|
902
916
|
public abstract getInitialSnapshotDetails(): Promise<ISnapshotDetails>;
|
|
903
917
|
|
|
@@ -1009,7 +1023,10 @@ export abstract class FluidDataStoreContext
|
|
|
1009
1023
|
this.localChangesTelemetryCount--;
|
|
1010
1024
|
}
|
|
1011
1025
|
|
|
1012
|
-
public getCreateChildSummarizerNodeFn(
|
|
1026
|
+
public getCreateChildSummarizerNodeFn(
|
|
1027
|
+
id: string,
|
|
1028
|
+
createParam: CreateChildSummarizerNodeParam,
|
|
1029
|
+
) {
|
|
1013
1030
|
return (
|
|
1014
1031
|
summarizeInternal: SummarizeInternalFn,
|
|
1015
1032
|
getGCDataFn: (fullGC?: boolean) => Promise<IGarbageCollectionData>,
|
|
@@ -1075,7 +1092,10 @@ export class RemoteFluidDataStoreContext extends FluidDataStoreContext {
|
|
|
1075
1092
|
// Sequence number of the snapshot.
|
|
1076
1093
|
let sequenceNumber: number | undefined;
|
|
1077
1094
|
// Check whether we need to fetch the snapshot first to load.
|
|
1078
|
-
if (
|
|
1095
|
+
if (
|
|
1096
|
+
this.snapshotFetchRequired === undefined &&
|
|
1097
|
+
this._baseSnapshot?.groupId !== undefined
|
|
1098
|
+
) {
|
|
1079
1099
|
assert(
|
|
1080
1100
|
this.blobContents !== undefined,
|
|
1081
1101
|
0x97a /* Blob contents should be present to evaluate */,
|
|
@@ -1143,7 +1163,10 @@ export class RemoteFluidDataStoreContext extends FluidDataStoreContext {
|
|
|
1143
1163
|
}
|
|
1144
1164
|
}
|
|
1145
1165
|
|
|
1146
|
-
assert(
|
|
1166
|
+
assert(
|
|
1167
|
+
this.pkg !== undefined,
|
|
1168
|
+
0x8f6 /* The datastore context package should be defined */,
|
|
1169
|
+
);
|
|
1147
1170
|
return {
|
|
1148
1171
|
pkg: this.pkg,
|
|
1149
1172
|
isRootDataStore,
|
package/src/dataStoreContexts.ts
CHANGED
|
@@ -5,12 +5,17 @@
|
|
|
5
5
|
|
|
6
6
|
import { IDisposable, ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
|
|
7
7
|
import { assert, Deferred, Lazy } from "@fluidframework/core-utils/internal";
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
ITelemetryLoggerExt,
|
|
10
|
+
createChildLogger,
|
|
11
|
+
} from "@fluidframework/telemetry-utils/internal";
|
|
9
12
|
|
|
10
13
|
import { FluidDataStoreContext, LocalFluidDataStoreContext } from "./dataStoreContext.js";
|
|
11
14
|
|
|
12
15
|
/** @internal */
|
|
13
|
-
export class DataStoreContexts
|
|
16
|
+
export class DataStoreContexts
|
|
17
|
+
implements Iterable<[string, FluidDataStoreContext]>, IDisposable
|
|
18
|
+
{
|
|
14
19
|
private readonly notBoundContexts = new Set<string>();
|
|
15
20
|
|
|
16
21
|
/** Attached and loaded context proxies */
|
|
@@ -100,7 +100,10 @@ export abstract class BaseDeltaManagerProxy
|
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
constructor(
|
|
103
|
-
protected readonly deltaManager: IDeltaManager<
|
|
103
|
+
protected readonly deltaManager: IDeltaManager<
|
|
104
|
+
ISequencedDocumentMessage,
|
|
105
|
+
IDocumentMessage
|
|
106
|
+
>,
|
|
104
107
|
) {
|
|
105
108
|
super();
|
|
106
109
|
|
|
@@ -192,7 +195,10 @@ export class DeltaManagerSummarizerProxy extends BaseDeltaManagerProxy {
|
|
|
192
195
|
private readonly isSummarizerClient: boolean;
|
|
193
196
|
|
|
194
197
|
constructor(
|
|
195
|
-
protected readonly deltaManager: IDeltaManager<
|
|
198
|
+
protected readonly deltaManager: IDeltaManager<
|
|
199
|
+
ISequencedDocumentMessage,
|
|
200
|
+
IDocumentMessage
|
|
201
|
+
>,
|
|
196
202
|
) {
|
|
197
203
|
super(deltaManager);
|
|
198
204
|
this.isSummarizerClient = this.deltaManager.clientDetails.type === summarizerClientType;
|
|
@@ -237,7 +243,10 @@ export class DeltaManagerPendingOpsProxy extends BaseDeltaManagerProxy {
|
|
|
237
243
|
};
|
|
238
244
|
|
|
239
245
|
constructor(
|
|
240
|
-
protected readonly deltaManager: IDeltaManager<
|
|
246
|
+
protected readonly deltaManager: IDeltaManager<
|
|
247
|
+
ISequencedDocumentMessage,
|
|
248
|
+
IDocumentMessage
|
|
249
|
+
>,
|
|
241
250
|
private readonly pendingStateManager: Pick<
|
|
242
251
|
PendingStateManager,
|
|
243
252
|
"minimumPendingMessageSequenceNumber"
|
package/src/deltaScheduler.ts
CHANGED
|
@@ -148,9 +148,7 @@ export class DeltaScheduler {
|
|
|
148
148
|
numberOfTurns: this.schedulingLog.numberOfTurns,
|
|
149
149
|
processingTime: formatTick(this.schedulingLog.totalProcessingTime),
|
|
150
150
|
opsProcessed:
|
|
151
|
-
this.schedulingLog.lastSequenceNumber -
|
|
152
|
-
this.schedulingLog.firstSequenceNumber +
|
|
153
|
-
1,
|
|
151
|
+
this.schedulingLog.lastSequenceNumber - this.schedulingLog.firstSequenceNumber + 1,
|
|
154
152
|
batchesProcessed: this.schedulingLog.numberOfBatchesProcessed,
|
|
155
153
|
duration: formatTick(currentTime - this.schedulingLog.startTime),
|
|
156
154
|
schedulingCount: this.schedulingCount,
|
|
@@ -12,7 +12,10 @@ import {
|
|
|
12
12
|
type IGarbageCollectionData,
|
|
13
13
|
type ITelemetryContext,
|
|
14
14
|
} from "@fluidframework/runtime-definitions/internal";
|
|
15
|
-
import {
|
|
15
|
+
import {
|
|
16
|
+
createResponseError,
|
|
17
|
+
responseToException,
|
|
18
|
+
} from "@fluidframework/runtime-utils/internal";
|
|
16
19
|
import {
|
|
17
20
|
ITelemetryLoggerExt,
|
|
18
21
|
DataProcessingError,
|
|
@@ -56,7 +59,10 @@ import {
|
|
|
56
59
|
urlToGCNodePath,
|
|
57
60
|
} from "./gcHelpers.js";
|
|
58
61
|
import { runGarbageCollection } from "./gcReferenceGraphAlgorithm.js";
|
|
59
|
-
import {
|
|
62
|
+
import {
|
|
63
|
+
IGarbageCollectionSnapshotData,
|
|
64
|
+
IGarbageCollectionState,
|
|
65
|
+
} from "./gcSummaryDefinitions.js";
|
|
60
66
|
import { GCSummaryStateTracker } from "./gcSummaryStateTracker.js";
|
|
61
67
|
import { GCTelemetryTracker } from "./gcTelemetry.js";
|
|
62
68
|
import {
|
|
@@ -242,10 +248,7 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
242
248
|
return undefined;
|
|
243
249
|
}
|
|
244
250
|
|
|
245
|
-
const snapshotData = await getGCDataFromSnapshot(
|
|
246
|
-
gcSnapshotTree,
|
|
247
|
-
readAndParseBlob,
|
|
248
|
-
);
|
|
251
|
+
const snapshotData = await getGCDataFromSnapshot(gcSnapshotTree, readAndParseBlob);
|
|
249
252
|
|
|
250
253
|
// If the GC version in base snapshot does not match the GC version currently in effect, the GC data
|
|
251
254
|
// in the snapshot cannot be interpreted correctly. Set everything to undefined except for
|
|
@@ -260,10 +263,7 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
260
263
|
}
|
|
261
264
|
return snapshotData;
|
|
262
265
|
} catch (error) {
|
|
263
|
-
const dpe = DataProcessingError.wrapIfUnrecognized(
|
|
264
|
-
error,
|
|
265
|
-
"FailedToInitializeGC",
|
|
266
|
-
);
|
|
266
|
+
const dpe = DataProcessingError.wrapIfUnrecognized(error, "FailedToInitializeGC");
|
|
267
267
|
dpe.addTelemetryProperties({
|
|
268
268
|
gcConfigs: JSON.stringify(this.configs),
|
|
269
269
|
});
|
|
@@ -746,7 +746,7 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
746
746
|
const containerGCMessage: ContainerRuntimeGCMessage = {
|
|
747
747
|
type: ContainerMessageType.GC,
|
|
748
748
|
contents,
|
|
749
|
-
compatDetails: { behavior: "Ignore" },
|
|
749
|
+
compatDetails: { behavior: "Ignore" }, // DEPRECATED: For temporary back compat only
|
|
750
750
|
};
|
|
751
751
|
this.submitMessage(containerGCMessage);
|
|
752
752
|
return;
|
|
@@ -814,14 +814,16 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
814
814
|
*/
|
|
815
815
|
const gcDataSuperSet = concatGarbageCollectionData(previousGCData, currentGCData);
|
|
816
816
|
const newOutboundRoutesSinceLastRun: string[] = [];
|
|
817
|
-
this.newReferencesSinceLastRun.forEach(
|
|
818
|
-
|
|
819
|
-
gcDataSuperSet.gcNodes[sourceNodeId]
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
817
|
+
this.newReferencesSinceLastRun.forEach(
|
|
818
|
+
(outboundRoutes: string[], sourceNodeId: string) => {
|
|
819
|
+
if (gcDataSuperSet.gcNodes[sourceNodeId] === undefined) {
|
|
820
|
+
gcDataSuperSet.gcNodes[sourceNodeId] = outboundRoutes;
|
|
821
|
+
} else {
|
|
822
|
+
gcDataSuperSet.gcNodes[sourceNodeId].push(...outboundRoutes);
|
|
823
|
+
}
|
|
824
|
+
newOutboundRoutesSinceLastRun.push(...outboundRoutes);
|
|
825
|
+
},
|
|
826
|
+
);
|
|
825
827
|
|
|
826
828
|
/**
|
|
827
829
|
* Run GC on the above reference graph starting with root and all new outbound routes. This will generate a
|
|
@@ -892,9 +894,14 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
892
894
|
/**
|
|
893
895
|
* Process a GC message.
|
|
894
896
|
* @param message - The GC message from the container runtime.
|
|
897
|
+
* @param messageTimestampMs - The timestamp of the message.
|
|
895
898
|
* @param local - Whether it was send by this client.
|
|
896
899
|
*/
|
|
897
|
-
public processMessage(
|
|
900
|
+
public processMessage(
|
|
901
|
+
message: ContainerRuntimeGCMessage,
|
|
902
|
+
messageTimestampMs: number,
|
|
903
|
+
local: boolean,
|
|
904
|
+
) {
|
|
898
905
|
const gcMessageType = message.contents.type;
|
|
899
906
|
switch (gcMessageType) {
|
|
900
907
|
case GarbageCollectionMessageType.Sweep: {
|
|
@@ -909,7 +916,12 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
909
916
|
|
|
910
917
|
// Mark the node as referenced to ensure it isn't Swept
|
|
911
918
|
const tombstonedNodePath = message.contents.nodePath;
|
|
912
|
-
this.addedOutboundReference(
|
|
919
|
+
this.addedOutboundReference(
|
|
920
|
+
"/",
|
|
921
|
+
tombstonedNodePath,
|
|
922
|
+
messageTimestampMs,
|
|
923
|
+
true /* autorecovery */,
|
|
924
|
+
);
|
|
913
925
|
|
|
914
926
|
// In case the cause of the TombstoneLoaded event is incorrect GC Data (i.e. the object is actually reachable),
|
|
915
927
|
// do fullGC on the next run to get a chance to repair (in the likely case the bug is not deterministic)
|
|
@@ -919,10 +931,7 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
919
931
|
}
|
|
920
932
|
default: {
|
|
921
933
|
if (
|
|
922
|
-
!compatBehaviorAllowsGCMessageType(
|
|
923
|
-
gcMessageType,
|
|
924
|
-
message.compatDetails?.behavior,
|
|
925
|
-
)
|
|
934
|
+
!compatBehaviorAllowsGCMessageType(gcMessageType, message.compatDetails?.behavior)
|
|
926
935
|
) {
|
|
927
936
|
const error = DataProcessingError.create(
|
|
928
937
|
`Garbage collection message of unknown type ${gcMessageType}`,
|
|
@@ -990,7 +999,9 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
990
999
|
request,
|
|
991
1000
|
headerData,
|
|
992
1001
|
}: IGCNodeUpdatedProps) {
|
|
993
|
-
|
|
1002
|
+
// If there is no reference timestamp to work with, no ops have been processed after creation. If so, skip
|
|
1003
|
+
// logging as nothing interesting would have happened worth logging.
|
|
1004
|
+
if (!this.shouldRunGC || timestampMs === undefined) {
|
|
994
1005
|
return;
|
|
995
1006
|
}
|
|
996
1007
|
|
|
@@ -1005,8 +1016,7 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
1005
1016
|
this.telemetryTracker.nodeUsed(trackedId, {
|
|
1006
1017
|
id: fullPath,
|
|
1007
1018
|
usageType: reason,
|
|
1008
|
-
currentReferenceTimestampMs:
|
|
1009
|
-
timestampMs ?? this.runtime.getCurrentReferenceTimestampMs(),
|
|
1019
|
+
currentReferenceTimestampMs: timestampMs,
|
|
1010
1020
|
packagePath,
|
|
1011
1021
|
completedGCRuns: this.completedRuns,
|
|
1012
1022
|
isTombstoned,
|
|
@@ -1085,7 +1095,7 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
1085
1095
|
type: GarbageCollectionMessageType.TombstoneLoaded,
|
|
1086
1096
|
nodePath,
|
|
1087
1097
|
},
|
|
1088
|
-
compatDetails: { behavior: "Ignore" },
|
|
1098
|
+
compatDetails: { behavior: "Ignore" }, // DEPRECATED: For temporary back compat only
|
|
1089
1099
|
};
|
|
1090
1100
|
this.submitMessage(containerGCMessage);
|
|
1091
1101
|
}
|
|
@@ -1096,9 +1106,15 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
1096
1106
|
*
|
|
1097
1107
|
* @param fromNodePath - The node from which the reference is added.
|
|
1098
1108
|
* @param toNodePath - The node to which the reference is added.
|
|
1109
|
+
* @param timestampMs - The timestamp of the message that added the reference.
|
|
1099
1110
|
* @param autorecovery - This reference is added artificially, for autorecovery. Used for logging.
|
|
1100
1111
|
*/
|
|
1101
|
-
public addedOutboundReference(
|
|
1112
|
+
public addedOutboundReference(
|
|
1113
|
+
fromNodePath: string,
|
|
1114
|
+
toNodePath: string,
|
|
1115
|
+
timestampMs: number,
|
|
1116
|
+
autorecovery?: true,
|
|
1117
|
+
) {
|
|
1102
1118
|
if (!this.shouldRunGC) {
|
|
1103
1119
|
return;
|
|
1104
1120
|
}
|
|
@@ -1129,7 +1145,7 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
1129
1145
|
id: toNodePath,
|
|
1130
1146
|
fromId: fromNodePath,
|
|
1131
1147
|
usageType: "Revived",
|
|
1132
|
-
currentReferenceTimestampMs:
|
|
1148
|
+
currentReferenceTimestampMs: timestampMs,
|
|
1133
1149
|
packagePath: undefined,
|
|
1134
1150
|
completedGCRuns: this.completedRuns,
|
|
1135
1151
|
isTombstoned: this.tombstones.includes(trackedId),
|
package/src/gc/gcConfigs.ts
CHANGED
|
@@ -122,7 +122,7 @@ export function generateGCConfigs(
|
|
|
122
122
|
!gcEnabled || tombstoneTimeoutMs === undefined
|
|
123
123
|
? false
|
|
124
124
|
: mc.config.getBoolean(runSweepKey) ??
|
|
125
|
-
|
|
125
|
+
(sweepAllowed && createParams.gcOptions.enableGCSweep === true);
|
|
126
126
|
const disableDatastoreSweep =
|
|
127
127
|
mc.config.getBoolean(disableDatastoreSweepKey) === true ||
|
|
128
128
|
createParams.gcOptions[gcDisableDataStoreSweepOptionName] === true;
|
|
@@ -199,7 +199,11 @@ export function generateGCConfigs(
|
|
|
199
199
|
*
|
|
200
200
|
* If there is no Session Expiry timeout, GC can never guarantee an object won't be revived, so return undefined.
|
|
201
201
|
*/
|
|
202
|
-
function computeTombstoneTimeout(
|
|
202
|
+
function computeTombstoneTimeout(
|
|
203
|
+
sessionExpiryTimeoutMs: number | undefined,
|
|
204
|
+
): number | undefined {
|
|
203
205
|
const bufferMs = oneDayMs;
|
|
204
|
-
return
|
|
206
|
+
return (
|
|
207
|
+
sessionExpiryTimeoutMs && sessionExpiryTimeoutMs + maxSnapshotCacheExpiryMs + bufferMs
|
|
208
|
+
);
|
|
205
209
|
}
|
package/src/gc/gcDefinitions.ts
CHANGED
|
@@ -365,9 +365,18 @@ export interface IGarbageCollector {
|
|
|
365
365
|
*/
|
|
366
366
|
nodeUpdated(props: IGCNodeUpdatedProps): void;
|
|
367
367
|
/** Called when a reference is added to a node. Used to identify nodes that were referenced between summaries. */
|
|
368
|
-
addedOutboundReference(
|
|
368
|
+
addedOutboundReference(
|
|
369
|
+
fromNodePath: string,
|
|
370
|
+
toNodePath: string,
|
|
371
|
+
timestampMs: number,
|
|
372
|
+
autorecovery?: true,
|
|
373
|
+
): void;
|
|
369
374
|
/** Called to process a garbage collection message. */
|
|
370
|
-
processMessage(
|
|
375
|
+
processMessage(
|
|
376
|
+
message: ContainerRuntimeGCMessage,
|
|
377
|
+
messageTimestampMs: number,
|
|
378
|
+
local: boolean,
|
|
379
|
+
): void;
|
|
371
380
|
/** Returns true if this node has been deleted by GC during sweep phase. */
|
|
372
381
|
isNodeDeleted(nodePath: string): boolean;
|
|
373
382
|
setConnectionState(connected: boolean, clientId?: string): void;
|
|
@@ -383,8 +392,11 @@ export interface IGCNodeUpdatedProps {
|
|
|
383
392
|
node: { type: (typeof GCNodeType)["DataStore" | "Blob"]; path: string };
|
|
384
393
|
/** Whether the node (or a subpath) was loaded or changed. */
|
|
385
394
|
reason: "Loaded" | "Changed";
|
|
386
|
-
/**
|
|
387
|
-
|
|
395
|
+
/**
|
|
396
|
+
* The op-based timestamp when the node changed. If the update is from receiving an op, this should
|
|
397
|
+
* be the timestamp of the op. If not, this should be the timestamp of the last op processed.
|
|
398
|
+
*/
|
|
399
|
+
timestampMs: number | undefined;
|
|
388
400
|
/** The package path of the node. This may not be available if the node hasn't been loaded yet */
|
|
389
401
|
packagePath?: readonly string[];
|
|
390
402
|
/** The original request for loads to preserve it in telemetry */
|
package/src/gc/gcHelpers.ts
CHANGED
|
@@ -78,8 +78,12 @@ export function shouldAllowGcSweep(
|
|
|
78
78
|
/**
|
|
79
79
|
* Sorts the given GC state as per the id of the GC nodes. It also sorts the outbound routes array of each node.
|
|
80
80
|
*/
|
|
81
|
-
export function generateSortedGCState(
|
|
82
|
-
|
|
81
|
+
export function generateSortedGCState(
|
|
82
|
+
gcState: IGarbageCollectionState,
|
|
83
|
+
): IGarbageCollectionState {
|
|
84
|
+
const sortableArray: [string, IGarbageCollectionNodeData][] = Object.entries(
|
|
85
|
+
gcState.gcNodes,
|
|
86
|
+
);
|
|
83
87
|
sortableArray.sort(([a], [b]) => a.localeCompare(b));
|
|
84
88
|
const sortedGCState: IGarbageCollectionState = { gcNodes: {} };
|
|
85
89
|
for (const [nodeId, nodeData] of sortableArray) {
|
|
@@ -18,7 +18,10 @@ import { IRefreshSummaryResult } from "../summary/index.js";
|
|
|
18
18
|
|
|
19
19
|
import { IGCStats, IGarbageCollectorConfigs } from "./gcDefinitions.js";
|
|
20
20
|
import { generateSortedGCState } from "./gcHelpers.js";
|
|
21
|
-
import {
|
|
21
|
+
import {
|
|
22
|
+
IGarbageCollectionSnapshotData,
|
|
23
|
+
IGarbageCollectionState,
|
|
24
|
+
} from "./gcSummaryDefinitions.js";
|
|
22
25
|
|
|
23
26
|
export const gcStateBlobKey = `${gcBlobPrefix}_root`;
|
|
24
27
|
|
package/src/gc/gcTelemetry.ts
CHANGED
|
@@ -63,7 +63,7 @@ interface INodeUsageProps extends ICommonProps {
|
|
|
63
63
|
/** The full path (in GC Path format) to the node in question */
|
|
64
64
|
id: string;
|
|
65
65
|
/** Latest timestamp received from the server, as a baseline for computing GC state/age */
|
|
66
|
-
currentReferenceTimestampMs: number
|
|
66
|
+
currentReferenceTimestampMs: number;
|
|
67
67
|
/** The package path of the node. This may not be available if the node hasn't been loaded yet */
|
|
68
68
|
packagePath: readonly string[] | undefined;
|
|
69
69
|
/** In case of Revived - what node added the reference? */
|
|
@@ -165,12 +165,6 @@ export class GCTelemetryTracker {
|
|
|
165
165
|
...otherNodeUsageProps
|
|
166
166
|
}: INodeUsageProps,
|
|
167
167
|
) {
|
|
168
|
-
// If there is no reference timestamp to work with, no ops have been processed after creation. If so, skip
|
|
169
|
-
// logging as nothing interesting would have happened worth logging.
|
|
170
|
-
if (currentReferenceTimestampMs === undefined) {
|
|
171
|
-
return;
|
|
172
|
-
}
|
|
173
|
-
|
|
174
168
|
// Note: For SubDataStore Load usage, trackedId will be the DataStore's id, not the full path in question.
|
|
175
169
|
// This is necessary because the SubDataStore path may be unrecognized by GC (if suited for a custom request handler)
|
|
176
170
|
const nodeStateTracker = this.getNodeStateTracker(trackedId);
|
|
@@ -390,8 +384,7 @@ export class GCTelemetryTracker {
|
|
|
390
384
|
*/
|
|
391
385
|
const nodeStateTracker = this.getNodeStateTracker(detailedProps.trackedId); // Note: This is never SubDataStore path
|
|
392
386
|
const active =
|
|
393
|
-
nodeStateTracker === undefined ||
|
|
394
|
-
nodeStateTracker.state === UnreferencedState.Active;
|
|
387
|
+
nodeStateTracker === undefined || nodeStateTracker.state === UnreferencedState.Active;
|
|
395
388
|
if ((usageType === "Revived") === active) {
|
|
396
389
|
const pkg = await this.getNodePackagePath(eventProps.id.value);
|
|
397
390
|
const fromPkg = eventProps.fromId
|
package/src/index.ts
CHANGED
package/src/messageTypes.ts
CHANGED
|
@@ -60,6 +60,7 @@ export enum ContainerMessageType {
|
|
|
60
60
|
/**
|
|
61
61
|
* How should an older client handle an unrecognized remote op type?
|
|
62
62
|
*
|
|
63
|
+
* @deprecated The utility of a mechanism to handle unknown messages is outweighed by the nuance required to get it right.
|
|
63
64
|
* @internal
|
|
64
65
|
*/
|
|
65
66
|
export type CompatModeBehavior =
|
|
@@ -71,6 +72,7 @@ export type CompatModeBehavior =
|
|
|
71
72
|
/**
|
|
72
73
|
* All the info an older client would need to know how to handle an unrecognized remote op type
|
|
73
74
|
*
|
|
75
|
+
* @deprecated The utility of a mechanism to handle unknown messages is outweighed by the nuance required to get it right.
|
|
74
76
|
* @internal
|
|
75
77
|
*/
|
|
76
78
|
export interface IContainerRuntimeMessageCompatDetails {
|
|
@@ -85,8 +87,7 @@ export interface IContainerRuntimeMessageCompatDetails {
|
|
|
85
87
|
* IMPORTANT: when creating one to be serialized, set the properties in the order they appear here.
|
|
86
88
|
* This way stringified values can be compared.
|
|
87
89
|
*/
|
|
88
|
-
interface TypedContainerRuntimeMessage<TType extends ContainerMessageType, TContents>
|
|
89
|
-
extends Partial<RecentlyAddedContainerRuntimeMessageDetails> {
|
|
90
|
+
interface TypedContainerRuntimeMessage<TType extends ContainerMessageType, TContents> {
|
|
90
91
|
/** Type of the op, within the ContainerRuntime's domain */
|
|
91
92
|
type: TType;
|
|
92
93
|
/** Domain-specific contents, interpreted according to the type */
|
|
@@ -95,6 +96,7 @@ interface TypedContainerRuntimeMessage<TType extends ContainerMessageType, TCont
|
|
|
95
96
|
|
|
96
97
|
/**
|
|
97
98
|
* Additional details expected for any recently added message.
|
|
99
|
+
* @deprecated The utility of a mechanism to handle unknown messages is outweighed by the nuance required to get it right.
|
|
98
100
|
* @internal
|
|
99
101
|
*/
|
|
100
102
|
export interface RecentlyAddedContainerRuntimeMessageDetails {
|
|
@@ -137,7 +139,9 @@ export type ContainerRuntimeIdAllocationMessage = TypedContainerRuntimeMessage<
|
|
|
137
139
|
export type ContainerRuntimeGCMessage = TypedContainerRuntimeMessage<
|
|
138
140
|
ContainerMessageType.GC,
|
|
139
141
|
GarbageCollectionMessage
|
|
140
|
-
|
|
142
|
+
> &
|
|
143
|
+
// While deprecating: GC messages may still contain compat details for now
|
|
144
|
+
Partial<RecentlyAddedContainerRuntimeMessageDetails>;
|
|
141
145
|
export type ContainerRuntimeDocumentSchemaMessage = TypedContainerRuntimeMessage<
|
|
142
146
|
ContainerMessageType.DocumentSchemaChange,
|
|
143
147
|
IDocumentSchemaChangeMessage
|
|
@@ -232,23 +236,3 @@ export type InboundSequencedContainerRuntimeMessageOrSystemMessage =
|
|
|
232
236
|
*/
|
|
233
237
|
export type InboundSequencedRecentlyAddedContainerRuntimeMessage = ISequencedDocumentMessage &
|
|
234
238
|
Partial<RecentlyAddedContainerRuntimeMessageDetails>;
|
|
235
|
-
|
|
236
|
-
/**
|
|
237
|
-
* The unpacked runtime message / details to be handled or dispatched by the ContainerRuntime
|
|
238
|
-
*
|
|
239
|
-
* IMPORTANT: when creating one to be serialized, set the properties in the order they appear here.
|
|
240
|
-
* This way stringified values can be compared.
|
|
241
|
-
*
|
|
242
|
-
* @deprecated this is an internal type which should not be used outside of the package.
|
|
243
|
-
* Internally, it is superseded by `TypedContainerRuntimeMessage`.
|
|
244
|
-
*
|
|
245
|
-
* @internal
|
|
246
|
-
*/
|
|
247
|
-
export interface ContainerRuntimeMessage {
|
|
248
|
-
/** Type of the op, within the ContainerRuntime's domain */
|
|
249
|
-
type: ContainerMessageType;
|
|
250
|
-
/** Domain-specific contents, interpreted according to the type */
|
|
251
|
-
contents: any;
|
|
252
|
-
/** Info describing how to handle this op in case the type is unrecognized (default: fail to process) */
|
|
253
|
-
compatDetails?: IContainerRuntimeMessageCompatDetails;
|
|
254
|
-
}
|
package/src/opLifecycle/index.ts
CHANGED
|
@@ -10,4 +10,8 @@ export { OpCompressor } from "./opCompressor.js";
|
|
|
10
10
|
export { OpDecompressor } from "./opDecompressor.js";
|
|
11
11
|
export { OpSplitter, splitOp, isChunkedMessage } from "./opSplitter.js";
|
|
12
12
|
export { RemoteMessageProcessor, unpackRuntimeMessage } from "./remoteMessageProcessor.js";
|
|
13
|
-
export {
|
|
13
|
+
export {
|
|
14
|
+
OpGroupingManager,
|
|
15
|
+
OpGroupingManagerConfig,
|
|
16
|
+
isGroupedBatch,
|
|
17
|
+
} from "./opGroupingManager.js";
|
|
@@ -65,8 +65,7 @@ export class OpDecompressor {
|
|
|
65
65
|
IsoBuffer.from(
|
|
66
66
|
(message.contents as IPackedContentsContents).packedContents,
|
|
67
67
|
"base64",
|
|
68
|
-
).toString("base64") ===
|
|
69
|
-
(message.contents as IPackedContentsContents).packedContents
|
|
68
|
+
).toString("base64") === (message.contents as IPackedContentsContents).packedContents
|
|
70
69
|
) {
|
|
71
70
|
this.logger.sendTelemetryEvent({
|
|
72
71
|
eventName: "LegacyCompression",
|
|
@@ -139,10 +138,7 @@ export class OpDecompressor {
|
|
|
139
138
|
|
|
140
139
|
if (batchMetadata === false || this.isSingleMessageBatch) {
|
|
141
140
|
// End of compressed batch
|
|
142
|
-
const returnMessage = newMessage(
|
|
143
|
-
message,
|
|
144
|
-
this.rootMessageContents[this.processedCount],
|
|
145
|
-
);
|
|
141
|
+
const returnMessage = newMessage(message, this.rootMessageContents[this.processedCount]);
|
|
146
142
|
|
|
147
143
|
this.activeBatch = false;
|
|
148
144
|
this.isSingleMessageBatch = false;
|
|
@@ -73,10 +73,7 @@ export class OpGroupingManager {
|
|
|
73
73
|
if (message.metadata) {
|
|
74
74
|
const keys = Object.keys(message.metadata);
|
|
75
75
|
assert(keys.length < 2, 0x5dd /* cannot group ops with metadata */);
|
|
76
|
-
assert(
|
|
77
|
-
keys.length === 0 || keys[0] === "batch",
|
|
78
|
-
0x5de /* unexpected op metadata */,
|
|
79
|
-
);
|
|
76
|
+
assert(keys.length === 0 || keys[0] === "batch", 0x5de /* unexpected op metadata */);
|
|
80
77
|
}
|
|
81
78
|
}
|
|
82
79
|
|
|
@@ -53,7 +53,9 @@ export class OpSplitter {
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
public get isBatchChunkingEnabled(): boolean {
|
|
56
|
-
return
|
|
56
|
+
return (
|
|
57
|
+
this.chunkSizeInBytes < Number.POSITIVE_INFINITY && this.submitBatchFn !== undefined
|
|
58
|
+
);
|
|
57
59
|
}
|
|
58
60
|
|
|
59
61
|
public get chunks(): ReadonlyMap<string, string[]> {
|
|
@@ -272,7 +274,8 @@ export const splitOp = (
|
|
|
272
274
|
);
|
|
273
275
|
|
|
274
276
|
const contentLength = op.contents.length;
|
|
275
|
-
const chunkCount =
|
|
277
|
+
const chunkCount =
|
|
278
|
+
Math.floor((contentLength - 1) / chunkSizeInBytes) + 1 + (extraOp ? 1 : 0);
|
|
276
279
|
let offset = 0;
|
|
277
280
|
for (let chunkId = 1; chunkId <= chunkCount; chunkId++) {
|
|
278
281
|
const chunk: IChunkedOp = {
|
|
@@ -306,7 +309,10 @@ export const splitOp = (
|
|
|
306
309
|
);
|
|
307
310
|
}
|
|
308
311
|
|
|
309
|
-
assert(
|
|
312
|
+
assert(
|
|
313
|
+
offset >= contentLength,
|
|
314
|
+
0x58c /* Content offset equal or larger than content length */,
|
|
315
|
+
);
|
|
310
316
|
assert(chunks.length === chunkCount, 0x5a5 /* Expected number of chunks */);
|
|
311
317
|
return chunks;
|
|
312
318
|
};
|
|
@@ -382,10 +382,7 @@ export class Outbox {
|
|
|
382
382
|
|
|
383
383
|
this.params.legacySendBatchFn(batch);
|
|
384
384
|
} else {
|
|
385
|
-
assert(
|
|
386
|
-
batch.referenceSequenceNumber !== undefined,
|
|
387
|
-
0x58e /* Batch must not be empty */,
|
|
388
|
-
);
|
|
385
|
+
assert(batch.referenceSequenceNumber !== undefined, 0x58e /* Batch must not be empty */);
|
|
389
386
|
this.params.submitBatchFn(
|
|
390
387
|
batch.content.map((message) => ({
|
|
391
388
|
contents: message.contents,
|
package/src/packageVersion.ts
CHANGED