@fluidframework/container-runtime 2.0.0-dev-rc.3.0.0.254866 → 2.0.0-dev-rc.5.0.0.263932

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 (338) hide show
  1. package/CHANGELOG.md +69 -0
  2. package/api-report/container-runtime.api.md +93 -39
  3. package/dist/batchTracker.d.ts +1 -1
  4. package/dist/batchTracker.d.ts.map +1 -1
  5. package/dist/batchTracker.js.map +1 -1
  6. package/dist/blobManager.d.ts +7 -7
  7. package/dist/blobManager.d.ts.map +1 -1
  8. package/dist/blobManager.js +2 -4
  9. package/dist/blobManager.js.map +1 -1
  10. package/dist/channelCollection.d.ts +10 -6
  11. package/dist/channelCollection.d.ts.map +1 -1
  12. package/dist/channelCollection.js +85 -22
  13. package/dist/channelCollection.js.map +1 -1
  14. package/dist/connectionTelemetry.d.ts +2 -2
  15. package/dist/connectionTelemetry.d.ts.map +1 -1
  16. package/dist/connectionTelemetry.js +54 -5
  17. package/dist/connectionTelemetry.js.map +1 -1
  18. package/dist/containerRuntime.d.ts +22 -35
  19. package/dist/containerRuntime.d.ts.map +1 -1
  20. package/dist/containerRuntime.js +232 -174
  21. package/dist/containerRuntime.js.map +1 -1
  22. package/dist/dataStore.d.ts +1 -1
  23. package/dist/dataStore.d.ts.map +1 -1
  24. package/dist/dataStore.js.map +1 -1
  25. package/dist/dataStoreContext.d.ts +9 -6
  26. package/dist/dataStoreContext.d.ts.map +1 -1
  27. package/dist/dataStoreContext.js +19 -5
  28. package/dist/dataStoreContext.js.map +1 -1
  29. package/dist/dataStoreContexts.d.ts +2 -0
  30. package/dist/dataStoreContexts.d.ts.map +1 -1
  31. package/dist/dataStoreContexts.js +7 -0
  32. package/dist/dataStoreContexts.js.map +1 -1
  33. package/dist/deltaManagerProxies.d.ts +81 -0
  34. package/dist/deltaManagerProxies.d.ts.map +1 -0
  35. package/dist/{deltaManagerSummarizerProxy.js → deltaManagerProxies.js} +75 -20
  36. package/dist/deltaManagerProxies.js.map +1 -0
  37. package/dist/deltaScheduler.d.ts +2 -2
  38. package/dist/deltaScheduler.d.ts.map +1 -1
  39. package/dist/deltaScheduler.js.map +1 -1
  40. package/dist/gc/garbageCollection.d.ts +5 -12
  41. package/dist/gc/garbageCollection.d.ts.map +1 -1
  42. package/dist/gc/garbageCollection.js +45 -29
  43. package/dist/gc/garbageCollection.js.map +1 -1
  44. package/dist/gc/gcDefinitions.d.ts +27 -6
  45. package/dist/gc/gcDefinitions.d.ts.map +1 -1
  46. package/dist/gc/gcDefinitions.js.map +1 -1
  47. package/dist/gc/gcHelpers.d.ts +5 -4
  48. package/dist/gc/gcHelpers.d.ts.map +1 -1
  49. package/dist/gc/gcHelpers.js +14 -2
  50. package/dist/gc/gcHelpers.js.map +1 -1
  51. package/dist/gc/gcTelemetry.d.ts +14 -4
  52. package/dist/gc/gcTelemetry.d.ts.map +1 -1
  53. package/dist/gc/gcTelemetry.js +24 -21
  54. package/dist/gc/gcTelemetry.js.map +1 -1
  55. package/dist/gc/index.d.ts +2 -2
  56. package/dist/gc/index.d.ts.map +1 -1
  57. package/dist/gc/index.js +2 -2
  58. package/dist/gc/index.js.map +1 -1
  59. package/dist/index.d.ts +3 -3
  60. package/dist/index.d.ts.map +1 -1
  61. package/dist/index.js +2 -1
  62. package/dist/index.js.map +1 -1
  63. package/dist/{alpha.d.ts → legacy.d.ts} +8 -1
  64. package/dist/messageTypes.d.ts +5 -2
  65. package/dist/messageTypes.d.ts.map +1 -1
  66. package/dist/messageTypes.js.map +1 -1
  67. package/dist/metadata.d.ts +2 -2
  68. package/dist/metadata.d.ts.map +1 -1
  69. package/dist/metadata.js.map +1 -1
  70. package/dist/opLifecycle/batchManager.d.ts +4 -1
  71. package/dist/opLifecycle/batchManager.d.ts.map +1 -1
  72. package/dist/opLifecycle/batchManager.js +0 -10
  73. package/dist/opLifecycle/batchManager.js.map +1 -1
  74. package/dist/opLifecycle/opDecompressor.d.ts.map +1 -1
  75. package/dist/opLifecycle/opDecompressor.js +6 -6
  76. package/dist/opLifecycle/opDecompressor.js.map +1 -1
  77. package/dist/opLifecycle/opGroupingManager.js +2 -2
  78. package/dist/opLifecycle/opGroupingManager.js.map +1 -1
  79. package/dist/opLifecycle/opSplitter.js +1 -1
  80. package/dist/opLifecycle/opSplitter.js.map +1 -1
  81. package/dist/opLifecycle/outbox.d.ts +0 -4
  82. package/dist/opLifecycle/outbox.d.ts.map +1 -1
  83. package/dist/opLifecycle/outbox.js +7 -38
  84. package/dist/opLifecycle/outbox.js.map +1 -1
  85. package/dist/packageVersion.d.ts +1 -1
  86. package/dist/packageVersion.js +1 -1
  87. package/dist/packageVersion.js.map +1 -1
  88. package/dist/pendingStateManager.d.ts +9 -2
  89. package/dist/pendingStateManager.d.ts.map +1 -1
  90. package/dist/pendingStateManager.js +26 -10
  91. package/dist/pendingStateManager.js.map +1 -1
  92. package/dist/public.d.ts +3 -0
  93. package/dist/scheduleManager.d.ts +2 -2
  94. package/dist/scheduleManager.d.ts.map +1 -1
  95. package/dist/scheduleManager.js.map +1 -1
  96. package/dist/summary/documentSchema.d.ts +3 -1
  97. package/dist/summary/documentSchema.d.ts.map +1 -1
  98. package/dist/summary/documentSchema.js +34 -16
  99. package/dist/summary/documentSchema.js.map +1 -1
  100. package/dist/summary/index.d.ts +1 -1
  101. package/dist/summary/index.d.ts.map +1 -1
  102. package/dist/summary/index.js.map +1 -1
  103. package/dist/summary/orderedClientElection.d.ts +2 -2
  104. package/dist/summary/orderedClientElection.d.ts.map +1 -1
  105. package/dist/summary/orderedClientElection.js.map +1 -1
  106. package/dist/summary/runningSummarizer.js +10 -10
  107. package/dist/summary/runningSummarizer.js.map +1 -1
  108. package/dist/summary/summarizer.d.ts +1 -2
  109. package/dist/summary/summarizer.d.ts.map +1 -1
  110. package/dist/summary/summarizer.js.map +1 -1
  111. package/dist/summary/summarizerClientElection.d.ts +1 -1
  112. package/dist/summary/summarizerClientElection.d.ts.map +1 -1
  113. package/dist/summary/summarizerClientElection.js.map +1 -1
  114. package/dist/summary/summarizerHeuristics.d.ts +1 -1
  115. package/dist/summary/summarizerHeuristics.d.ts.map +1 -1
  116. package/dist/summary/summarizerHeuristics.js.map +1 -1
  117. package/dist/summary/summarizerNode/summarizerNode.d.ts +4 -3
  118. package/dist/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
  119. package/dist/summary/summarizerNode/summarizerNode.js +4 -10
  120. package/dist/summary/summarizerNode/summarizerNode.js.map +1 -1
  121. package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts +2 -3
  122. package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
  123. package/dist/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
  124. package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts +1 -2
  125. package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
  126. package/dist/summary/summarizerNode/summarizerNodeWithGc.js +2 -9
  127. package/dist/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
  128. package/dist/summary/summarizerTypes.d.ts +3 -5
  129. package/dist/summary/summarizerTypes.d.ts.map +1 -1
  130. package/dist/summary/summarizerTypes.js.map +1 -1
  131. package/dist/summary/summaryCollection.d.ts +2 -2
  132. package/dist/summary/summaryCollection.d.ts.map +1 -1
  133. package/dist/summary/summaryCollection.js.map +1 -1
  134. package/dist/summary/summaryFormat.d.ts +25 -5
  135. package/dist/summary/summaryFormat.d.ts.map +1 -1
  136. package/dist/summary/summaryFormat.js.map +1 -1
  137. package/dist/summary/summaryGenerator.d.ts +1 -2
  138. package/dist/summary/summaryGenerator.d.ts.map +1 -1
  139. package/dist/summary/summaryGenerator.js +12 -11
  140. package/dist/summary/summaryGenerator.js.map +1 -1
  141. package/dist/summary/summaryManager.d.ts.map +1 -1
  142. package/dist/summary/summaryManager.js +5 -5
  143. package/dist/summary/summaryManager.js.map +1 -1
  144. package/{lib/beta.d.ts → internal.d.ts} +2 -0
  145. package/{dist/beta.d.ts → legacy.d.ts} +2 -0
  146. package/lib/batchTracker.d.ts +1 -1
  147. package/lib/batchTracker.d.ts.map +1 -1
  148. package/lib/batchTracker.js.map +1 -1
  149. package/lib/blobManager.d.ts +7 -7
  150. package/lib/blobManager.d.ts.map +1 -1
  151. package/lib/blobManager.js +3 -5
  152. package/lib/blobManager.js.map +1 -1
  153. package/lib/channelCollection.d.ts +10 -6
  154. package/lib/channelCollection.d.ts.map +1 -1
  155. package/lib/channelCollection.js +88 -25
  156. package/lib/channelCollection.js.map +1 -1
  157. package/lib/connectionTelemetry.d.ts +2 -2
  158. package/lib/connectionTelemetry.d.ts.map +1 -1
  159. package/lib/connectionTelemetry.js +49 -0
  160. package/lib/connectionTelemetry.js.map +1 -1
  161. package/lib/containerRuntime.d.ts +22 -35
  162. package/lib/containerRuntime.d.ts.map +1 -1
  163. package/lib/containerRuntime.js +232 -174
  164. package/lib/containerRuntime.js.map +1 -1
  165. package/lib/dataStore.d.ts +1 -1
  166. package/lib/dataStore.d.ts.map +1 -1
  167. package/lib/dataStore.js +1 -1
  168. package/lib/dataStore.js.map +1 -1
  169. package/lib/dataStoreContext.d.ts +9 -6
  170. package/lib/dataStoreContext.d.ts.map +1 -1
  171. package/lib/dataStoreContext.js +21 -7
  172. package/lib/dataStoreContext.js.map +1 -1
  173. package/lib/dataStoreContexts.d.ts +2 -0
  174. package/lib/dataStoreContexts.d.ts.map +1 -1
  175. package/lib/dataStoreContexts.js +7 -0
  176. package/lib/dataStoreContexts.js.map +1 -1
  177. package/lib/deltaManagerProxies.d.ts +81 -0
  178. package/lib/deltaManagerProxies.d.ts.map +1 -0
  179. package/lib/{deltaManagerSummarizerProxy.js → deltaManagerProxies.js} +72 -19
  180. package/lib/deltaManagerProxies.js.map +1 -0
  181. package/lib/deltaScheduler.d.ts +2 -2
  182. package/lib/deltaScheduler.d.ts.map +1 -1
  183. package/lib/deltaScheduler.js.map +1 -1
  184. package/lib/gc/garbageCollection.d.ts +5 -12
  185. package/lib/gc/garbageCollection.d.ts.map +1 -1
  186. package/lib/gc/garbageCollection.js +47 -31
  187. package/lib/gc/garbageCollection.js.map +1 -1
  188. package/lib/gc/gcDefinitions.d.ts +27 -6
  189. package/lib/gc/gcDefinitions.d.ts.map +1 -1
  190. package/lib/gc/gcDefinitions.js.map +1 -1
  191. package/lib/gc/gcHelpers.d.ts +5 -4
  192. package/lib/gc/gcHelpers.d.ts.map +1 -1
  193. package/lib/gc/gcHelpers.js +12 -1
  194. package/lib/gc/gcHelpers.js.map +1 -1
  195. package/lib/gc/gcTelemetry.d.ts +14 -4
  196. package/lib/gc/gcTelemetry.d.ts.map +1 -1
  197. package/lib/gc/gcTelemetry.js +24 -21
  198. package/lib/gc/gcTelemetry.js.map +1 -1
  199. package/lib/gc/index.d.ts +2 -2
  200. package/lib/gc/index.d.ts.map +1 -1
  201. package/lib/gc/index.js +1 -1
  202. package/lib/gc/index.js.map +1 -1
  203. package/lib/index.d.ts +3 -3
  204. package/lib/index.d.ts.map +1 -1
  205. package/lib/index.js +1 -1
  206. package/lib/index.js.map +1 -1
  207. package/lib/{alpha.d.ts → legacy.d.ts} +8 -1
  208. package/lib/messageTypes.d.ts +5 -2
  209. package/lib/messageTypes.d.ts.map +1 -1
  210. package/lib/messageTypes.js.map +1 -1
  211. package/lib/metadata.d.ts +2 -2
  212. package/lib/metadata.d.ts.map +1 -1
  213. package/lib/metadata.js.map +1 -1
  214. package/lib/opLifecycle/batchManager.d.ts +4 -1
  215. package/lib/opLifecycle/batchManager.d.ts.map +1 -1
  216. package/lib/opLifecycle/batchManager.js +0 -10
  217. package/lib/opLifecycle/batchManager.js.map +1 -1
  218. package/lib/opLifecycle/opDecompressor.d.ts.map +1 -1
  219. package/lib/opLifecycle/opDecompressor.js +6 -6
  220. package/lib/opLifecycle/opDecompressor.js.map +1 -1
  221. package/lib/opLifecycle/opGroupingManager.js +2 -2
  222. package/lib/opLifecycle/opGroupingManager.js.map +1 -1
  223. package/lib/opLifecycle/opSplitter.js +1 -1
  224. package/lib/opLifecycle/opSplitter.js.map +1 -1
  225. package/lib/opLifecycle/outbox.d.ts +0 -4
  226. package/lib/opLifecycle/outbox.d.ts.map +1 -1
  227. package/lib/opLifecycle/outbox.js +7 -38
  228. package/lib/opLifecycle/outbox.js.map +1 -1
  229. package/lib/packageVersion.d.ts +1 -1
  230. package/lib/packageVersion.js +1 -1
  231. package/lib/packageVersion.js.map +1 -1
  232. package/lib/pendingStateManager.d.ts +9 -2
  233. package/lib/pendingStateManager.d.ts.map +1 -1
  234. package/lib/pendingStateManager.js +27 -11
  235. package/lib/pendingStateManager.js.map +1 -1
  236. package/lib/public.d.ts +3 -0
  237. package/lib/scheduleManager.d.ts +2 -2
  238. package/lib/scheduleManager.d.ts.map +1 -1
  239. package/lib/scheduleManager.js.map +1 -1
  240. package/lib/summary/documentSchema.d.ts +3 -1
  241. package/lib/summary/documentSchema.d.ts.map +1 -1
  242. package/lib/summary/documentSchema.js +34 -16
  243. package/lib/summary/documentSchema.js.map +1 -1
  244. package/lib/summary/index.d.ts +1 -1
  245. package/lib/summary/index.d.ts.map +1 -1
  246. package/lib/summary/index.js.map +1 -1
  247. package/lib/summary/orderedClientElection.d.ts +2 -2
  248. package/lib/summary/orderedClientElection.d.ts.map +1 -1
  249. package/lib/summary/orderedClientElection.js +1 -1
  250. package/lib/summary/orderedClientElection.js.map +1 -1
  251. package/lib/summary/runningSummarizer.js +1 -1
  252. package/lib/summary/runningSummarizer.js.map +1 -1
  253. package/lib/summary/summarizer.d.ts +1 -2
  254. package/lib/summary/summarizer.d.ts.map +1 -1
  255. package/lib/summary/summarizer.js.map +1 -1
  256. package/lib/summary/summarizerClientElection.d.ts +1 -1
  257. package/lib/summary/summarizerClientElection.d.ts.map +1 -1
  258. package/lib/summary/summarizerClientElection.js.map +1 -1
  259. package/lib/summary/summarizerHeuristics.d.ts +1 -1
  260. package/lib/summary/summarizerHeuristics.d.ts.map +1 -1
  261. package/lib/summary/summarizerHeuristics.js.map +1 -1
  262. package/lib/summary/summarizerNode/summarizerNode.d.ts +4 -3
  263. package/lib/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
  264. package/lib/summary/summarizerNode/summarizerNode.js +4 -10
  265. package/lib/summary/summarizerNode/summarizerNode.js.map +1 -1
  266. package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts +2 -3
  267. package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
  268. package/lib/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
  269. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts +1 -2
  270. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
  271. package/lib/summary/summarizerNode/summarizerNodeWithGc.js +2 -9
  272. package/lib/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
  273. package/lib/summary/summarizerTypes.d.ts +3 -5
  274. package/lib/summary/summarizerTypes.d.ts.map +1 -1
  275. package/lib/summary/summarizerTypes.js.map +1 -1
  276. package/lib/summary/summaryCollection.d.ts +2 -2
  277. package/lib/summary/summaryCollection.d.ts.map +1 -1
  278. package/lib/summary/summaryCollection.js.map +1 -1
  279. package/lib/summary/summaryFormat.d.ts +25 -5
  280. package/lib/summary/summaryFormat.d.ts.map +1 -1
  281. package/lib/summary/summaryFormat.js.map +1 -1
  282. package/lib/summary/summaryGenerator.d.ts +1 -2
  283. package/lib/summary/summaryGenerator.d.ts.map +1 -1
  284. package/lib/summary/summaryGenerator.js +5 -4
  285. package/lib/summary/summaryGenerator.js.map +1 -1
  286. package/lib/summary/summaryManager.d.ts.map +1 -1
  287. package/lib/summary/summaryManager.js +2 -2
  288. package/lib/summary/summaryManager.js.map +1 -1
  289. package/lib/tsdoc-metadata.json +1 -1
  290. package/package.json +37 -59
  291. package/src/batchTracker.ts +1 -2
  292. package/src/blobManager.ts +11 -10
  293. package/src/channelCollection.ts +115 -47
  294. package/src/connectionTelemetry.ts +59 -4
  295. package/src/containerRuntime.ts +302 -270
  296. package/src/dataStore.ts +7 -4
  297. package/src/dataStoreContext.ts +57 -16
  298. package/src/dataStoreContexts.ts +13 -2
  299. package/src/{deltaManagerSummarizerProxy.ts → deltaManagerProxies.ts} +98 -24
  300. package/src/deltaScheduler.ts +2 -3
  301. package/src/gc/garbageCollection.ts +64 -42
  302. package/src/gc/gcDefinitions.ts +22 -10
  303. package/src/gc/gcHelpers.ts +14 -1
  304. package/src/gc/gcTelemetry.ts +57 -50
  305. package/src/gc/index.ts +2 -1
  306. package/src/index.ts +7 -0
  307. package/src/messageTypes.ts +4 -2
  308. package/src/metadata.ts +2 -2
  309. package/src/opLifecycle/README.md +4 -4
  310. package/src/opLifecycle/batchManager.ts +5 -14
  311. package/src/opLifecycle/opDecompressor.ts +12 -6
  312. package/src/opLifecycle/opGroupingManager.ts +2 -2
  313. package/src/opLifecycle/opSplitter.ts +1 -1
  314. package/src/opLifecycle/outbox.ts +7 -53
  315. package/src/packageVersion.ts +1 -1
  316. package/src/pendingStateManager.ts +38 -15
  317. package/src/scheduleManager.ts +2 -2
  318. package/src/summary/documentSchema.ts +52 -18
  319. package/src/summary/index.ts +4 -0
  320. package/src/summary/orderedClientElection.ts +6 -3
  321. package/src/summary/runningSummarizer.ts +1 -1
  322. package/src/summary/summarizer.ts +1 -1
  323. package/src/summary/summarizerClientElection.ts +1 -1
  324. package/src/summary/summarizerHeuristics.ts +1 -1
  325. package/src/summary/summarizerNode/summarizerNode.ts +3 -12
  326. package/src/summary/summarizerNode/summarizerNodeUtils.ts +2 -3
  327. package/src/summary/summarizerNode/summarizerNodeWithGc.ts +1 -10
  328. package/src/summary/summarizerTypes.ts +6 -5
  329. package/src/summary/summaryCollection.ts +2 -2
  330. package/src/summary/summaryFormat.ts +30 -4
  331. package/src/summary/summaryGenerator.ts +20 -9
  332. package/src/summary/summaryManager.ts +6 -3
  333. package/dist/deltaManagerSummarizerProxy.d.ts +0 -44
  334. package/dist/deltaManagerSummarizerProxy.d.ts.map +0 -1
  335. package/dist/deltaManagerSummarizerProxy.js.map +0 -1
  336. package/lib/deltaManagerSummarizerProxy.d.ts +0 -44
  337. package/lib/deltaManagerSummarizerProxy.d.ts.map +0 -1
  338. package/lib/deltaManagerSummarizerProxy.js.map +0 -1
@@ -7,14 +7,19 @@ import { AttachState } from "@fluidframework/container-definitions";
7
7
  import {
8
8
  FluidObject,
9
9
  IDisposable,
10
- IFluidHandle,
11
10
  IRequest,
12
11
  IResponse,
13
12
  ITelemetryBaseLogger,
14
13
  } from "@fluidframework/core-interfaces";
14
+ import type { IFluidHandleInternal } from "@fluidframework/core-interfaces/internal";
15
15
  import { assert, Lazy, LazyPromise } from "@fluidframework/core-utils/internal";
16
16
  import { FluidObjectHandle } from "@fluidframework/datastore/internal";
17
- import { buildSnapshotTree } from "@fluidframework/driver-utils/internal";
17
+ import {
18
+ buildSnapshotTree,
19
+ getSnapshotTree,
20
+ isInstanceOfISnapshot,
21
+ } from "@fluidframework/driver-utils/internal";
22
+ import type { ISnapshot } from "@fluidframework/driver-definitions/internal";
18
23
  import { ISequencedDocumentMessage, ISnapshotTree } from "@fluidframework/protocol-definitions";
19
24
  import {
20
25
  IGarbageCollectionData,
@@ -63,7 +68,11 @@ import {
63
68
  tagCodeArtifacts,
64
69
  } from "@fluidframework/telemetry-utils/internal";
65
70
 
66
- import { RuntimeHeaderData, defaultRuntimeHeaderData } from "./containerRuntime.js";
71
+ import {
72
+ DeletedResponseHeaderKey,
73
+ RuntimeHeaderData,
74
+ defaultRuntimeHeaderData,
75
+ } from "./containerRuntime.js";
67
76
  import {
68
77
  IDataStoreAliasMessage,
69
78
  channelToDataStore,
@@ -83,7 +92,8 @@ import { FluidDataStoreRegistry } from "./dataStoreRegistry.js";
83
92
  import {
84
93
  GCNodeType,
85
94
  detectOutboundRoutesViaDDSKey,
86
- trimLeadingAndTrailingSlashes,
95
+ IGCNodeUpdatedProps,
96
+ urlToGCNodePath,
87
97
  } from "./gc/index.js";
88
98
  import { ContainerMessageType, LocalContainerRuntimeMessage } from "./messageTypes.js";
89
99
  import { StorageServiceWithAttachBlobs } from "./storageServiceWithAttachBlobs.js";
@@ -163,6 +173,7 @@ export function wrapContext(context: IFluidParentContext): IFluidParentContext {
163
173
  getAudience: (...args) => {
164
174
  return context.getAudience(...args);
165
175
  },
176
+ // back-compat, to be removed in 2.0
166
177
  ensureNoDataModelChanges: (...args) => {
167
178
  return context.ensureNoDataModelChanges(...args);
168
179
  },
@@ -249,7 +260,7 @@ export class ChannelCollection implements IFluidDataStoreChannel, IDisposable {
249
260
 
250
261
  private readonly disposeOnce = new Lazy<void>(() => this.contexts.dispose());
251
262
 
252
- public readonly entryPoint: IFluidHandle<FluidObject>;
263
+ public readonly entryPoint: IFluidHandleInternal<FluidObject>;
253
264
 
254
265
  public readonly containerLoadStats: {
255
266
  // number of dataStores during loadContainer
@@ -263,7 +274,7 @@ export class ChannelCollection implements IFluidDataStoreChannel, IDisposable {
263
274
  private dataStoresSinceLastGC: string[] = [];
264
275
  // The handle to the container runtime. This is used mainly for GC purposes to represent outbound reference from
265
276
  // the container runtime to other nodes.
266
- private readonly containerRuntimeHandle: IFluidHandle;
277
+ private readonly containerRuntimeHandle: IFluidHandleInternal;
267
278
  private readonly pendingAliasMap: Map<string, Promise<AliasResult>> = new Map<
268
279
  string,
269
280
  Promise<AliasResult>
@@ -273,17 +284,10 @@ export class ChannelCollection implements IFluidDataStoreChannel, IDisposable {
273
284
  private readonly aliasedDataStores: Set<string>;
274
285
 
275
286
  constructor(
276
- protected readonly baseSnapshot: ISnapshotTree | undefined,
287
+ protected readonly baseSnapshot: ISnapshotTree | ISnapshot | undefined,
277
288
  public readonly parentContext: IFluidParentContext,
278
289
  baseLogger: ITelemetryBaseLogger,
279
- private readonly gcNodeUpdated: (
280
- nodePath: string,
281
- reason: "Loaded" | "Changed",
282
- timestampMs?: number,
283
- packagePath?: readonly string[],
284
- request?: IRequest,
285
- headerData?: RuntimeHeaderData,
286
- ) => void,
290
+ private readonly gcNodeUpdated: (props: IGCNodeUpdatedProps) => void,
287
291
  private readonly isDataStoreDeleted: (nodePath: string) => boolean,
288
292
  private readonly aliasMap: Map<string, string>,
289
293
  provideEntryPoint: (runtime: ChannelCollection) => Promise<FluidObject>,
@@ -305,7 +309,8 @@ export class ChannelCollection implements IFluidDataStoreChannel, IDisposable {
305
309
  // Extract stores stored inside the snapshot
306
310
  const fluidDataStores = new Map<string, ISnapshotTree>();
307
311
  if (baseSnapshot) {
308
- for (const [key, value] of Object.entries(baseSnapshot.trees)) {
312
+ const baseSnapshotTree = getSnapshotTree(baseSnapshot);
313
+ for (const [key, value] of Object.entries(baseSnapshotTree.trees)) {
309
314
  fluidDataStores.set(key, value);
310
315
  }
311
316
  }
@@ -321,9 +326,16 @@ export class ChannelCollection implements IFluidDataStoreChannel, IDisposable {
321
326
  }
322
327
  // If we have a detached container, then create local data store contexts.
323
328
  if (this.parentContext.attachState !== AttachState.Detached) {
329
+ let snapshotForRemoteFluidDatastoreContext: ISnapshot | ISnapshotTree = value;
330
+ if (isInstanceOfISnapshot(baseSnapshot)) {
331
+ snapshotForRemoteFluidDatastoreContext = {
332
+ ...baseSnapshot,
333
+ snapshotTree: value,
334
+ };
335
+ }
324
336
  dataStoreContext = new RemoteFluidDataStoreContext({
325
337
  id: key,
326
- snapshotTree: value,
338
+ snapshot: snapshotForRemoteFluidDatastoreContext,
327
339
  parentContext: this.wrapContextForInnerChannel(key),
328
340
  storage: this.parentContext.storage,
329
341
  scope: this.parentContext.scope,
@@ -444,9 +456,12 @@ export class ChannelCollection implements IFluidDataStoreChannel, IDisposable {
444
456
  }
445
457
 
446
458
  const flatAttachBlobs = new Map<string, ArrayBufferLike>();
447
- let snapshotTree: ISnapshotTree | undefined;
459
+ let snapshot: ISnapshotTree | ISnapshot | undefined;
448
460
  if (attachMessage.snapshot) {
449
- snapshotTree = buildSnapshotTree(attachMessage.snapshot.entries, flatAttachBlobs);
461
+ snapshot = buildSnapshotTree(attachMessage.snapshot.entries, flatAttachBlobs);
462
+ if (isInstanceOfISnapshot(this.baseSnapshot)) {
463
+ snapshot = { ...this.baseSnapshot, snapshotTree: snapshot };
464
+ }
450
465
  }
451
466
 
452
467
  // Include the type of attach message which is the pkg of the store to be
@@ -454,7 +469,7 @@ export class ChannelCollection implements IFluidDataStoreChannel, IDisposable {
454
469
  const pkg = [attachMessage.type];
455
470
  const remoteFluidDataStoreContext = new RemoteFluidDataStoreContext({
456
471
  id: attachMessage.id,
457
- snapshotTree,
472
+ snapshot,
458
473
  parentContext: this.wrapContextForInnerChannel(attachMessage.id),
459
474
  storage: new StorageServiceWithAttachBlobs(this.parentContext.storage, flatAttachBlobs),
460
475
  scope: this.parentContext.scope,
@@ -564,8 +579,8 @@ export class ChannelCollection implements IFluidDataStoreChannel, IDisposable {
564
579
  * If the container is detached, this data store will be part of the summary that makes the container attached.
565
580
  */
566
581
  if (this.parentContext.attachState !== AttachState.Detached) {
567
- localContext.setAttachState(AttachState.Attaching);
568
582
  this.submitAttachChannelOp(localContext);
583
+ localContext.setAttachState(AttachState.Attaching);
569
584
  }
570
585
 
571
586
  this.contexts.bind(id);
@@ -645,6 +660,7 @@ export class ChannelCollection implements IFluidDataStoreChannel, IDisposable {
645
660
  createProps?: any,
646
661
  loadingGroupId?: string,
647
662
  ) {
663
+ assert(loadingGroupId !== "", 0x974 /* loadingGroupId should not be the empty string */);
648
664
  const context = new contextCtor({
649
665
  id,
650
666
  pkg,
@@ -876,17 +892,18 @@ export class ChannelCollection implements IFluidDataStoreChannel, IDisposable {
876
892
 
877
893
  // Notify that a GC node for the data store changed. This is used to detect if a deleted data store is
878
894
  // being used.
879
- this.gcNodeUpdated(
880
- `/${address}`,
881
- "Changed",
882
- message.timestamp,
883
- context.isLoaded ? context.packagePath : undefined,
884
- );
895
+ this.gcNodeUpdated({
896
+ node: { type: "DataStore", path: `/${address}` },
897
+ reason: "Changed",
898
+ timestampMs: message.timestamp,
899
+ packagePath: context.isLoaded ? context.packagePath : undefined,
900
+ });
885
901
  }
886
902
 
887
- public async getDataStore(
903
+ private async getDataStore(
888
904
  id: string,
889
905
  requestHeaderData: RuntimeHeaderData,
906
+ originalRequest: IRequest,
890
907
  ): Promise<IFluidDataStoreContextInternal> {
891
908
  const headerData = { ...defaultRuntimeHeaderData, ...requestHeaderData };
892
909
  if (
@@ -896,13 +913,15 @@ export class ChannelCollection implements IFluidDataStoreChannel, IDisposable {
896
913
  "Requested",
897
914
  "getDataStore",
898
915
  requestHeaderData,
916
+ originalRequest,
899
917
  )
900
918
  ) {
901
919
  // The requested data store has been deleted by gc. Create a 404 response exception.
902
- const request: IRequest = { url: id };
903
920
  throw responseToException(
904
- createResponseError(404, "DataStore was deleted", request),
905
- request,
921
+ createResponseError(404, "DataStore was deleted", originalRequest, {
922
+ [DeletedResponseHeaderKey]: true,
923
+ }),
924
+ originalRequest,
906
925
  );
907
926
  }
908
927
 
@@ -946,28 +965,69 @@ export class ChannelCollection implements IFluidDataStoreChannel, IDisposable {
946
965
  * Checks if the data store has been deleted by GC. If so, log an error.
947
966
  * @param id - The data store's id.
948
967
  * @param context - The data store context.
968
+ * @param deletedLogSuffix - Whether it was Changed or Requested (will go into the eventName)
949
969
  * @param callSite - The function name this is called from.
950
970
  * @param requestHeaderData - The request header information to log if the data store is deleted.
971
+ * @param originalRequest - The original request (could be for a child of the DataStore)
951
972
  * @returns true if the data store is deleted. Otherwise, returns false.
952
973
  */
953
974
  private checkAndLogIfDeleted(
954
975
  id: string,
955
976
  context: IFluidDataStoreContext | undefined,
956
- deletedLogSuffix: string,
977
+ deletedLogSuffix: "Changed" | "Requested",
957
978
  callSite: string,
958
979
  requestHeaderData?: RuntimeHeaderData,
980
+ originalRequest?: IRequest,
959
981
  ) {
960
982
  const dataStoreNodePath = `/${id}`;
961
983
  if (!this.isDataStoreDeleted(dataStoreNodePath)) {
962
984
  return false;
963
985
  }
964
986
 
987
+ const idToLog =
988
+ originalRequest !== undefined
989
+ ? urlToGCNodePath(originalRequest.url)
990
+ : dataStoreNodePath;
991
+
992
+ // Log the package details asynchronously since getInitialSnapshotDetails is async
993
+ const recentelyDeletedContext = this.contexts.getRecentlyDeletedContext(id);
994
+ if (recentelyDeletedContext !== undefined) {
995
+ recentelyDeletedContext
996
+ .getInitialSnapshotDetails()
997
+ .then((details) => {
998
+ return details.pkg.join("/");
999
+ })
1000
+ .then(
1001
+ (pkg) => ({ pkg, error: undefined }),
1002
+ (error) => ({ pkg: undefined, error }),
1003
+ )
1004
+ .then(({ pkg, error }) => {
1005
+ this.mc.logger.sendTelemetryEvent(
1006
+ {
1007
+ eventName: `GC_DeletedDataStore_PathInfo`,
1008
+ ...tagCodeArtifacts({
1009
+ id: idToLog,
1010
+ pkg,
1011
+ }),
1012
+ callSite,
1013
+ },
1014
+ error,
1015
+ );
1016
+ })
1017
+ .catch(() => {});
1018
+ }
1019
+
965
1020
  this.mc.logger.sendErrorEvent({
966
1021
  eventName: `GC_Deleted_DataStore_${deletedLogSuffix}`,
967
- ...tagCodeArtifacts({ id }),
1022
+ ...tagCodeArtifacts({ id: idToLog }),
968
1023
  callSite,
969
1024
  headers: JSON.stringify(requestHeaderData),
970
1025
  exists: context !== undefined,
1026
+ details: {
1027
+ url: originalRequest?.url,
1028
+ headers: JSON.stringify(originalRequest?.headers),
1029
+ aliased: this.aliasedDataStores.has(id),
1030
+ },
971
1031
  });
972
1032
  return true;
973
1033
  }
@@ -1110,7 +1170,7 @@ export class ChannelCollection implements IFluidDataStoreChannel, IDisposable {
1110
1170
  0x166 /* "BaseSnapshot should be there as detached container loaded from snapshot" */,
1111
1171
  );
1112
1172
  dataStoreSummary = convertSnapshotTreeToSummaryTree(
1113
- this.baseSnapshot.trees[key],
1173
+ getSnapshotTree(this.baseSnapshot).trees[key],
1114
1174
  );
1115
1175
  }
1116
1176
  builder.addWithStats(key, dataStoreSummary);
@@ -1214,6 +1274,16 @@ export class ChannelCollection implements IFluidDataStoreChannel, IDisposable {
1214
1274
  const dataStoreContext = this.contexts.get(dataStoreId);
1215
1275
  assert(dataStoreContext !== undefined, 0x2d7 /* No data store with specified id */);
1216
1276
 
1277
+ if (dataStoreContext.isLoaded) {
1278
+ this.mc.logger.sendTelemetryEvent({
1279
+ eventName: "GC_DeletingLoadedDataStore",
1280
+ ...tagCodeArtifacts({
1281
+ id: dataStoreId,
1282
+ pkg: dataStoreContext.packagePath.join("/"),
1283
+ }),
1284
+ });
1285
+ }
1286
+
1217
1287
  dataStoreContext.delete();
1218
1288
  // Delete the contexts of unused data stores.
1219
1289
  this.contexts.delete(dataStoreId);
@@ -1355,31 +1425,29 @@ export class ChannelCollection implements IFluidDataStoreChannel, IDisposable {
1355
1425
  headerData.allowInactive = request.headers[AllowInactiveRequestHeaderKey];
1356
1426
  }
1357
1427
 
1358
- // We allow Tombstone requests for sub-DataStore objects
1428
+ // We allow Tombstone/Inactive requests for sub-DataStore objects
1359
1429
  if (requestForChild) {
1360
1430
  headerData.allowTombstone = true;
1431
+ headerData.allowInactive = true;
1361
1432
  }
1362
1433
 
1363
1434
  await this.waitIfPendingAlias(id);
1364
1435
  const internalId = this.internalId(id);
1365
- const dataStoreContext = await this.getDataStore(internalId, headerData);
1436
+ const dataStoreContext = await this.getDataStore(internalId, headerData, request);
1366
1437
 
1367
- // Remove query params, leading and trailing slashes from the url. This is done to make sure the format is
1368
- // the same as GC nodes id.
1369
- const urlWithoutQuery = trimLeadingAndTrailingSlashes(request.url.split("?")[0]);
1370
1438
  // Get the initial snapshot details which contain the data store package path.
1371
1439
  const details = await dataStoreContext.getInitialSnapshotDetails();
1372
1440
 
1373
- // Note that this will throw if the data store is inactive or tombstoned and throwing on incorrect usage
1374
- // is configured.
1375
- this.gcNodeUpdated(
1376
- `/${urlWithoutQuery}`,
1377
- "Loaded",
1378
- undefined /* timestampMs */,
1379
- details.pkg,
1441
+ // When notifying GC of this node being loaded, we only indicate the DataStore itself, not the full subDataStore url if applicable.
1442
+ // This is in case the url is to a route that Fluid doesn't understand or track for GC (e.g. if suited for a custom request handler)
1443
+ this.gcNodeUpdated({
1444
+ node: { type: "DataStore", path: `/${id}` },
1445
+ reason: "Loaded",
1446
+ packagePath: details.pkg,
1380
1447
  request,
1381
1448
  headerData,
1382
- );
1449
+ });
1450
+
1383
1451
  const dataStore = await dataStoreContext.realize();
1384
1452
 
1385
1453
  const subRequest = requestParser.createSubRequest(1);
@@ -4,18 +4,19 @@
4
4
  */
5
5
 
6
6
  import { performance } from "@fluid-internal/client-utils";
7
- import { IDeltaManager } from "@fluidframework/container-definitions";
7
+ import { IDeltaManager } from "@fluidframework/container-definitions/internal";
8
8
  import { IContainerRuntimeEvents } from "@fluidframework/container-runtime-definitions/internal";
9
9
  import { IEventProvider } from "@fluidframework/core-interfaces";
10
10
  import { assert } from "@fluidframework/core-utils/internal";
11
+ import { isRuntimeMessage } from "@fluidframework/driver-utils/internal";
11
12
  import {
12
13
  IDocumentMessage,
13
14
  ISequencedDocumentMessage,
14
15
  MessageType,
15
16
  } from "@fluidframework/protocol-definitions";
16
- import { ITelemetryLoggerExt } from "@fluidframework/telemetry-utils";
17
17
  import {
18
18
  IEventSampler,
19
+ ITelemetryLoggerExt,
19
20
  ISampledTelemetryLogger,
20
21
  createChildLogger,
21
22
  createSampledLogger,
@@ -80,6 +81,11 @@ class OpPerfTelemetry {
80
81
  private connectionStartTime = 0;
81
82
  private gap = 0;
82
83
 
84
+ /** Count of no-ops sent by this client. This variable is reset everytime the OpStats sampled event is logged */
85
+ private noOpCountForTelemetry = 0;
86
+ /** Cumulative size of the ops processed by this client. This variable is reset everytime the OpStats sampled event is logged */
87
+ private processedOpSizeForTelemetry = 0;
88
+
83
89
  private readonly logger: ITelemetryLoggerExt;
84
90
 
85
91
  private static readonly OP_LATENCY_SAMPLE_RATE = 500;
@@ -88,6 +94,9 @@ class OpPerfTelemetry {
88
94
  private static readonly DELTA_LATENCY_SAMPLE_RATE = 100;
89
95
  private readonly deltaLatencyLogger: ISampledTelemetryLogger;
90
96
 
97
+ private static readonly PROCESSED_OPS_SAMPLE_RATE = 500;
98
+ private readonly opsLogger: ISampledTelemetryLogger;
99
+
91
100
  /**
92
101
  * Create an instance of OpPerfTelemetry which starts monitoring and generating telemetry related to op performance.
93
102
  *
@@ -142,11 +151,27 @@ class OpPerfTelemetry {
142
151
  // due to complexity of the different asynchronus scenarios of the op message lifecycle.
143
152
  this.opLatencyLogger = createSampledLogger(logger);
144
153
 
154
+ const opsEventSampler: IEventSampler = (() => {
155
+ let eventCount = 0;
156
+ return {
157
+ sample: () => {
158
+ eventCount++;
159
+ const shouldSample =
160
+ eventCount % OpPerfTelemetry.PROCESSED_OPS_SAMPLE_RATE === 0;
161
+ if (shouldSample) {
162
+ eventCount = 0;
163
+ this.noOpCountForTelemetry = 0;
164
+ this.processedOpSizeForTelemetry = 0;
165
+ }
166
+ return shouldSample;
167
+ },
168
+ };
169
+ })();
170
+ this.opsLogger = createSampledLogger(logger, opsEventSampler);
171
+
145
172
  this.deltaManager.on("pong", (latency) => this.recordPingTime(latency));
146
173
  this.deltaManager.on("submitOp", (message) => this.beforeOpSubmit(message));
147
-
148
174
  this.deltaManager.on("op", (message) => this.afterProcessingOp(message));
149
-
150
175
  this.deltaManager.on("connect", (details, opsBehind) => {
151
176
  if (opsBehind !== undefined) {
152
177
  this.connectionOpSeqNumber = this.deltaManager.lastKnownSeqNumber;
@@ -226,6 +251,9 @@ class OpPerfTelemetry {
226
251
  latencyStats.opPerfData.lengthInboundQueue = this.deltaManager.inbound.length;
227
252
  }
228
253
  }
254
+ if (isRuntimeMessage(message) && typeof message.contents === "string") {
255
+ this.processedOpSizeForTelemetry += message.contents.length;
256
+ }
229
257
  });
230
258
 
231
259
  this.deltaManager.inbound.on("idle", (count: number, duration: number) => {
@@ -302,6 +330,12 @@ class OpPerfTelemetry {
302
330
  opPerfData: {},
303
331
  });
304
332
  }
333
+
334
+ if (message.type === MessageType.NoOp) {
335
+ // Count the number of no-ops submitted by this client.
336
+ // The value is reset when we log the OpStats sampled event.
337
+ this.noOpCountForTelemetry++;
338
+ }
305
339
  }
306
340
 
307
341
  private afterProcessingOp(message: ISequencedDocumentMessage) {
@@ -335,6 +369,7 @@ class OpPerfTelemetry {
335
369
 
336
370
  if (
337
371
  this.clientId === message.clientId &&
372
+ message.type === MessageType.Operation &&
338
373
  (this.opLatencyLogger.isSamplingDisabled ||
339
374
  this.clientSequenceNumberForLatencyStatistics === message.clientSequenceNumber)
340
375
  ) {
@@ -372,9 +407,29 @@ class OpPerfTelemetry {
372
407
  this.deltaManager.lastSequenceNumber - this.deltaManager.minimumSequenceNumber,
373
408
  ...latencyData.opPerfData,
374
409
  });
410
+
375
411
  this.clientSequenceNumberForLatencyStatistics = undefined;
376
412
  this.latencyStatistics.delete(message.clientSequenceNumber);
377
413
  }
414
+
415
+ if (isRuntimeMessage(message)) {
416
+ // Sampled logging of Ops that have been processed by the current client, the NoOp sent and the
417
+ // size of the ops processed within one sampling window of this log event.
418
+ // This data will be used to monitor the efficiency of NoOp-heuristics or to get approximate collab window size.
419
+ this.opsLogger.sendPerformanceEvent({
420
+ eventName: "OpStats",
421
+ // Logging as 'details' property to avoid adding new column name to the log tables */
422
+ details: {
423
+ // Count of the ops processed by the current client. Note: these counts are after
424
+ // compression/grouping/chunking (if enabled) of the ops.
425
+ processedOpCount: OpPerfTelemetry.PROCESSED_OPS_SAMPLE_RATE,
426
+ // Cumulative size of all the ops processed by the current client since the last OpStats event log
427
+ processedOpSize: this.processedOpSizeForTelemetry,
428
+ // Count of all the NoOp sent by the current client since the last OpStats event log
429
+ submitedNoOpCount: this.noOpCountForTelemetry,
430
+ },
431
+ });
432
+ }
378
433
  }
379
434
  }
380
435
  export interface IPerfSignalReport {