@fluidframework/container-loader 2.0.0-dev.4.4.0.162574 → 2.0.0-dev.5.3.2.178189

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 (179) hide show
  1. package/CHANGELOG.md +59 -0
  2. package/README.md +27 -3
  3. package/dist/catchUpMonitor.d.ts +1 -1
  4. package/dist/catchUpMonitor.d.ts.map +1 -1
  5. package/dist/catchUpMonitor.js.map +1 -1
  6. package/dist/connectionManager.d.ts +3 -2
  7. package/dist/connectionManager.d.ts.map +1 -1
  8. package/dist/connectionManager.js +32 -13
  9. package/dist/connectionManager.js.map +1 -1
  10. package/dist/connectionStateHandler.d.ts +18 -3
  11. package/dist/connectionStateHandler.d.ts.map +1 -1
  12. package/dist/connectionStateHandler.js +34 -9
  13. package/dist/connectionStateHandler.js.map +1 -1
  14. package/dist/container.d.ts +99 -70
  15. package/dist/container.d.ts.map +1 -1
  16. package/dist/container.js +260 -218
  17. package/dist/container.js.map +1 -1
  18. package/dist/containerContext.d.ts +24 -67
  19. package/dist/containerContext.d.ts.map +1 -1
  20. package/dist/containerContext.js +28 -217
  21. package/dist/containerContext.js.map +1 -1
  22. package/dist/containerStorageAdapter.d.ts +3 -3
  23. package/dist/containerStorageAdapter.d.ts.map +1 -1
  24. package/dist/containerStorageAdapter.js +29 -6
  25. package/dist/containerStorageAdapter.js.map +1 -1
  26. package/dist/contracts.d.ts +9 -3
  27. package/dist/contracts.d.ts.map +1 -1
  28. package/dist/contracts.js.map +1 -1
  29. package/dist/deltaManager.d.ts +22 -9
  30. package/dist/deltaManager.d.ts.map +1 -1
  31. package/dist/deltaManager.js +42 -31
  32. package/dist/deltaManager.js.map +1 -1
  33. package/dist/deltaQueue.d.ts +2 -3
  34. package/dist/deltaQueue.d.ts.map +1 -1
  35. package/dist/deltaQueue.js +2 -3
  36. package/dist/deltaQueue.js.map +1 -1
  37. package/dist/disposal.d.ts +13 -0
  38. package/dist/disposal.d.ts.map +1 -0
  39. package/dist/disposal.js +25 -0
  40. package/dist/disposal.js.map +1 -0
  41. package/dist/index.d.ts +1 -2
  42. package/dist/index.d.ts.map +1 -1
  43. package/dist/index.js.map +1 -1
  44. package/dist/loader.d.ts +9 -8
  45. package/dist/loader.d.ts.map +1 -1
  46. package/dist/loader.js +47 -61
  47. package/dist/loader.js.map +1 -1
  48. package/dist/noopHeuristic.d.ts +23 -0
  49. package/dist/noopHeuristic.d.ts.map +1 -0
  50. package/dist/{collabWindowTracker.js → noopHeuristic.js} +30 -42
  51. package/dist/noopHeuristic.js.map +1 -0
  52. package/dist/packageVersion.d.ts +1 -1
  53. package/dist/packageVersion.js +1 -1
  54. package/dist/packageVersion.js.map +1 -1
  55. package/dist/protocol.d.ts +7 -12
  56. package/dist/protocol.d.ts.map +1 -1
  57. package/dist/protocol.js +17 -19
  58. package/dist/protocol.js.map +1 -1
  59. package/dist/protocolTreeDocumentStorageService.d.ts +1 -1
  60. package/dist/protocolTreeDocumentStorageService.d.ts.map +1 -1
  61. package/dist/protocolTreeDocumentStorageService.js.map +1 -1
  62. package/dist/quorum.d.ts +1 -17
  63. package/dist/quorum.d.ts.map +1 -1
  64. package/dist/quorum.js +1 -17
  65. package/dist/quorum.js.map +1 -1
  66. package/dist/retriableDocumentStorageService.d.ts +3 -2
  67. package/dist/retriableDocumentStorageService.d.ts.map +1 -1
  68. package/dist/retriableDocumentStorageService.js.map +1 -1
  69. package/dist/tsdoc-metadata.json +11 -0
  70. package/dist/utils.d.ts +2 -0
  71. package/dist/utils.d.ts.map +1 -1
  72. package/dist/utils.js +8 -1
  73. package/dist/utils.js.map +1 -1
  74. package/lib/catchUpMonitor.d.ts +1 -1
  75. package/lib/catchUpMonitor.d.ts.map +1 -1
  76. package/lib/catchUpMonitor.js.map +1 -1
  77. package/lib/connectionManager.d.ts +3 -2
  78. package/lib/connectionManager.d.ts.map +1 -1
  79. package/lib/connectionManager.js +33 -14
  80. package/lib/connectionManager.js.map +1 -1
  81. package/lib/connectionStateHandler.d.ts +18 -3
  82. package/lib/connectionStateHandler.d.ts.map +1 -1
  83. package/lib/connectionStateHandler.js +35 -10
  84. package/lib/connectionStateHandler.js.map +1 -1
  85. package/lib/container.d.ts +99 -70
  86. package/lib/container.d.ts.map +1 -1
  87. package/lib/container.js +264 -222
  88. package/lib/container.js.map +1 -1
  89. package/lib/containerContext.d.ts +24 -67
  90. package/lib/containerContext.d.ts.map +1 -1
  91. package/lib/containerContext.js +28 -217
  92. package/lib/containerContext.js.map +1 -1
  93. package/lib/containerStorageAdapter.d.ts +3 -3
  94. package/lib/containerStorageAdapter.d.ts.map +1 -1
  95. package/lib/containerStorageAdapter.js +29 -6
  96. package/lib/containerStorageAdapter.js.map +1 -1
  97. package/lib/contracts.d.ts +9 -3
  98. package/lib/contracts.d.ts.map +1 -1
  99. package/lib/contracts.js.map +1 -1
  100. package/lib/deltaManager.d.ts +22 -9
  101. package/lib/deltaManager.d.ts.map +1 -1
  102. package/lib/deltaManager.js +44 -33
  103. package/lib/deltaManager.js.map +1 -1
  104. package/lib/deltaQueue.d.ts +2 -3
  105. package/lib/deltaQueue.d.ts.map +1 -1
  106. package/lib/deltaQueue.js +2 -3
  107. package/lib/deltaQueue.js.map +1 -1
  108. package/lib/disposal.d.ts +13 -0
  109. package/lib/disposal.d.ts.map +1 -0
  110. package/lib/disposal.js +21 -0
  111. package/lib/disposal.js.map +1 -0
  112. package/lib/index.d.ts +1 -2
  113. package/lib/index.d.ts.map +1 -1
  114. package/lib/index.js +1 -1
  115. package/lib/index.js.map +1 -1
  116. package/lib/loader.d.ts +9 -8
  117. package/lib/loader.d.ts.map +1 -1
  118. package/lib/loader.js +47 -61
  119. package/lib/loader.js.map +1 -1
  120. package/lib/noopHeuristic.d.ts +23 -0
  121. package/lib/noopHeuristic.d.ts.map +1 -0
  122. package/lib/{collabWindowTracker.js → noopHeuristic.js} +30 -42
  123. package/lib/noopHeuristic.js.map +1 -0
  124. package/lib/packageVersion.d.ts +1 -1
  125. package/lib/packageVersion.js +1 -1
  126. package/lib/packageVersion.js.map +1 -1
  127. package/lib/protocol.d.ts +7 -12
  128. package/lib/protocol.d.ts.map +1 -1
  129. package/lib/protocol.js +15 -18
  130. package/lib/protocol.js.map +1 -1
  131. package/lib/protocolTreeDocumentStorageService.d.ts +1 -1
  132. package/lib/protocolTreeDocumentStorageService.d.ts.map +1 -1
  133. package/lib/protocolTreeDocumentStorageService.js.map +1 -1
  134. package/lib/quorum.d.ts +1 -17
  135. package/lib/quorum.d.ts.map +1 -1
  136. package/lib/quorum.js +1 -16
  137. package/lib/quorum.js.map +1 -1
  138. package/lib/retriableDocumentStorageService.d.ts +3 -2
  139. package/lib/retriableDocumentStorageService.d.ts.map +1 -1
  140. package/lib/retriableDocumentStorageService.js.map +1 -1
  141. package/lib/utils.d.ts +2 -0
  142. package/lib/utils.d.ts.map +1 -1
  143. package/lib/utils.js +7 -1
  144. package/lib/utils.js.map +1 -1
  145. package/package.json +22 -20
  146. package/src/catchUpMonitor.ts +1 -1
  147. package/src/connectionManager.ts +40 -22
  148. package/src/connectionStateHandler.ts +66 -17
  149. package/src/container.ts +464 -292
  150. package/src/containerContext.ts +33 -341
  151. package/src/containerStorageAdapter.ts +40 -10
  152. package/src/contracts.ts +11 -3
  153. package/src/deltaManager.ts +74 -45
  154. package/src/deltaQueue.ts +2 -3
  155. package/src/disposal.ts +25 -0
  156. package/src/index.ts +1 -8
  157. package/src/loader.ts +85 -83
  158. package/src/{collabWindowTracker.ts → noopHeuristic.ts} +37 -47
  159. package/src/packageVersion.ts +1 -1
  160. package/src/protocol.ts +18 -39
  161. package/src/protocolTreeDocumentStorageService.ts +1 -1
  162. package/src/quorum.ts +2 -31
  163. package/src/retriableDocumentStorageService.ts +4 -2
  164. package/src/utils.ts +15 -1
  165. package/dist/collabWindowTracker.d.ts +0 -19
  166. package/dist/collabWindowTracker.d.ts.map +0 -1
  167. package/dist/collabWindowTracker.js.map +0 -1
  168. package/dist/deltaManagerProxy.d.ts +0 -42
  169. package/dist/deltaManagerProxy.d.ts.map +0 -1
  170. package/dist/deltaManagerProxy.js +0 -79
  171. package/dist/deltaManagerProxy.js.map +0 -1
  172. package/lib/collabWindowTracker.d.ts +0 -19
  173. package/lib/collabWindowTracker.d.ts.map +0 -1
  174. package/lib/collabWindowTracker.js.map +0 -1
  175. package/lib/deltaManagerProxy.d.ts +0 -42
  176. package/lib/deltaManagerProxy.d.ts.map +0 -1
  177. package/lib/deltaManagerProxy.js +0 -74
  178. package/lib/deltaManagerProxy.js.map +0 -1
  179. package/src/deltaManagerProxy.ts +0 -109
package/CHANGELOG.md CHANGED
@@ -1,5 +1,64 @@
1
1
  # @fluidframework/container-loader
2
2
 
3
+ ## 2.0.0-internal.5.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Move closeAndGetPendingLocalState to IContainerExperimental ([#16302](https://github.com/microsoft/FluidFramework/issues/16302)) [93151af787](https://github.com/microsoft/FluidFramework/commits/93151af787b76e547cf3460df47f81832131db8c)
8
+
9
+ This change deprecates the experimental method closeAndGetPendingLocalState on IContainer and moves it to IContainerExperimental.
10
+ IContainerExperimental is an interface that is easily casted to, which enables partners to access experimental features for testing and evaluation.
11
+ Moving the experimental method off IContainer will reduce exposure and churn on that production interface as we iterate on and finalize our experimental features.
12
+ Experimental features should not be used in production environments.
13
+
14
+ ## 2.0.0-internal.5.2.0
15
+
16
+ ### Minor Changes
17
+
18
+ - IContainerContext members deprecated ([#16180](https://github.com/microsoft/FluidFramework/issues/16180)) [bf6a26cfe6](https://github.com/microsoft/FluidFramework/commits/bf6a26cfe6ac58386f2c9af260603a15b03ba84f)
19
+
20
+ IContainerContext members disposed, dispose(), serviceConfiguration, and id have been deprecated and will be removed in an upcoming release.
21
+
22
+ disposed - The disposed state on the IContainerContext is not meaningful to the runtime.
23
+
24
+ dispose() - The runtime is not permitted to dispose the IContainerContext, this results in an inconsistent system state.
25
+
26
+ serviceConfiguration - This property is redundant, and is unused by the runtime. The same information can be found via `deltaManager.serviceConfiguration` on this object if it is necessary.
27
+
28
+ id - The docId is already logged by the IContainerContext.taggedLogger for telemetry purposes, so this is generally unnecessary for telemetry. If the id is needed for other purposes it should be passed to the consumer explicitly.
29
+
30
+ ## 2.0.0-internal.5.1.0
31
+
32
+ Dependency updates only.
33
+
34
+ ## 2.0.0-internal.5.0.0
35
+
36
+ ### Major Changes
37
+
38
+ - IContainer.dispose is now required [96484ac6c2](https://github.com/microsoft/FluidFramework/commits/96484ac6c24fed60f79d717616cb9072ab476488)
39
+
40
+ `IContainer.dispose` is now a required method. This method should dispose any resources and switch the container to a
41
+ permanently disconnected state.
42
+
43
+ See the
44
+ [Closure](https://github.com/microsoft/FluidFramework/blob/main/packages/loader/container-loader/README.md#closure)
45
+ section of Loader README.md for more details.
46
+
47
+ - Calling `IContainer.close(...)` will no longer dispose the container runtime, document service, or document storage service. [8b242fdc79](https://github.com/microsoft/FluidFramework/commits/8b242fdc796714cf1da9ad3f90d02efb122af0c2)
48
+
49
+ If the container is not expected to be used after the `close(...)` call, replace it instead with a
50
+ `IContainer.dispose(...)` call (this should be the most common case). Using `IContainer.dispose(...)` will no longer
51
+ switch the container to "readonly" mode and relevant code should instead listen to the Container's "disposed" event.
52
+
53
+ If you intend to pass your own critical error to the container, use `IContainer.close(...)`. Once you are done using the
54
+ container, call `IContainer.dispose(...)`.
55
+
56
+ See the [Closure](packages/loader/container-loader/README.md#Closure) section of Loader README.md for more details.
57
+
58
+ ## 2.0.0-internal.4.4.0
59
+
60
+ Dependency updates only.
61
+
3
62
  ## 2.0.0-internal.4.1.0
4
63
 
5
64
  ### Minor Changes
package/README.md CHANGED
@@ -66,6 +66,7 @@ Please see specific sections for more details on these states and events - this
66
66
  2. ["closed"](#Closure) event: If raised with error, host is responsible for conveying error in some form to the user. Container is left in disconnected & readonly state when it is closed (because of error or not).
67
67
  3. ["readonly"](#Readonly-states) event: Host should have some indication to user that container is not editable. User permissions can change over lifetime of Container, but they can't change per connection session (in other words, change in permissions causes disconnect and reconnect). Hosts are advised to recheck this property on every reconnect.
68
68
  4. [Dirty events](#Dirty-events): Host should have some reasonable UX / workflows to ensure user does not lose edits unexpectedly. I.e. there is enough signals (potentially including blocking user from closing container) ensuring that all user edits make it to storage, unless user explicitly choses to lose such edits.
69
+ 5. [Closing or disposing containers](#containerclose): For most cases, you should use the `IContainer.dispose(...)` API to free up resources. If you intend on using the container after closure, or need to pass some critical error to the container, use the `IContainer.close(...)` API.
69
70
 
70
71
  ## Expectations from container runtime and data store implementers
71
72
 
@@ -89,7 +90,7 @@ Usually container is returned when state of container (and data stores) is rehyd
89
90
 
90
91
  ### Closure
91
92
 
92
- Container can be closed directly by host by calling `Container.close()` and/or `Container.dispose()`. If the container is expected to be used upon closure, use the `close()` API. Otherwise, use the `dispose()` API. The differences between these methods are detailed in the sections below.
93
+ Container can be closed directly by host by calling `Container.close()` and/or `Container.dispose()`. If the container is expected to be used upon closure, or you need to pass your own critical error to the container, use the `close()` API. Otherwise, use the `dispose()` API. The differences between these methods are detailed in the sections below.
93
94
 
94
95
  #### `Container.close()`
95
96
 
@@ -97,7 +98,9 @@ Once closed, container terminates connection to ordering service, and any local
97
98
 
98
99
  The "closed" state effectively means the container is disconnected forever and cannot be reconnected.
99
100
 
100
- Container can also be closed by runtime itself as result of some critical error. Critical errors can be internal (like violation in op ordering invariants), or external (file was deleted). Please see [Error Handling](#Error-handling) for more details
101
+ If after some time a closed container is no longer needed, calling `Container.dispose()` will dispose the runtime resources.
102
+
103
+ Container can also be closed and/or disposed by runtime itself as result of some critical error. Critical errors can be internal (like violation in op ordering invariants), or external (file was deleted). Please see [Error Handling](#Error-handling) for more details.
101
104
 
102
105
  When container is closed, the following is true (in no particular order):
103
106
 
@@ -106,7 +109,7 @@ When container is closed, the following is true (in no particular order):
106
109
  3. "readonly" event fires on DeltaManager & Container (and Container.readonly property is set to true) indicating to all data stores that container is read-only, and data stores should not allow local edits, as they are not going to make it.
107
110
  4. "disconnected" event fires, if connection was active at the moment of container closure.
108
111
 
109
- `"closed"` event is available on Container for hosts. `"disposed"` event is delivered to container runtime when container is closed. But container runtime can be also disposed when new code proposal is made and new version of the code (and container runtime) is loaded in accordance with it.
112
+ `"closed"` event is available on Container for hosts.
110
113
 
111
114
  #### `Container.dispose()`
112
115
 
@@ -196,6 +199,27 @@ Please note that hosts can implement various strategies on how to handle disconn
196
199
 
197
200
  It's worth pointing out that being connected does not mean all user edits are preserved on container closure. There is latency in the system, and loader layer does not provide any guarantees here. Not every implementation needs a solution here (games likely do not care), and thus solving this problem is pushed to framework level (i.e. having a data store that can expose `'dirtyDocument'` signal from ContainerRuntime and request route that can return such data store).
198
201
 
202
+ ## Connection State Transitions Flow Chart
203
+
204
+ ```mermaid
205
+ flowchart TD;
206
+ A(Disconnected)-->B{Reconnect on error if \n AutoReconnect Enabled?};
207
+ B--Yes-->C(Establishing Connection);
208
+ B--No-->D[Connection during Container \n connect call];
209
+ D-->C
210
+ C-->E{Connection Success \n including any Retry?};
211
+ E--No-->F[Error or container.close or container.disconnect];
212
+ A-->F;
213
+ F-->A;
214
+ E--Yes-->G(Catching Up);
215
+ G-->F;
216
+ G-->H{Which Connection Mode?};
217
+ H--Read-->I(Connected);
218
+ H--Write-->J[Wait for Join Op];
219
+ J-->I;
220
+ I-->F;
221
+ ```
222
+
199
223
  ## Readonly states
200
224
 
201
225
  User permissions can change over lifetime of Container. They can't change during single connection session (in other words, change in permissions causes disconnect and reconnect). Hosts are advised to recheck this property on every reconnect.
@@ -2,7 +2,7 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
- import { IDisposable } from "@fluidframework/common-definitions";
5
+ import { IDisposable } from "@fluidframework/core-interfaces";
6
6
  import { IDeltaManager } from "@fluidframework/container-definitions";
7
7
  /** @see CatchUpMonitor for usage */
8
8
  declare type CaughtUpListener = () => void;
@@ -1 +1 @@
1
- {"version":3,"file":"catchUpMonitor.d.ts","sourceRoot":"","sources":["../src/catchUpMonitor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAC;AAEjE,OAAO,EAAE,aAAa,EAAE,MAAM,uCAAuC,CAAC;AAGtE,oCAAoC;AACpC,aAAK,gBAAgB,GAAG,MAAM,IAAI,CAAC;AAEnC,mGAAmG;AACnG,oBAAY,eAAe,GAAG,WAAW,CAAC;AAE1C;;;GAGG;AACH,qBAAa,cAAe,YAAW,eAAe;IAepD,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAf1B,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAkB;IAElC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAKxB;IAEF;;OAEG;gBAEe,YAAY,EAAE,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,EACrC,QAAQ,EAAE,gBAAgB;IAerC,QAAQ,EAAE,OAAO,CAAS;IAC1B,OAAO;CAQd"}
1
+ {"version":3,"file":"catchUpMonitor.d.ts","sourceRoot":"","sources":["../src/catchUpMonitor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAE9D,OAAO,EAAE,aAAa,EAAE,MAAM,uCAAuC,CAAC;AAGtE,oCAAoC;AACpC,aAAK,gBAAgB,GAAG,MAAM,IAAI,CAAC;AAEnC,mGAAmG;AACnG,oBAAY,eAAe,GAAG,WAAW,CAAC;AAE1C;;;GAGG;AACH,qBAAa,cAAe,YAAW,eAAe;IAepD,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAf1B,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAkB;IAElC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAKxB;IAEF;;OAEG;gBAEe,YAAY,EAAE,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,EACrC,QAAQ,EAAE,gBAAgB;IAerC,QAAQ,EAAE,OAAO,CAAS;IAC1B,OAAO;CAQd"}
@@ -1 +1 @@
1
- {"version":3,"file":"catchUpMonitor.js","sourceRoot":"","sources":["../src/catchUpMonitor.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAGH,+DAAsD;AAUtD;;;GAGG;AACH,MAAa,cAAc;IAW1B;;OAEG;IACH,YACkB,YAAqC,EACrC,QAA0B;QAD1B,iBAAY,GAAZ,YAAY,CAAyB;QACrC,aAAQ,GAAR,QAAQ,CAAkB;QAdpC,aAAQ,GAAY,KAAK,CAAC;QAEjB,cAAS,GAAG,CAAC,OAA0D,EAAE,EAAE;YAC3F,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,OAAO,CAAC,cAAc,IAAI,IAAI,CAAC,eAAe,EAAE;gBACrE,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;gBACrB,IAAI,CAAC,QAAQ,EAAE,CAAC;aAChB;QACF,CAAC,CAAC;QAsBK,aAAQ,GAAY,KAAK,CAAC;QAbhC,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,YAAY,CAAC,kBAAkB,CAAC;QAE5D,IAAA,qBAAM,EACL,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC,YAAY,CAAC,kBAAkB,EAC5D,KAAK,CAAC,oEAAoE,CAC1E,CAAC;QAEF,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QAE3C,wEAAwE;QACxE,IAAI,CAAC,SAAS,CAAC,EAAE,cAAc,EAAE,IAAI,CAAC,YAAY,CAAC,kBAAkB,EAAE,CAAC,CAAC;IAC1E,CAAC;IAGM,OAAO;QACb,IAAI,IAAI,CAAC,QAAQ,EAAE;YAClB,OAAO;SACP;QACD,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QAErB,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;IAC7C,CAAC;CACD;AAxCD,wCAwCC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IDisposable } from \"@fluidframework/common-definitions\";\nimport { assert } from \"@fluidframework/common-utils\";\nimport { IDeltaManager } from \"@fluidframework/container-definitions\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/protocol-definitions\";\n\n/** @see CatchUpMonitor for usage */\ntype CaughtUpListener = () => void;\n\n/** Monitor that emits an event when a Container has caught up to a given point in the op stream */\nexport type ICatchUpMonitor = IDisposable;\n\n/**\n * Monitors a Container's DeltaManager, notifying listeners when all ops have been processed\n * that were known at the time the monitor was created.\n */\nexport class CatchUpMonitor implements ICatchUpMonitor {\n\tprivate readonly targetSeqNumber: number;\n\tprivate caughtUp: boolean = false;\n\n\tprivate readonly opHandler = (message: Pick<ISequencedDocumentMessage, \"sequenceNumber\">) => {\n\t\tif (!this.caughtUp && message.sequenceNumber >= this.targetSeqNumber) {\n\t\t\tthis.caughtUp = true;\n\t\t\tthis.listener();\n\t\t}\n\t};\n\n\t/**\n\t * Create the CatchUpMonitor, setting the target sequence number to wait for based on DeltaManager's current state.\n\t */\n\tconstructor(\n\t\tprivate readonly deltaManager: IDeltaManager<any, any>,\n\t\tprivate readonly listener: CaughtUpListener,\n\t) {\n\t\tthis.targetSeqNumber = this.deltaManager.lastKnownSeqNumber;\n\n\t\tassert(\n\t\t\tthis.targetSeqNumber >= this.deltaManager.lastSequenceNumber,\n\t\t\t0x37c /* Cannot wait for seqNumber below last processed sequence number */,\n\t\t);\n\n\t\tthis.deltaManager.on(\"op\", this.opHandler);\n\n\t\t// Simulate the last processed op to set caughtUp in case we already are\n\t\tthis.opHandler({ sequenceNumber: this.deltaManager.lastSequenceNumber });\n\t}\n\n\tpublic disposed: boolean = false;\n\tpublic dispose() {\n\t\tif (this.disposed) {\n\t\t\treturn;\n\t\t}\n\t\tthis.disposed = true;\n\n\t\tthis.deltaManager.off(\"op\", this.opHandler);\n\t}\n}\n"]}
1
+ {"version":3,"file":"catchUpMonitor.js","sourceRoot":"","sources":["../src/catchUpMonitor.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAGH,+DAAsD;AAUtD;;;GAGG;AACH,MAAa,cAAc;IAW1B;;OAEG;IACH,YACkB,YAAqC,EACrC,QAA0B;QAD1B,iBAAY,GAAZ,YAAY,CAAyB;QACrC,aAAQ,GAAR,QAAQ,CAAkB;QAdpC,aAAQ,GAAY,KAAK,CAAC;QAEjB,cAAS,GAAG,CAAC,OAA0D,EAAE,EAAE;YAC3F,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,OAAO,CAAC,cAAc,IAAI,IAAI,CAAC,eAAe,EAAE;gBACrE,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;gBACrB,IAAI,CAAC,QAAQ,EAAE,CAAC;aAChB;QACF,CAAC,CAAC;QAsBK,aAAQ,GAAY,KAAK,CAAC;QAbhC,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,YAAY,CAAC,kBAAkB,CAAC;QAE5D,IAAA,qBAAM,EACL,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC,YAAY,CAAC,kBAAkB,EAC5D,KAAK,CAAC,oEAAoE,CAC1E,CAAC;QAEF,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QAE3C,wEAAwE;QACxE,IAAI,CAAC,SAAS,CAAC,EAAE,cAAc,EAAE,IAAI,CAAC,YAAY,CAAC,kBAAkB,EAAE,CAAC,CAAC;IAC1E,CAAC;IAGM,OAAO;QACb,IAAI,IAAI,CAAC,QAAQ,EAAE;YAClB,OAAO;SACP;QACD,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QAErB,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;IAC7C,CAAC;CACD;AAxCD,wCAwCC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IDisposable } from \"@fluidframework/core-interfaces\";\nimport { assert } from \"@fluidframework/common-utils\";\nimport { IDeltaManager } from \"@fluidframework/container-definitions\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/protocol-definitions\";\n\n/** @see CatchUpMonitor for usage */\ntype CaughtUpListener = () => void;\n\n/** Monitor that emits an event when a Container has caught up to a given point in the op stream */\nexport type ICatchUpMonitor = IDisposable;\n\n/**\n * Monitors a Container's DeltaManager, notifying listeners when all ops have been processed\n * that were known at the time the monitor was created.\n */\nexport class CatchUpMonitor implements ICatchUpMonitor {\n\tprivate readonly targetSeqNumber: number;\n\tprivate caughtUp: boolean = false;\n\n\tprivate readonly opHandler = (message: Pick<ISequencedDocumentMessage, \"sequenceNumber\">) => {\n\t\tif (!this.caughtUp && message.sequenceNumber >= this.targetSeqNumber) {\n\t\t\tthis.caughtUp = true;\n\t\t\tthis.listener();\n\t\t}\n\t};\n\n\t/**\n\t * Create the CatchUpMonitor, setting the target sequence number to wait for based on DeltaManager's current state.\n\t */\n\tconstructor(\n\t\tprivate readonly deltaManager: IDeltaManager<any, any>,\n\t\tprivate readonly listener: CaughtUpListener,\n\t) {\n\t\tthis.targetSeqNumber = this.deltaManager.lastKnownSeqNumber;\n\n\t\tassert(\n\t\t\tthis.targetSeqNumber >= this.deltaManager.lastSequenceNumber,\n\t\t\t0x37c /* Cannot wait for seqNumber below last processed sequence number */,\n\t\t);\n\n\t\tthis.deltaManager.on(\"op\", this.opHandler);\n\n\t\t// Simulate the last processed op to set caughtUp in case we already are\n\t\tthis.opHandler({ sequenceNumber: this.deltaManager.lastSequenceNumber });\n\t}\n\n\tpublic disposed: boolean = false;\n\tpublic dispose() {\n\t\tif (this.disposed) {\n\t\t\treturn;\n\t\t}\n\t\tthis.disposed = true;\n\n\t\tthis.deltaManager.off(\"op\", this.opHandler);\n\t}\n}\n"]}
@@ -2,10 +2,11 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
- import { ITelemetryLogger, ITelemetryProperties } from "@fluidframework/common-definitions";
5
+ import { ITelemetryProperties } from "@fluidframework/core-interfaces";
6
6
  import { IDeltaQueue, ReadOnlyInfo, ICriticalContainerError } from "@fluidframework/container-definitions";
7
7
  import { IDocumentService } from "@fluidframework/driver-definitions";
8
8
  import { ConnectionMode, IClient, IClientConfiguration, IClientDetails, IDocumentMessage, ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
9
+ import { ITelemetryLoggerExt } from "@fluidframework/telemetry-utils";
9
10
  import { ReconnectMode, IConnectionManager, IConnectionManagerFactoryArgs } from "./contracts";
10
11
  /**
11
12
  * Implementation of IConnectionManager, used by Container class
@@ -84,7 +85,7 @@ export declare class ConnectionManager implements IConnectionManager {
84
85
  private get readonly();
85
86
  get readOnlyInfo(): ReadOnlyInfo;
86
87
  private static detailsFromConnection;
87
- constructor(serviceProvider: () => IDocumentService | undefined, containerDirty: () => boolean, client: IClient, reconnectAllowed: boolean, logger: ITelemetryLogger, props: IConnectionManagerFactoryArgs);
88
+ constructor(serviceProvider: () => IDocumentService | undefined, containerDirty: () => boolean, client: IClient, reconnectAllowed: boolean, logger: ITelemetryLoggerExt, props: IConnectionManagerFactoryArgs);
88
89
  dispose(error?: ICriticalContainerError, switchToReadonly?: boolean): void;
89
90
  /**
90
91
  * Enables or disables automatic reconnecting.
@@ -1 +1 @@
1
- {"version":3,"file":"connectionManager.d.ts","sourceRoot":"","sources":["../src/connectionManager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"connectionManager.d.ts","sourceRoot":"","sources":["../src/connectionManager.ts"],"names":[],"mappings":"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"}
@@ -11,13 +11,13 @@ exports.ConnectionManager = void 0;
11
11
  const abort_controller_1 = __importDefault(require("abort-controller"));
12
12
  const common_utils_1 = require("@fluidframework/common-utils");
13
13
  const container_utils_1 = require("@fluidframework/container-utils");
14
- const driver_definitions_1 = require("@fluidframework/driver-definitions");
15
14
  const driver_utils_1 = require("@fluidframework/driver-utils");
16
15
  const protocol_definitions_1 = require("@fluidframework/protocol-definitions");
17
16
  const telemetry_utils_1 = require("@fluidframework/telemetry-utils");
18
17
  const contracts_1 = require("./contracts");
19
18
  const deltaQueue_1 = require("./deltaQueue");
20
19
  const protocol_1 = require("./protocol");
20
+ const utils_1 = require("./utils");
21
21
  const MaxReconnectDelayInMs = 8000;
22
22
  const InitialReconnectDelayInMs = 1000;
23
23
  const DefaultChunkSize = 16 * 1024;
@@ -41,8 +41,9 @@ const clientNoDeltaStream = {
41
41
  };
42
42
  const clientIdNoDeltaStream = "storage-only client";
43
43
  class NoDeltaStream extends common_utils_1.TypedEventEmitter {
44
- constructor() {
45
- super(...arguments);
44
+ constructor(storageOnlyReason) {
45
+ super();
46
+ this.storageOnlyReason = storageOnlyReason;
46
47
  this.clientId = clientIdNoDeltaStream;
47
48
  this.claims = {
48
49
  scopes: [protocol_definitions_1.ScopeType.DocRead],
@@ -84,6 +85,9 @@ class NoDeltaStream extends common_utils_1.TypedEventEmitter {
84
85
  this._disposed = true;
85
86
  }
86
87
  }
88
+ function isNoDeltaStreamConnection(connection) {
89
+ return connection instanceof NoDeltaStream;
90
+ }
87
91
  const waitForOnline = async () => {
88
92
  var _a;
89
93
  // Only wait if we have a strong signal that we're offline - otherwise assume we're online.
@@ -249,13 +253,19 @@ class ConnectionManager {
249
253
  return this.readOnlyInfo.readonly;
250
254
  }
251
255
  get readOnlyInfo() {
252
- const storageOnly = this.connection !== undefined && this.connection instanceof NoDeltaStream;
256
+ let storageOnly = false;
257
+ let storageOnlyReason;
258
+ if (isNoDeltaStreamConnection(this.connection)) {
259
+ storageOnly = true;
260
+ storageOnlyReason = this.connection.storageOnlyReason;
261
+ }
253
262
  if (storageOnly || this._forceReadonly || this._readonlyPermissions === true) {
254
263
  return {
255
264
  readonly: true,
256
265
  forced: this._forceReadonly,
257
266
  permissions: this._readonlyPermissions,
258
267
  storageOnly,
268
+ storageOnlyReason,
259
269
  };
260
270
  }
261
271
  return { readonly: this._readonlyPermissions };
@@ -279,7 +289,6 @@ class ConnectionManager {
279
289
  return;
280
290
  }
281
291
  this._disposed = true;
282
- this.pendingConnection = undefined;
283
292
  // Ensure that things like triggerConnect() will short circuit
284
293
  this._reconnectMode = contracts_1.ReconnectMode.Never;
285
294
  this._outbound.clear();
@@ -376,7 +385,7 @@ class ConnectionManager {
376
385
  let pendingConnectionMode;
377
386
  if (this.pendingConnection !== undefined) {
378
387
  pendingConnectionMode = this.pendingConnection.connectionMode;
379
- this.cancelConnection(); // Throw out in-progress connection attempt in favor of new attempt
388
+ this.cancelConnection(reason); // Throw out in-progress connection attempt in favor of new attempt
380
389
  (0, common_utils_1.assert)(this.pendingConnection === undefined, 0x344 /* this.pendingConnection should be undefined */);
381
390
  }
382
391
  // If there is no specified ConnectionMode, try the previous mode, if there is no previous mode use default
@@ -410,6 +419,7 @@ class ConnectionManager {
410
419
  },
411
420
  connectionMode: requestedMode,
412
421
  };
422
+ this.props.establishConnectionHandler(reason);
413
423
  // This loop will keep trying to connect until successful, with a delay between each iteration.
414
424
  while (connection === undefined) {
415
425
  if (this._disposed) {
@@ -435,10 +445,8 @@ class ConnectionManager {
435
445
  }
436
446
  }
437
447
  catch (origError) {
438
- if (typeof origError === "object" &&
439
- origError !== null &&
440
- (origError === null || origError === void 0 ? void 0 : origError.errorType) === driver_definitions_1.DriverErrorType.deltaStreamConnectionForbidden) {
441
- connection = new NoDeltaStream();
448
+ if ((0, utils_1.isDeltaStreamConnectionForbiddenError)(origError)) {
449
+ connection = new NoDeltaStream(origError.storageOnlyReason);
442
450
  requestedMode = "read";
443
451
  break;
444
452
  }
@@ -456,6 +464,7 @@ class ConnectionManager {
456
464
  duration: telemetry_utils_1.TelemetryLogger.formatTick(common_utils_1.performance.now() - connectStartTime),
457
465
  }, origError);
458
466
  lastError = origError;
467
+ const waitStartTime = common_utils_1.performance.now();
459
468
  const retryDelayFromError = (0, driver_utils_1.getRetryDelayFromError)(origError);
460
469
  if (retryDelayFromError !== undefined) {
461
470
  // If the error told us to wait, then we wait.
@@ -476,6 +485,14 @@ class ConnectionManager {
476
485
  // NOTE: This isn't strictly true for drivers that don't require network (e.g. local driver). Really this logic
477
486
  // should probably live in the driver.
478
487
  await waitForOnline();
488
+ this.logger.sendPerformanceEvent({
489
+ eventName: "WaitBetweenConnectionAttempts",
490
+ duration: common_utils_1.performance.now() - waitStartTime,
491
+ details: JSON.stringify({
492
+ retryDelayFromError,
493
+ delayMs,
494
+ }),
495
+ });
479
496
  }
480
497
  }
481
498
  // If we retried more than once, log an event about how long it took (this will not log to error table)
@@ -526,7 +543,7 @@ class ConnectionManager {
526
543
  this.pendingReconnect = false;
527
544
  if (this.connection === undefined) {
528
545
  if (this.pendingConnection !== undefined) {
529
- this.cancelConnection();
546
+ this.cancelConnection(reason);
530
547
  return true;
531
548
  }
532
549
  return false;
@@ -553,11 +570,12 @@ class ConnectionManager {
553
570
  /**
554
571
  * Cancel in-progress connection attempt.
555
572
  */
556
- cancelConnection() {
573
+ cancelConnection(reason) {
557
574
  (0, common_utils_1.assert)(this.pendingConnection !== undefined, 0x345 /* this.pendingConnection is undefined when trying to cancel */);
558
575
  this.pendingConnection.abort();
559
576
  this.pendingConnection = undefined;
560
577
  this.logger.sendTelemetryEvent({ eventName: "ConnectionCancelReceived" });
578
+ this.props.cancelConnectionHandler(`Cancel Pending Connection due to ${reason}`);
561
579
  }
562
580
  /**
563
581
  * Once we've successfully gotten a connection, we need to set up state, attach event listeners, and process
@@ -721,7 +739,7 @@ class ConnectionManager {
721
739
  // should probably live in the driver.
722
740
  await waitForOnline();
723
741
  this.triggerConnect(error !== undefined
724
- ? "Reconnect on Error"
742
+ ? "Reconnecting due to Error"
725
743
  : `Reconnecting due to: ${disconnectMessage}`, requestedMode);
726
744
  }
727
745
  prepareMessageToSend(message) {
@@ -733,6 +751,7 @@ class ConnectionManager {
733
751
  forcedReadonly: this.readOnlyInfo.forced,
734
752
  readonlyPermissions: this.readOnlyInfo.permissions,
735
753
  storageOnly: this.readOnlyInfo.storageOnly,
754
+ storageOnlyReason: this.readOnlyInfo.storageOnlyReason,
736
755
  });
737
756
  this.props.closeHandler(error);
738
757
  return undefined;