@fluidframework/container-runtime 0.57.0-51086 → 0.57.2

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 (64) hide show
  1. package/dist/containerRuntime.d.ts +10 -6
  2. package/dist/containerRuntime.d.ts.map +1 -1
  3. package/dist/containerRuntime.js +64 -30
  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 +5 -7
  10. package/dist/dataStoreContext.d.ts.map +1 -1
  11. package/dist/dataStoreContext.js +11 -6
  12. package/dist/dataStoreContext.js.map +1 -1
  13. package/dist/dataStores.d.ts +1 -1
  14. package/dist/dataStores.d.ts.map +1 -1
  15. package/dist/dataStores.js +2 -2
  16. package/dist/dataStores.js.map +1 -1
  17. package/dist/garbageCollection.d.ts +24 -11
  18. package/dist/garbageCollection.d.ts.map +1 -1
  19. package/dist/garbageCollection.js +94 -53
  20. package/dist/garbageCollection.js.map +1 -1
  21. package/dist/index.d.ts +0 -1
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +1 -3
  24. package/dist/index.js.map +1 -1
  25. package/dist/packageVersion.d.ts +1 -1
  26. package/dist/packageVersion.d.ts.map +1 -1
  27. package/dist/packageVersion.js +1 -1
  28. package/dist/packageVersion.js.map +1 -1
  29. package/lib/containerRuntime.d.ts +10 -6
  30. package/lib/containerRuntime.d.ts.map +1 -1
  31. package/lib/containerRuntime.js +65 -31
  32. package/lib/containerRuntime.js.map +1 -1
  33. package/lib/dataStore.d.ts +1 -36
  34. package/lib/dataStore.d.ts.map +1 -1
  35. package/lib/dataStore.js +4 -26
  36. package/lib/dataStore.js.map +1 -1
  37. package/lib/dataStoreContext.d.ts +5 -7
  38. package/lib/dataStoreContext.d.ts.map +1 -1
  39. package/lib/dataStoreContext.js +11 -6
  40. package/lib/dataStoreContext.js.map +1 -1
  41. package/lib/dataStores.d.ts +1 -1
  42. package/lib/dataStores.d.ts.map +1 -1
  43. package/lib/dataStores.js +2 -2
  44. package/lib/dataStores.js.map +1 -1
  45. package/lib/garbageCollection.d.ts +24 -11
  46. package/lib/garbageCollection.d.ts.map +1 -1
  47. package/lib/garbageCollection.js +94 -53
  48. package/lib/garbageCollection.js.map +1 -1
  49. package/lib/index.d.ts +0 -1
  50. package/lib/index.d.ts.map +1 -1
  51. package/lib/index.js +0 -1
  52. package/lib/index.js.map +1 -1
  53. package/lib/packageVersion.d.ts +1 -1
  54. package/lib/packageVersion.d.ts.map +1 -1
  55. package/lib/packageVersion.js +1 -1
  56. package/lib/packageVersion.js.map +1 -1
  57. package/package.json +13 -13
  58. package/src/containerRuntime.ts +98 -34
  59. package/src/dataStore.ts +6 -42
  60. package/src/dataStoreContext.ts +15 -13
  61. package/src/dataStores.ts +8 -3
  62. package/src/garbageCollection.ts +114 -57
  63. package/src/index.ts +0 -1
  64. 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-51086";
8
+ export declare const pkgVersion = "0.57.2";
9
9
  //# sourceMappingURL=packageVersion.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"packageVersion.d.ts","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,OAAO,sCAAsC,CAAC;AAC3D,eAAO,MAAM,UAAU,iBAAiB,CAAC"}
1
+ {"version":3,"file":"packageVersion.d.ts","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,OAAO,sCAAsC,CAAC;AAC3D,eAAO,MAAM,UAAU,WAAW,CAAC"}
@@ -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-51086";
8
+ export const pkgVersion = "0.57.2";
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,cAAc,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-51086\";\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.2\";\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/container-runtime",
3
- "version": "0.57.0-51086",
3
+ "version": "0.57.2",
4
4
  "description": "Fluid container runtime",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": "https://github.com/microsoft/FluidFramework",
@@ -58,27 +58,27 @@
58
58
  "dependencies": {
59
59
  "@fluidframework/common-definitions": "^0.20.1",
60
60
  "@fluidframework/common-utils": "^0.32.1",
61
- "@fluidframework/container-definitions": "^0.46.0-0",
62
- "@fluidframework/container-runtime-definitions": "0.57.0-51086",
63
- "@fluidframework/container-utils": "0.57.0-51086",
61
+ "@fluidframework/container-definitions": "^0.46.0",
62
+ "@fluidframework/container-runtime-definitions": "^0.57.2",
63
+ "@fluidframework/container-utils": "^0.57.2",
64
64
  "@fluidframework/core-interfaces": "^0.42.0",
65
- "@fluidframework/datastore": "0.57.0-51086",
65
+ "@fluidframework/datastore": "^0.57.2",
66
66
  "@fluidframework/driver-definitions": "^0.44.0",
67
- "@fluidframework/driver-utils": "0.57.0-51086",
68
- "@fluidframework/garbage-collector": "0.57.0-51086",
67
+ "@fluidframework/driver-utils": "^0.57.2",
68
+ "@fluidframework/garbage-collector": "^0.57.2",
69
69
  "@fluidframework/protocol-base": "^0.1034.0",
70
70
  "@fluidframework/protocol-definitions": "^0.1026.0",
71
- "@fluidframework/runtime-definitions": "0.57.0-51086",
72
- "@fluidframework/runtime-utils": "0.57.0-51086",
73
- "@fluidframework/telemetry-utils": "0.57.0-51086",
71
+ "@fluidframework/runtime-definitions": "^0.57.2",
72
+ "@fluidframework/runtime-utils": "^0.57.2",
73
+ "@fluidframework/telemetry-utils": "^0.57.2",
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
- "@fluidframework/eslint-config-fluid": "^0.26.0-0",
80
- "@fluidframework/mocha-test-setup": "0.57.0-51086",
81
- "@fluidframework/test-runtime-utils": "0.57.0-51086",
79
+ "@fluidframework/eslint-config-fluid": "^0.26.0",
80
+ "@fluidframework/mocha-test-setup": "^0.57.2",
81
+ "@fluidframework/test-runtime-utils": "^0.57.2",
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
  }
@@ -952,8 +958,8 @@ export class ContainerRuntime extends TypedEventEmitter<IContainerRuntimeEvents>
952
958
  * and is the single source of truth for this container.
953
959
  */
954
960
  public readonly disableIsolatedChannels: boolean;
955
- /** The message in the metadata of the base summary this container is loaded from. */
956
- private readonly baseSummaryMessage: ISummaryMetadataMessage | undefined;
961
+ /** The last message processed at the time of the last summary. */
962
+ private messageAtLastSummary: ISummaryMetadataMessage | undefined;
957
963
 
958
964
  private get summarizer(): Summarizer {
959
965
  assert(this._summarizer !== undefined, 0x257 /* "This is not summarizing container" */);
@@ -984,7 +990,8 @@ export class ContainerRuntime extends TypedEventEmitter<IContainerRuntimeEvents>
984
990
  private _storage?: IDocumentStorageService,
985
991
  ) {
986
992
  super();
987
- this.baseSummaryMessage = metadata?.message;
993
+
994
+ this.messageAtLastSummary = metadata?.message;
988
995
 
989
996
  // If this is an existing container, we get values from metadata.
990
997
  // otherwise, we initialize them.
@@ -1020,25 +1027,20 @@ export class ContainerRuntime extends TypedEventEmitter<IContainerRuntimeEvents>
1020
1027
  (this.mc.config.getBoolean(useDataStoreAliasingKey) ?? false) ||
1021
1028
  (runtimeOptions.useDataStoreAliasing ?? false);
1022
1029
 
1023
- /**
1024
- * Function that return the current server timestamp. This is used by the garbage collector to set the
1025
- * time when a node becomes unreferenced.
1026
- * We use the timestamp of the last op for current timestamp. However, there can be cases where
1027
- * we don't have an op (on demand summaries for instance). In those cases, we will use the timestamp
1028
- * of this client's connection.
1029
- */
1030
- const getCurrentTimestamp = () => {
1031
- const client = this.clientId !== undefined ? this.getAudience().getMember(this.clientId) : undefined;
1032
- const timestamp = client?.timestamp;
1033
- return this.deltaManager.lastMessage?.timestamp ?? timestamp ?? Date.now();
1034
- };
1030
+ this.maxConsecutiveReconnects =
1031
+ this.mc.config.getNumber(maxConsecutiveReconnectsKey) ?? this.defaultMaxConsecutiveReconnects;
1032
+
1035
1033
  this.garbageCollector = GarbageCollector.create(
1036
1034
  this,
1037
1035
  this.runtimeOptions.gcOptions,
1038
1036
  (unusedRoutes: string[]) => this.dataStores.deleteUnusedRoutes(unusedRoutes),
1039
1037
  (nodePath: string) => this.dataStores.getNodePackagePath(nodePath),
1040
- getCurrentTimestamp,
1041
- this.closeFn,
1038
+ /**
1039
+ * Returns the timestamp of the last message seen by this client. This is used by garbage collector as
1040
+ * the current reference timestamp for tracking unreferenced objects.
1041
+ */
1042
+ () => this.deltaManager.lastMessage?.timestamp ?? this.messageAtLastSummary?.timestamp,
1043
+ () => this.messageAtLastSummary?.timestamp,
1042
1044
  context.baseSnapshot,
1043
1045
  async <T>(id: string) => readAndParse<T>(this.storage, id),
1044
1046
  this.mc.logger,
@@ -1090,8 +1092,12 @@ export class ContainerRuntime extends TypedEventEmitter<IContainerRuntimeEvents>
1090
1092
  (id: string) => this.summarizerNode.deleteChild(id),
1091
1093
  this.mc.logger,
1092
1094
  async () => this.garbageCollector.getDataStoreBaseGCDetails(),
1093
- (dataStorePath: string, packagePath?: readonly string[]) =>
1094
- this.garbageCollector.nodeUpdated(dataStorePath, "Changed", packagePath),
1095
+ (path: string, timestampMs: number, packagePath?: readonly string[]) => this.garbageCollector.nodeUpdated(
1096
+ path,
1097
+ "Changed",
1098
+ timestampMs,
1099
+ packagePath,
1100
+ ),
1095
1101
  new Map<string, string>(dataStoreAliasMap),
1096
1102
  this.garbageCollector.writeDataAtRoot,
1097
1103
  );
@@ -1393,9 +1399,13 @@ export class ContainerRuntime extends TypedEventEmitter<IContainerRuntimeEvents>
1393
1399
  }
1394
1400
 
1395
1401
  const dataStoreChannel = await dataStoreContext.realize();
1396
- // Let the garbage collector know that a data store was requested / loaded. Realize the data store first so
1397
- // that the package path is available.
1398
- this.garbageCollector.nodeUpdated(`/${id}`, "Loaded", dataStoreContext.packagePath, request?.headers);
1402
+ this.garbageCollector.nodeUpdated(
1403
+ `/${id}`,
1404
+ "Loaded",
1405
+ undefined /* timestampMs */,
1406
+ dataStoreContext.packagePath,
1407
+ request?.headers,
1408
+ );
1399
1409
  return dataStoreChannel;
1400
1410
  }
1401
1411
 
@@ -1406,9 +1416,9 @@ export class ContainerRuntime extends TypedEventEmitter<IContainerRuntimeEvents>
1406
1416
  summaryFormatVersion: 1,
1407
1417
  disableIsolatedChannels: this.disableIsolatedChannels || undefined,
1408
1418
  gcFeature: this.garbageCollector.gcSummaryFeatureVersion,
1409
- // The last message processed at the time of summary. If there are no messages, nothing has changed from
1410
- // the base summary we loaded from. So, use the message from its metadata blob.
1411
- message: extractSummaryMetadataMessage(this.deltaManager.lastMessage) ?? this.baseSummaryMessage,
1419
+ // The last message processed at the time of summary. If there are no new messages, use the message from the
1420
+ // last summary.
1421
+ message: extractSummaryMetadataMessage(this.deltaManager.lastMessage) ?? this.messageAtLastSummary,
1412
1422
  sessionExpiryTimeoutMs: this.garbageCollector.sessionExpiryTimeoutMs,
1413
1423
  };
1414
1424
  }
@@ -1446,6 +1456,42 @@ export class ContainerRuntime extends TypedEventEmitter<IContainerRuntimeEvents>
1446
1456
  }
1447
1457
  }
1448
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
+
1449
1495
  private replayPendingStates() {
1450
1496
  // We need to be able to send ops to replay states
1451
1497
  if (!this.canSendOps()) { return; }
@@ -1526,6 +1572,14 @@ export class ContainerRuntime extends TypedEventEmitter<IContainerRuntimeEvents>
1526
1572
  if (changeOfState) {
1527
1573
  this.deltaManager.off("op", this.onOp);
1528
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
+
1529
1583
  this.replayPendingStates();
1530
1584
  }
1531
1585
 
@@ -1589,6 +1643,13 @@ export class ContainerRuntime extends TypedEventEmitter<IContainerRuntimeEvents>
1589
1643
 
1590
1644
  this.emit("op", message);
1591
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
+ }
1592
1653
  } catch (e) {
1593
1654
  this.scheduleManager.afterOpProcessing(e, message);
1594
1655
  throw e;
@@ -1742,12 +1803,12 @@ export class ContainerRuntime extends TypedEventEmitter<IContainerRuntimeEvents>
1742
1803
  * @param props - Properties for the data store
1743
1804
  * @returns - An aliased data store which can can be found / loaded by alias.
1744
1805
  */
1745
- 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> {
1746
1807
  const internalId = uuid();
1747
1808
  const dataStore = await this._createDataStore(pkg, false /* isRoot */, internalId, props);
1748
- const aliasedDataStore = channelToDataStore(dataStore, internalId, this,this.dataStores, this.mc.logger);
1809
+ const aliasedDataStore = channelToDataStore(dataStore, internalId, this, this.dataStores, this.mc.logger);
1749
1810
  const result = await aliasedDataStore.trySetAlias(alias);
1750
- if (result !== AliasResult.Success) {
1811
+ if (result !== "Success") {
1751
1812
  throw new GenericError(
1752
1813
  "dataStoreAliasFailure",
1753
1814
  undefined /* error */,
@@ -1789,13 +1850,13 @@ export class ContainerRuntime extends TypedEventEmitter<IContainerRuntimeEvents>
1789
1850
  props?: any,
1790
1851
  id = uuid(),
1791
1852
  isRoot = false,
1792
- ): Promise<IFluidRouter> {
1853
+ ): Promise<IDataStore> {
1793
1854
  const fluidDataStore = await this.dataStores._createFluidDataStoreContext(
1794
1855
  Array.isArray(pkg) ? pkg : [pkg], id, isRoot, props).realize();
1795
1856
  if (isRoot) {
1796
1857
  fluidDataStore.bindToContext();
1797
1858
  }
1798
- return fluidDataStore;
1859
+ return channelToDataStore(fluidDataStore, id, this, this.dataStores, this.mc.logger);
1799
1860
  }
1800
1861
 
1801
1862
  public async _createDataStoreWithProps(
@@ -1803,7 +1864,7 @@ export class ContainerRuntime extends TypedEventEmitter<IContainerRuntimeEvents>
1803
1864
  props?: any,
1804
1865
  id = uuid(),
1805
1866
  isRoot = false,
1806
- ): Promise<IFluidRouter> {
1867
+ ): Promise<IDataStore> {
1807
1868
  return this._aliasingEnabled === true && isRoot ?
1808
1869
  this.createAndAliasDataStore(pkg, id, props) :
1809
1870
  this._createDataStoreWithPropsLegacy(pkg, props, id, isRoot);
@@ -2136,6 +2197,9 @@ export class ContainerRuntime extends TypedEventEmitter<IContainerRuntimeEvents>
2136
2197
  }
2137
2198
  const { summary: summaryTree, stats: partialStats } = summarizeResult;
2138
2199
 
2200
+ // Now that we have generated the summary, update the message at last summary to the last message processed.
2201
+ this.messageAtLastSummary = this.deltaManager.lastMessage;
2202
+
2139
2203
  // Counting dataStores and handles
2140
2204
  // Because handles are unchanged dataStores in the current logic,
2141
2205
  // summarized dataStore count is total dataStore count minus handle count
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,10 @@ 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;
848
+ /**
849
+ * @deprecated 0.16 Issue #1635, #3631
850
+ */
851
+ public readonly createProps?: any;
850
852
 
851
853
  constructor(props: ILocalFluidDataStoreContextProps) {
852
854
  super(
@@ -858,7 +860,8 @@ export class LocalFluidDataStoreContextBase extends FluidDataStoreContext {
858
860
  );
859
861
 
860
862
  this.snapshotTree = props.snapshotTree;
861
- this.isRootDataStore = props.isRootDataStore;
863
+ this.isRootDataStore = props.isRootDataStore ?? false;
864
+ this.createProps = props.createProps;
862
865
  this.attachListeners();
863
866
  }
864
867
 
@@ -933,7 +936,6 @@ export class LocalFluidDataStoreContextBase extends FluidDataStoreContext {
933
936
  return {
934
937
  pkg: this.pkg,
935
938
  snapshot,
936
- isRootDataStore: this.isRootDataStore,
937
939
  };
938
940
  }
939
941
 
package/src/dataStores.ts CHANGED
@@ -91,7 +91,8 @@ export class DataStores implements IDisposable {
91
91
  private readonly deleteChildSummarizerNodeFn: (id: string) => void,
92
92
  baseLogger: ITelemetryBaseLogger,
93
93
  getBaseGCDetails: () => Promise<Map<string, IGarbageCollectionDetailsBase>>,
94
- private readonly dataStoreChanged: (dataStorePath: string, packagePath?: readonly string[]) => void,
94
+ private readonly dataStoreChanged: (
95
+ dataStorePath: string, timestampMs: number, packagePath?: readonly string[]) => void,
95
96
  private readonly aliasMap: Map<string, string>,
96
97
  private readonly writeGCDataAtRoot: boolean,
97
98
  private readonly contexts: DataStoreContexts = new DataStoreContexts(baseLogger),
@@ -387,7 +388,11 @@ export class DataStores implements IDisposable {
387
388
  context.process(transformed, local, localMessageMetadata);
388
389
 
389
390
  // Notify that a data store changed. This is used to detect if a deleted data store is being used.
390
- this.dataStoreChanged(`/${envelope.address}`, context.isLoaded ? context.packagePath : undefined);
391
+ this.dataStoreChanged(
392
+ `/${envelope.address}`,
393
+ message.timestamp,
394
+ context.isLoaded ? context.packagePath : undefined,
395
+ );
391
396
  }
392
397
 
393
398
  public async getDataStore(id: string, wait: boolean): Promise<FluidDataStoreContext> {
@@ -612,7 +617,7 @@ export class DataStores implements IDisposable {
612
617
  // Currently, only return the data store package path for the node since GC is only interested in data stores.
613
618
  const dataStoreId = nodePath.split("/")[1];
614
619
  const context = this.contexts.get(dataStoreId);
615
- assert(context !== undefined, "Data store with given id does not exist");
620
+ assert(context !== undefined, 0x2b9 /* "Data store with given id does not exist" */);
616
621
  return context.isLoaded ? context.packagePath : undefined;
617
622
  }
618
623
  }