@fluidframework/container-runtime 0.57.0 → 0.57.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/dist/containerRuntime.d.ts +8 -4
  2. package/dist/containerRuntime.d.ts.map +1 -1
  3. package/dist/containerRuntime.js +52 -10
  4. package/dist/containerRuntime.js.map +1 -1
  5. package/dist/dataStore.d.ts +1 -36
  6. package/dist/dataStore.d.ts.map +1 -1
  7. package/dist/dataStore.js +5 -27
  8. package/dist/dataStore.js.map +1 -1
  9. package/dist/dataStoreContext.d.ts +1 -7
  10. package/dist/dataStoreContext.d.ts.map +1 -1
  11. package/dist/dataStoreContext.js +10 -6
  12. package/dist/dataStoreContext.js.map +1 -1
  13. package/dist/index.d.ts +0 -1
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +1 -3
  16. package/dist/index.js.map +1 -1
  17. package/dist/packageVersion.d.ts +1 -1
  18. package/dist/packageVersion.js +1 -1
  19. package/dist/packageVersion.js.map +1 -1
  20. package/lib/containerRuntime.d.ts +8 -4
  21. package/lib/containerRuntime.d.ts.map +1 -1
  22. package/lib/containerRuntime.js +53 -11
  23. package/lib/containerRuntime.js.map +1 -1
  24. package/lib/dataStore.d.ts +1 -36
  25. package/lib/dataStore.d.ts.map +1 -1
  26. package/lib/dataStore.js +4 -26
  27. package/lib/dataStore.js.map +1 -1
  28. package/lib/dataStoreContext.d.ts +1 -7
  29. package/lib/dataStoreContext.d.ts.map +1 -1
  30. package/lib/dataStoreContext.js +10 -6
  31. package/lib/dataStoreContext.js.map +1 -1
  32. package/lib/index.d.ts +0 -1
  33. package/lib/index.d.ts.map +1 -1
  34. package/lib/index.js +0 -1
  35. package/lib/index.js.map +1 -1
  36. package/lib/packageVersion.d.ts +1 -1
  37. package/lib/packageVersion.js +1 -1
  38. package/lib/packageVersion.js.map +1 -1
  39. package/package.json +11 -11
  40. package/src/containerRuntime.ts +69 -9
  41. package/src/dataStore.ts +6 -42
  42. package/src/dataStoreContext.ts +10 -13
  43. package/src/index.ts +0 -1
  44. package/src/packageVersion.ts +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACH,oBAAoB,EACpB,UAAU,EACV,uBAAuB,EACvB,iBAAiB,EACjB,sBAAsB,EACtB,wBAAwB,EACxB,yBAAyB,EACzB,gBAAgB,EAChB,cAAc,EACd,oBAAoB,EACpB,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,GACjB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EACH,YAAY,EACZ,SAAS,EACT,yBAAyB,EACzB,QAAQ,GACX,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACH,aAAa,EACb,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EACf,aAAa,GAChB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EACH,sBAAsB,EACtB,iBAAiB,EACjB,oBAAoB,EACpB,uBAAuB,EACvB,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,EACxB,0BAA0B,EAC1B,sBAAsB,EACtB,kBAAkB,EAClB,yBAAyB,EACzB,kBAAkB,EAClB,sBAAsB,EACtB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,EACjB,WAAW,EACX,iBAAiB,EACjB,4BAA4B,EAC5B,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,yBAAyB,EACzB,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,GACvB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACH,aAAa,EACb,qBAAqB,EACrB,QAAQ,EACR,0BAA0B,EAC1B,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,EACjB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,GACpB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,gCAAgC,EAAE,0BAA0B,EAAE,MAAM,gCAAgC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACH,oBAAoB,EACpB,UAAU,EACV,uBAAuB,EACvB,iBAAiB,EACjB,sBAAsB,EACtB,wBAAwB,EACxB,yBAAyB,EACzB,gBAAgB,EAChB,cAAc,EACd,oBAAoB,EACpB,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,GACjB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EACH,YAAY,EACZ,SAAS,EACT,yBAAyB,EACzB,QAAQ,GACX,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACH,aAAa,EACb,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EACf,aAAa,GAChB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EACH,sBAAsB,EACtB,iBAAiB,EACjB,oBAAoB,EACpB,uBAAuB,EACvB,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,EACxB,0BAA0B,EAC1B,sBAAsB,EACtB,kBAAkB,EAClB,yBAAyB,EACzB,kBAAkB,EAClB,sBAAsB,EACtB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,EACjB,WAAW,EACX,iBAAiB,EACjB,4BAA4B,EAC5B,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,yBAAyB,EACzB,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,GACvB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACH,aAAa,EACb,qBAAqB,EACrB,QAAQ,EACR,0BAA0B,EAC1B,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,EACjB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,GACpB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,gCAAgC,EAAE,0BAA0B,EAAE,MAAM,gCAAgC,CAAC"}
package/lib/index.js CHANGED
@@ -3,7 +3,6 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
  export { ContainerMessageType, isRuntimeMessage, RuntimeMessage, unpackRuntimeMessage, ScheduleManager, agentSchedulerId, ContainerRuntime, RuntimeHeaders, } from "./containerRuntime";
6
- export { AliasResult } from "./dataStore";
7
6
  export { DeltaScheduler } from "./deltaScheduler";
8
7
  export { FluidDataStoreRegistry } from "./dataStoreRegistry";
9
8
  export { gcBlobPrefix, gcTreeKey, } from "./garbageCollection";
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACH,oBAAoB,EAOpB,gBAAgB,EAChB,cAAc,EACd,oBAAoB,EACpB,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,GACjB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAc,WAAW,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EACH,YAAY,EACZ,SAAS,GAGZ,MAAM,qBAAqB,CAAC;AAQ7B,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAiBH,WAAW,GAWd,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAUH,iBAAiB,GACpB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAoC,0BAA0B,EAAE,MAAM,gCAAgC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nexport {\n ContainerMessageType,\n IChunkedOp,\n ContainerRuntimeMessage,\n IGCRuntimeOptions,\n ISummaryRuntimeOptions,\n IContainerRuntimeOptions,\n IRootSummaryTreeWithStats,\n isRuntimeMessage,\n RuntimeMessage,\n unpackRuntimeMessage,\n ScheduleManager,\n agentSchedulerId,\n ContainerRuntime,\n RuntimeHeaders,\n} from \"./containerRuntime\";\nexport { IDataStore, AliasResult } from \"./dataStore\";\nexport { DeltaScheduler } from \"./deltaScheduler\";\nexport { FluidDataStoreRegistry } from \"./dataStoreRegistry\";\nexport {\n gcBlobPrefix,\n gcTreeKey,\n IGarbageCollectionRuntime,\n IGCStats,\n} from \"./garbageCollection\";\nexport {\n IPendingFlush,\n IPendingFlushMode,\n IPendingLocalState,\n IPendingMessage,\n IPendingState,\n} from \"./pendingStateManager\";\nexport { Summarizer } from \"./summarizer\";\nexport {\n EnqueueSummarizeResult,\n IAckSummaryResult,\n IBaseSummarizeResult,\n IBroadcastSummaryResult,\n ICancellationToken,\n IConnectableRuntime,\n IEnqueueSummarizeOptions,\n IGenerateSummaryTreeResult,\n IGeneratedSummaryStats,\n INackSummaryResult,\n IOnDemandSummarizeOptions,\n IProvideSummarizer,\n ISubmitSummaryOpResult,\n ISubmitSummaryOptions,\n ISummarizeOptions,\n ISummarizeResults,\n ISummarizer,\n ISummarizerEvents,\n ISummarizerInternalsProvider,\n ISummarizerOptions,\n ISummarizerRuntime,\n ISummarizingWarning,\n ISummaryCancellationToken,\n IUploadSummaryResult,\n SubmitSummaryResult,\n SummarizeResultPart,\n SummarizerStopReason,\n} from \"./summarizerTypes\";\nexport {\n IAckedSummary,\n IClientSummaryWatcher,\n ISummary,\n ISummaryCollectionOpEvents,\n ISummaryAckMessage,\n ISummaryNackMessage,\n ISummaryOpMessage,\n OpActionEventListener,\n OpActionEventName,\n SummaryCollection,\n} from \"./summaryCollection\";\nexport { ICancellableSummarizerController, neverCancelledSummaryToken } from \"./runWhileConnectedCoordinator\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACH,oBAAoB,EAOpB,gBAAgB,EAChB,cAAc,EACd,oBAAoB,EACpB,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,GACjB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EACH,YAAY,EACZ,SAAS,GAGZ,MAAM,qBAAqB,CAAC;AAQ7B,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAiBH,WAAW,GAWd,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAUH,iBAAiB,GACpB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAoC,0BAA0B,EAAE,MAAM,gCAAgC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nexport {\n ContainerMessageType,\n IChunkedOp,\n ContainerRuntimeMessage,\n IGCRuntimeOptions,\n ISummaryRuntimeOptions,\n IContainerRuntimeOptions,\n IRootSummaryTreeWithStats,\n isRuntimeMessage,\n RuntimeMessage,\n unpackRuntimeMessage,\n ScheduleManager,\n agentSchedulerId,\n ContainerRuntime,\n RuntimeHeaders,\n} from \"./containerRuntime\";\nexport { DeltaScheduler } from \"./deltaScheduler\";\nexport { FluidDataStoreRegistry } from \"./dataStoreRegistry\";\nexport {\n gcBlobPrefix,\n gcTreeKey,\n IGarbageCollectionRuntime,\n IGCStats,\n} from \"./garbageCollection\";\nexport {\n IPendingFlush,\n IPendingFlushMode,\n IPendingLocalState,\n IPendingMessage,\n IPendingState,\n} from \"./pendingStateManager\";\nexport { Summarizer } from \"./summarizer\";\nexport {\n EnqueueSummarizeResult,\n IAckSummaryResult,\n IBaseSummarizeResult,\n IBroadcastSummaryResult,\n ICancellationToken,\n IConnectableRuntime,\n IEnqueueSummarizeOptions,\n IGenerateSummaryTreeResult,\n IGeneratedSummaryStats,\n INackSummaryResult,\n IOnDemandSummarizeOptions,\n IProvideSummarizer,\n ISubmitSummaryOpResult,\n ISubmitSummaryOptions,\n ISummarizeOptions,\n ISummarizeResults,\n ISummarizer,\n ISummarizerEvents,\n ISummarizerInternalsProvider,\n ISummarizerOptions,\n ISummarizerRuntime,\n ISummarizingWarning,\n ISummaryCancellationToken,\n IUploadSummaryResult,\n SubmitSummaryResult,\n SummarizeResultPart,\n SummarizerStopReason,\n} from \"./summarizerTypes\";\nexport {\n IAckedSummary,\n IClientSummaryWatcher,\n ISummary,\n ISummaryCollectionOpEvents,\n ISummaryAckMessage,\n ISummaryNackMessage,\n ISummaryOpMessage,\n OpActionEventListener,\n OpActionEventName,\n SummaryCollection,\n} from \"./summaryCollection\";\nexport { ICancellableSummarizerController, neverCancelledSummaryToken } from \"./runWhileConnectedCoordinator\";\n"]}
@@ -5,5 +5,5 @@
5
5
  * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
6
6
  */
7
7
  export declare const pkgName = "@fluidframework/container-runtime";
8
- export declare const pkgVersion = "0.57.0";
8
+ export declare const pkgVersion = "0.57.1";
9
9
  //# sourceMappingURL=packageVersion.d.ts.map
@@ -5,5 +5,5 @@
5
5
  * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
6
6
  */
7
7
  export const pkgName = "@fluidframework/container-runtime";
8
- export const pkgVersion = "0.57.0";
8
+ export const pkgVersion = "0.57.1";
9
9
  //# sourceMappingURL=packageVersion.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,mCAAmC,CAAC;AAC3D,MAAM,CAAC,MAAM,UAAU,GAAG,QAAQ,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/container-runtime\";\nexport const pkgVersion = \"0.57.0\";\n"]}
1
+ {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,mCAAmC,CAAC;AAC3D,MAAM,CAAC,MAAM,UAAU,GAAG,QAAQ,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/container-runtime\";\nexport const pkgVersion = \"0.57.1\";\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/container-runtime",
3
- "version": "0.57.0",
3
+ "version": "0.57.1",
4
4
  "description": "Fluid container runtime",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": "https://github.com/microsoft/FluidFramework",
@@ -59,26 +59,26 @@
59
59
  "@fluidframework/common-definitions": "^0.20.1",
60
60
  "@fluidframework/common-utils": "^0.32.1",
61
61
  "@fluidframework/container-definitions": "^0.46.0",
62
- "@fluidframework/container-runtime-definitions": "^0.57.0",
63
- "@fluidframework/container-utils": "^0.57.0",
62
+ "@fluidframework/container-runtime-definitions": "^0.57.1",
63
+ "@fluidframework/container-utils": "^0.57.1",
64
64
  "@fluidframework/core-interfaces": "^0.42.0",
65
- "@fluidframework/datastore": "^0.57.0",
65
+ "@fluidframework/datastore": "^0.57.1",
66
66
  "@fluidframework/driver-definitions": "^0.44.0",
67
- "@fluidframework/driver-utils": "^0.57.0",
68
- "@fluidframework/garbage-collector": "^0.57.0",
67
+ "@fluidframework/driver-utils": "^0.57.1",
68
+ "@fluidframework/garbage-collector": "^0.57.1",
69
69
  "@fluidframework/protocol-base": "^0.1034.0",
70
70
  "@fluidframework/protocol-definitions": "^0.1026.0",
71
- "@fluidframework/runtime-definitions": "^0.57.0",
72
- "@fluidframework/runtime-utils": "^0.57.0",
73
- "@fluidframework/telemetry-utils": "^0.57.0",
71
+ "@fluidframework/runtime-definitions": "^0.57.1",
72
+ "@fluidframework/runtime-utils": "^0.57.1",
73
+ "@fluidframework/telemetry-utils": "^0.57.1",
74
74
  "double-ended-queue": "^2.1.0-0",
75
75
  "uuid": "^8.3.1"
76
76
  },
77
77
  "devDependencies": {
78
78
  "@fluidframework/build-common": "^0.23.0",
79
79
  "@fluidframework/eslint-config-fluid": "^0.26.0",
80
- "@fluidframework/mocha-test-setup": "^0.57.0",
81
- "@fluidframework/test-runtime-utils": "^0.57.0",
80
+ "@fluidframework/mocha-test-setup": "^0.57.1",
81
+ "@fluidframework/test-runtime-utils": "^0.57.1",
82
82
  "@microsoft/api-extractor": "^7.16.1",
83
83
  "@rushstack/eslint-config": "^2.5.1",
84
84
  "@types/double-ended-queue": "^2.1.0",
@@ -2,7 +2,8 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
-
5
+ // See #9219
6
+ /* eslint-disable max-lines */
6
7
  import { EventEmitter } from "events";
7
8
  import { ITelemetryBaseLogger, ITelemetryGenericEvent, ITelemetryLogger } from "@fluidframework/common-definitions";
8
9
  import {
@@ -86,6 +87,7 @@ import {
86
87
  SummarizeInternalFn,
87
88
  channelsTreeName,
88
89
  IAttachMessage,
90
+ IDataStore,
89
91
  } from "@fluidframework/runtime-definitions";
90
92
  import {
91
93
  addBlobToSummary,
@@ -146,9 +148,7 @@ import {
146
148
  IGCStats,
147
149
  } from "./garbageCollection";
148
150
  import {
149
- AliasResult,
150
151
  channelToDataStore,
151
- IDataStore,
152
152
  IDataStoreAliasMessage,
153
153
  isDataStoreAliasMessage,
154
154
  } from "./dataStore";
@@ -336,6 +336,7 @@ interface OldContainerContextWithLogger extends IContainerContext {
336
336
  // Local storage key to set the default flush mode to TurnBased
337
337
  const turnBasedFlushModeKey = "Fluid.ContainerRuntime.FlushModeTurnBased";
338
338
  const useDataStoreAliasingKey = "Fluid.ContainerRuntime.UseDataStoreAliasing";
339
+ const maxConsecutiveReconnectsKey = "Fluid.ContainerRuntime.MaxConsecutiveReconnects";
339
340
 
340
341
  export enum RuntimeMessage {
341
342
  FluidDataStoreOp = "component",
@@ -892,6 +893,9 @@ export class ContainerRuntime extends TypedEventEmitter<IContainerRuntimeEvents>
892
893
  private readonly summarizerNode: IRootSummarizerNodeWithGC;
893
894
  private readonly _aliasingEnabled: boolean;
894
895
 
896
+ private readonly maxConsecutiveReconnects: number;
897
+ private readonly defaultMaxConsecutiveReconnects = 15;
898
+
895
899
  private _orderSequentiallyCalls: number = 0;
896
900
  private _flushMode: FlushMode;
897
901
  private needsFlush = false;
@@ -901,6 +905,8 @@ export class ContainerRuntime extends TypedEventEmitter<IContainerRuntimeEvents>
901
905
 
902
906
  private paused: boolean = false;
903
907
 
908
+ private consecutiveReconnects = 0;
909
+
904
910
  public get connected(): boolean {
905
911
  return this._connected;
906
912
  }
@@ -1021,6 +1027,9 @@ export class ContainerRuntime extends TypedEventEmitter<IContainerRuntimeEvents>
1021
1027
  (this.mc.config.getBoolean(useDataStoreAliasingKey) ?? false) ||
1022
1028
  (runtimeOptions.useDataStoreAliasing ?? false);
1023
1029
 
1030
+ this.maxConsecutiveReconnects =
1031
+ this.mc.config.getNumber(maxConsecutiveReconnectsKey) ?? this.defaultMaxConsecutiveReconnects;
1032
+
1024
1033
  this.garbageCollector = GarbageCollector.create(
1025
1034
  this,
1026
1035
  this.runtimeOptions.gcOptions,
@@ -1447,6 +1456,42 @@ export class ContainerRuntime extends TypedEventEmitter<IContainerRuntimeEvents>
1447
1456
  }
1448
1457
  }
1449
1458
 
1459
+ // Track how many times the container tries to reconnect with pending messages.
1460
+ // This happens when the connection state is changed and we reset the counter
1461
+ // when we are able to process a local op or when there are no pending messages.
1462
+ // If this counter reaches a max, it's a good indicator that the container
1463
+ // is not making progress and it is stuck in a retry loop.
1464
+ private shouldContinueReconnecting(): boolean {
1465
+ if (this.maxConsecutiveReconnects <= 0) {
1466
+ // Feature disabled, we never stop reconnecting
1467
+ return true;
1468
+ }
1469
+
1470
+ if (!this.pendingStateManager.hasPendingMessages()) {
1471
+ // If there are no pending messages, we can always reconnect
1472
+ this.resetReconnectCount();
1473
+ return true;
1474
+ }
1475
+
1476
+ this.consecutiveReconnects++;
1477
+ if (this.consecutiveReconnects === Math.floor(this.maxConsecutiveReconnects / 2)) {
1478
+ // If we're halfway through the max reconnects, send an event in order
1479
+ // to better identify false positives, if any. If the rate of this event
1480
+ // matches `MaxReconnectsWithNoProgress`, we can safely cut down
1481
+ // maxConsecutiveReconnects to half.
1482
+ this.mc.logger.sendTelemetryEvent({
1483
+ eventName: "ReconnectsWithNoProgress",
1484
+ attempts: this.consecutiveReconnects,
1485
+ });
1486
+ }
1487
+
1488
+ return this.consecutiveReconnects < this.maxConsecutiveReconnects;
1489
+ }
1490
+
1491
+ private resetReconnectCount() {
1492
+ this.consecutiveReconnects = 0;
1493
+ }
1494
+
1450
1495
  private replayPendingStates() {
1451
1496
  // We need to be able to send ops to replay states
1452
1497
  if (!this.canSendOps()) { return; }
@@ -1527,6 +1572,14 @@ export class ContainerRuntime extends TypedEventEmitter<IContainerRuntimeEvents>
1527
1572
  if (changeOfState) {
1528
1573
  this.deltaManager.off("op", this.onOp);
1529
1574
  this.context.pendingLocalState = undefined;
1575
+ if (!this.shouldContinueReconnecting()) {
1576
+ this.closeFn(new GenericError(
1577
+ "MaxReconnectsWithNoProgress",
1578
+ undefined, // error
1579
+ { attempts: this.consecutiveReconnects }));
1580
+ return;
1581
+ }
1582
+
1530
1583
  this.replayPendingStates();
1531
1584
  }
1532
1585
 
@@ -1590,6 +1643,13 @@ export class ContainerRuntime extends TypedEventEmitter<IContainerRuntimeEvents>
1590
1643
 
1591
1644
  this.emit("op", message);
1592
1645
  this.scheduleManager.afterOpProcessing(undefined, message);
1646
+
1647
+ if (local) {
1648
+ // If we have processed a local op, this means that the container is
1649
+ // making progress and we can reset the counter for how many times
1650
+ // we have consecutively replayed the pending states
1651
+ this.resetReconnectCount();
1652
+ }
1593
1653
  } catch (e) {
1594
1654
  this.scheduleManager.afterOpProcessing(e, message);
1595
1655
  throw e;
@@ -1743,12 +1803,12 @@ export class ContainerRuntime extends TypedEventEmitter<IContainerRuntimeEvents>
1743
1803
  * @param props - Properties for the data store
1744
1804
  * @returns - An aliased data store which can can be found / loaded by alias.
1745
1805
  */
1746
- private async createAndAliasDataStore(pkg: string | string[], alias: string, props?: any): Promise<IFluidRouter> {
1806
+ private async createAndAliasDataStore(pkg: string | string[], alias: string, props?: any): Promise<IDataStore> {
1747
1807
  const internalId = uuid();
1748
1808
  const dataStore = await this._createDataStore(pkg, false /* isRoot */, internalId, props);
1749
- const aliasedDataStore = channelToDataStore(dataStore, internalId, this,this.dataStores, this.mc.logger);
1809
+ const aliasedDataStore = channelToDataStore(dataStore, internalId, this, this.dataStores, this.mc.logger);
1750
1810
  const result = await aliasedDataStore.trySetAlias(alias);
1751
- if (result !== AliasResult.Success) {
1811
+ if (result !== "Success") {
1752
1812
  throw new GenericError(
1753
1813
  "dataStoreAliasFailure",
1754
1814
  undefined /* error */,
@@ -1790,13 +1850,13 @@ export class ContainerRuntime extends TypedEventEmitter<IContainerRuntimeEvents>
1790
1850
  props?: any,
1791
1851
  id = uuid(),
1792
1852
  isRoot = false,
1793
- ): Promise<IFluidRouter> {
1853
+ ): Promise<IDataStore> {
1794
1854
  const fluidDataStore = await this.dataStores._createFluidDataStoreContext(
1795
1855
  Array.isArray(pkg) ? pkg : [pkg], id, isRoot, props).realize();
1796
1856
  if (isRoot) {
1797
1857
  fluidDataStore.bindToContext();
1798
1858
  }
1799
- return fluidDataStore;
1859
+ return channelToDataStore(fluidDataStore, id, this, this.dataStores, this.mc.logger);
1800
1860
  }
1801
1861
 
1802
1862
  public async _createDataStoreWithProps(
@@ -1804,7 +1864,7 @@ export class ContainerRuntime extends TypedEventEmitter<IContainerRuntimeEvents>
1804
1864
  props?: any,
1805
1865
  id = uuid(),
1806
1866
  isRoot = false,
1807
- ): Promise<IFluidRouter> {
1867
+ ): Promise<IDataStore> {
1808
1868
  return this._aliasingEnabled === true && isRoot ?
1809
1869
  this.createAndAliasDataStore(pkg, id, props) :
1810
1870
  this._createDataStoreWithPropsLegacy(pkg, props, id, isRoot);
package/src/dataStore.ts CHANGED
@@ -6,8 +6,8 @@
6
6
  import { ITelemetryLogger } from "@fluidframework/common-definitions";
7
7
  import { unreachableCase } from "@fluidframework/common-utils";
8
8
  import { AttachState } from "@fluidframework/container-definitions";
9
- import { IFluidRouter, IRequest, IResponse } from "@fluidframework/core-interfaces";
10
- import { IFluidDataStoreChannel } from "@fluidframework/runtime-definitions";
9
+ import { IRequest, IResponse } from "@fluidframework/core-interfaces";
10
+ import { AliasResult, IDataStore, IFluidDataStoreChannel } from "@fluidframework/runtime-definitions";
11
11
  import { TelemetryDataTag } from "@fluidframework/telemetry-utils";
12
12
  import { ContainerRuntime } from "./containerRuntime";
13
13
  import { DataStores } from "./dataStores";
@@ -36,42 +36,6 @@ export interface IDataStoreAliasMessage {
36
36
  && typeof maybeDataStoreAliasMessage?.alias === "string";
37
37
  };
38
38
 
39
- /**
40
- * Encapsulates the return codes of the aliasing API
41
- */
42
- export enum AliasResult {
43
- /**
44
- * The datastore has been successfully aliased
45
- */
46
- Success = "Success",
47
- /**
48
- * There is already a datastore bound to the provided alias
49
- */
50
- Conflict = "Conflict",
51
- /**
52
- * The datastore is currently in the process of being aliased
53
- */
54
- Aliasing = "Aliasing",
55
- /**
56
- * The datastore has been attempted to be aliased before
57
- */
58
- AlreadyAliased = "AlreadyAliased",
59
- }
60
-
61
- /**
62
- * A fluid router with the capability of being assigned an alias
63
- */
64
- export interface IDataStore extends IFluidRouter {
65
- /**
66
- * Attempt to assign an alias to the datastore.
67
- * If the operation succeeds, the datastore can be referenced
68
- * by the supplied alias.
69
- *
70
- * @param alias - Given alias for this datastore.
71
- */
72
- trySetAlias(alias: string): Promise<AliasResult>;
73
- }
74
-
75
39
  export const channelToDataStore = (
76
40
  fluidDataStoreChannel: IFluidDataStoreChannel,
77
41
  internalId: string,
@@ -94,11 +58,11 @@ class DataStore implements IDataStore {
94
58
  switch (this.aliasState) {
95
59
  // If we're already aliasing, throw an exception
96
60
  case AliasState.Aliasing:
97
- return AliasResult.Aliasing;
61
+ return "Aliasing";
98
62
  // If this datastore is already aliased, return true only if this
99
63
  // is a repeated call for the same alias
100
64
  case AliasState.Aliased:
101
- return this.alias === alias ? AliasResult.Success : AliasResult.AlreadyAliased;
65
+ return this.alias === alias ? "Success" : "AlreadyAliased";
102
66
  // There is no current or past alias operation for this datastore,
103
67
  // it is safe to continue execution
104
68
  case AliasState.None: break;
@@ -118,7 +82,7 @@ class DataStore implements IDataStore {
118
82
  // Explicitly Lock-out future attempts of aliasing,
119
83
  // regardless of result
120
84
  this.aliasState = AliasState.Aliased;
121
- return localResult ? AliasResult.Success : AliasResult.Conflict;
85
+ return localResult ? "Success" : "Conflict";
122
86
  }
123
87
 
124
88
  const aliased = await this.ackBasedPromise<boolean>((resolve) => {
@@ -148,7 +112,7 @@ class DataStore implements IDataStore {
148
112
  return false;
149
113
  });
150
114
 
151
- return aliased ? AliasResult.Success : AliasResult.Conflict;
115
+ return aliased ? "Success" : "Conflict";
152
116
  }
153
117
 
154
118
  async request(request: IRequest): Promise<IResponse> {
@@ -106,11 +106,6 @@ export function createAttributesBlob(
106
106
 
107
107
  interface ISnapshotDetails {
108
108
  pkg: readonly string[];
109
- /**
110
- * This tells whether a data store is root. Root data stores are never collected.
111
- * Non-root data stores may be collected if they are not used.
112
- */
113
- isRootDataStore: boolean;
114
109
  snapshot?: ISnapshotTree;
115
110
  }
116
111
 
@@ -212,7 +207,10 @@ export abstract class FluidDataStoreContext extends TypedEventEmitter<IFluidData
212
207
  }
213
208
 
214
209
  public async isRoot(): Promise<boolean> {
215
- return (await this.getInitialSnapshotDetails()).isRootDataStore;
210
+ // This call updates this.isRootDataStore if it has not yet been updated
211
+ // The initial value is stored in the initial snapshot of the data store
212
+ await this.getInitialSnapshotDetails();
213
+ return this.isRootDataStore;
216
214
  }
217
215
 
218
216
  protected registry: IFluidDataStoreRegistry | undefined;
@@ -225,6 +223,7 @@ export abstract class FluidDataStoreContext extends TypedEventEmitter<IFluidData
225
223
  protected channelDeferred: Deferred<IFluidDataStoreChannel> | undefined;
226
224
  private _baseSnapshot: ISnapshotTree | undefined;
227
225
  protected _attachState: AttachState;
226
+ protected isRootDataStore: boolean = false;
228
227
  protected readonly summarizerNode: ISummarizerNodeWithGC;
229
228
  private readonly subLogger: ITelemetryLogger;
230
229
  private readonly thresholdOpsCounter: ThresholdCounter;
@@ -450,8 +449,8 @@ export abstract class FluidDataStoreContext extends TypedEventEmitter<IFluidData
450
449
  }
451
450
 
452
451
  // Add data store's attributes to the summary.
453
- const { pkg, isRootDataStore } = await this.getInitialSnapshotDetails();
454
- const attributes = createAttributes(pkg, isRootDataStore, this.disableIsolatedChannels);
452
+ const { pkg } = await this.getInitialSnapshotDetails();
453
+ const attributes = createAttributes(pkg, this.isRootDataStore, this.disableIsolatedChannels);
455
454
  addBlobToSummary(summarizeResult, dataStoreAttributesBlobName, JSON.stringify(attributes));
456
455
 
457
456
  // Add GC data to the summary if it's not written at the root.
@@ -729,7 +728,6 @@ export abstract class FluidDataStoreContext extends TypedEventEmitter<IFluidData
729
728
  }
730
729
 
731
730
  export class RemoteFluidDataStoreContext extends FluidDataStoreContext {
732
- private isRootDataStore: boolean | undefined;
733
731
  private readonly initSnapshotValue: ISnapshotTree | string | undefined;
734
732
  private readonly baseGCDetailsP: Promise<IGarbageCollectionDetailsBase>;
735
733
 
@@ -804,11 +802,12 @@ export class RemoteFluidDataStoreContext extends FluidDataStoreContext {
804
802
  }
805
803
  }
806
804
 
805
+ this.isRootDataStore = isRootDataStore;
806
+
807
807
  return {
808
808
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
809
809
  pkg: this.pkg!,
810
810
  snapshot: tree,
811
- isRootDataStore,
812
811
  };
813
812
  });
814
813
 
@@ -846,7 +845,6 @@ export class RemoteFluidDataStoreContext extends FluidDataStoreContext {
846
845
  */
847
846
  export class LocalFluidDataStoreContextBase extends FluidDataStoreContext {
848
847
  private readonly snapshotTree: ISnapshotTree | undefined;
849
- protected isRootDataStore: boolean | undefined;
850
848
  /**
851
849
  * @deprecated 0.16 Issue #1635, #3631
852
850
  */
@@ -862,7 +860,7 @@ export class LocalFluidDataStoreContextBase extends FluidDataStoreContext {
862
860
  );
863
861
 
864
862
  this.snapshotTree = props.snapshotTree;
865
- this.isRootDataStore = props.isRootDataStore;
863
+ this.isRootDataStore = props.isRootDataStore ?? false;
866
864
  this.createProps = props.createProps;
867
865
  this.attachListeners();
868
866
  }
@@ -938,7 +936,6 @@ export class LocalFluidDataStoreContextBase extends FluidDataStoreContext {
938
936
  return {
939
937
  pkg: this.pkg,
940
938
  snapshot,
941
- isRootDataStore: this.isRootDataStore,
942
939
  };
943
940
  }
944
941
 
package/src/index.ts CHANGED
@@ -19,7 +19,6 @@ export {
19
19
  ContainerRuntime,
20
20
  RuntimeHeaders,
21
21
  } from "./containerRuntime";
22
- export { IDataStore, AliasResult } from "./dataStore";
23
22
  export { DeltaScheduler } from "./deltaScheduler";
24
23
  export { FluidDataStoreRegistry } from "./dataStoreRegistry";
25
24
  export {
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/container-runtime";
9
- export const pkgVersion = "0.57.0";
9
+ export const pkgVersion = "0.57.1";