@fluidframework/container-runtime 2.0.0-dev-rc.3.0.0.254674 → 2.0.0-dev-rc.4.0.0.261659

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 (293) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/api-report/container-runtime.api.md +33 -19
  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/channelCollection.d.ts +5 -3
  7. package/dist/channelCollection.d.ts.map +1 -1
  8. package/dist/channelCollection.js +67 -15
  9. package/dist/channelCollection.js.map +1 -1
  10. package/dist/connectionTelemetry.d.ts +1 -1
  11. package/dist/connectionTelemetry.d.ts.map +1 -1
  12. package/dist/connectionTelemetry.js +54 -5
  13. package/dist/connectionTelemetry.js.map +1 -1
  14. package/dist/containerRuntime.d.ts +17 -27
  15. package/dist/containerRuntime.d.ts.map +1 -1
  16. package/dist/containerRuntime.js +174 -143
  17. package/dist/containerRuntime.js.map +1 -1
  18. package/dist/dataStore.d.ts +1 -1
  19. package/dist/dataStore.d.ts.map +1 -1
  20. package/dist/dataStore.js.map +1 -1
  21. package/dist/dataStoreContext.d.ts.map +1 -1
  22. package/dist/dataStoreContext.js +1 -0
  23. package/dist/dataStoreContext.js.map +1 -1
  24. package/dist/dataStoreContexts.d.ts +2 -0
  25. package/dist/dataStoreContexts.d.ts.map +1 -1
  26. package/dist/dataStoreContexts.js +7 -0
  27. package/dist/dataStoreContexts.js.map +1 -1
  28. package/dist/deltaManagerSummarizerProxy.d.ts +18 -6
  29. package/dist/deltaManagerSummarizerProxy.d.ts.map +1 -1
  30. package/dist/deltaManagerSummarizerProxy.js +38 -19
  31. package/dist/deltaManagerSummarizerProxy.js.map +1 -1
  32. package/dist/deltaScheduler.d.ts +1 -1
  33. package/dist/deltaScheduler.d.ts.map +1 -1
  34. package/dist/deltaScheduler.js.map +1 -1
  35. package/dist/gc/garbageCollection.d.ts +5 -12
  36. package/dist/gc/garbageCollection.d.ts.map +1 -1
  37. package/dist/gc/garbageCollection.js +45 -29
  38. package/dist/gc/garbageCollection.js.map +1 -1
  39. package/dist/gc/gcDefinitions.d.ts +27 -6
  40. package/dist/gc/gcDefinitions.d.ts.map +1 -1
  41. package/dist/gc/gcDefinitions.js.map +1 -1
  42. package/dist/gc/gcHelpers.d.ts +5 -4
  43. package/dist/gc/gcHelpers.d.ts.map +1 -1
  44. package/dist/gc/gcHelpers.js +14 -2
  45. package/dist/gc/gcHelpers.js.map +1 -1
  46. package/dist/gc/gcTelemetry.d.ts +14 -4
  47. package/dist/gc/gcTelemetry.d.ts.map +1 -1
  48. package/dist/gc/gcTelemetry.js +24 -21
  49. package/dist/gc/gcTelemetry.js.map +1 -1
  50. package/dist/gc/index.d.ts +2 -2
  51. package/dist/gc/index.d.ts.map +1 -1
  52. package/dist/gc/index.js +2 -2
  53. package/dist/gc/index.js.map +1 -1
  54. package/dist/index.d.ts +2 -2
  55. package/dist/index.d.ts.map +1 -1
  56. package/dist/index.js +2 -1
  57. package/dist/index.js.map +1 -1
  58. package/dist/{alpha.d.ts → legacy.d.ts} +3 -1
  59. package/dist/metadata.d.ts +2 -2
  60. package/dist/metadata.d.ts.map +1 -1
  61. package/dist/metadata.js.map +1 -1
  62. package/dist/opLifecycle/batchManager.d.ts +0 -1
  63. package/dist/opLifecycle/batchManager.d.ts.map +1 -1
  64. package/dist/opLifecycle/batchManager.js +0 -10
  65. package/dist/opLifecycle/batchManager.js.map +1 -1
  66. package/dist/opLifecycle/opDecompressor.d.ts.map +1 -1
  67. package/dist/opLifecycle/opDecompressor.js +6 -6
  68. package/dist/opLifecycle/opDecompressor.js.map +1 -1
  69. package/dist/opLifecycle/opGroupingManager.js +2 -2
  70. package/dist/opLifecycle/opGroupingManager.js.map +1 -1
  71. package/dist/opLifecycle/opSplitter.js +1 -1
  72. package/dist/opLifecycle/opSplitter.js.map +1 -1
  73. package/dist/opLifecycle/outbox.d.ts +0 -4
  74. package/dist/opLifecycle/outbox.d.ts.map +1 -1
  75. package/dist/opLifecycle/outbox.js +2 -34
  76. package/dist/opLifecycle/outbox.js.map +1 -1
  77. package/dist/packageVersion.d.ts +1 -1
  78. package/dist/packageVersion.js +1 -1
  79. package/dist/packageVersion.js.map +1 -1
  80. package/dist/pendingStateManager.d.ts +3 -2
  81. package/dist/pendingStateManager.d.ts.map +1 -1
  82. package/dist/pendingStateManager.js +17 -10
  83. package/dist/pendingStateManager.js.map +1 -1
  84. package/dist/public.d.ts +3 -0
  85. package/dist/scheduleManager.d.ts +1 -1
  86. package/dist/scheduleManager.d.ts.map +1 -1
  87. package/dist/scheduleManager.js.map +1 -1
  88. package/dist/summary/documentSchema.d.ts +3 -1
  89. package/dist/summary/documentSchema.d.ts.map +1 -1
  90. package/dist/summary/documentSchema.js +34 -16
  91. package/dist/summary/documentSchema.js.map +1 -1
  92. package/dist/summary/orderedClientElection.d.ts +1 -1
  93. package/dist/summary/orderedClientElection.d.ts.map +1 -1
  94. package/dist/summary/orderedClientElection.js.map +1 -1
  95. package/dist/summary/summarizer.d.ts +1 -2
  96. package/dist/summary/summarizer.d.ts.map +1 -1
  97. package/dist/summary/summarizer.js.map +1 -1
  98. package/dist/summary/summarizerClientElection.d.ts +1 -1
  99. package/dist/summary/summarizerClientElection.d.ts.map +1 -1
  100. package/dist/summary/summarizerClientElection.js.map +1 -1
  101. package/dist/summary/summarizerHeuristics.d.ts +1 -1
  102. package/dist/summary/summarizerHeuristics.d.ts.map +1 -1
  103. package/dist/summary/summarizerHeuristics.js.map +1 -1
  104. package/dist/summary/summarizerNode/summarizerNode.d.ts +4 -3
  105. package/dist/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
  106. package/dist/summary/summarizerNode/summarizerNode.js +4 -10
  107. package/dist/summary/summarizerNode/summarizerNode.js.map +1 -1
  108. package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts +2 -3
  109. package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
  110. package/dist/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
  111. package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts +1 -2
  112. package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
  113. package/dist/summary/summarizerNode/summarizerNodeWithGc.js +2 -9
  114. package/dist/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
  115. package/dist/summary/summarizerTypes.d.ts +2 -3
  116. package/dist/summary/summarizerTypes.d.ts.map +1 -1
  117. package/dist/summary/summarizerTypes.js.map +1 -1
  118. package/dist/summary/summaryCollection.d.ts +1 -1
  119. package/dist/summary/summaryCollection.d.ts.map +1 -1
  120. package/dist/summary/summaryCollection.js.map +1 -1
  121. package/dist/summary/summaryGenerator.d.ts +1 -2
  122. package/dist/summary/summaryGenerator.d.ts.map +1 -1
  123. package/dist/summary/summaryGenerator.js +3 -2
  124. package/dist/summary/summaryGenerator.js.map +1 -1
  125. package/dist/summary/summaryManager.d.ts.map +1 -1
  126. package/dist/summary/summaryManager.js.map +1 -1
  127. package/{dist/beta.d.ts → internal.d.ts} +2 -0
  128. package/{lib/beta.d.ts → legacy.d.ts} +2 -0
  129. package/lib/batchTracker.d.ts +1 -1
  130. package/lib/batchTracker.d.ts.map +1 -1
  131. package/lib/batchTracker.js.map +1 -1
  132. package/lib/channelCollection.d.ts +5 -3
  133. package/lib/channelCollection.d.ts.map +1 -1
  134. package/lib/channelCollection.js +69 -17
  135. package/lib/channelCollection.js.map +1 -1
  136. package/lib/connectionTelemetry.d.ts +1 -1
  137. package/lib/connectionTelemetry.d.ts.map +1 -1
  138. package/lib/connectionTelemetry.js +49 -0
  139. package/lib/connectionTelemetry.js.map +1 -1
  140. package/lib/containerRuntime.d.ts +17 -27
  141. package/lib/containerRuntime.d.ts.map +1 -1
  142. package/lib/containerRuntime.js +174 -143
  143. package/lib/containerRuntime.js.map +1 -1
  144. package/lib/dataStore.d.ts +1 -1
  145. package/lib/dataStore.d.ts.map +1 -1
  146. package/lib/dataStore.js +1 -1
  147. package/lib/dataStore.js.map +1 -1
  148. package/lib/dataStoreContext.d.ts.map +1 -1
  149. package/lib/dataStoreContext.js +1 -0
  150. package/lib/dataStoreContext.js.map +1 -1
  151. package/lib/dataStoreContexts.d.ts +2 -0
  152. package/lib/dataStoreContexts.d.ts.map +1 -1
  153. package/lib/dataStoreContexts.js +7 -0
  154. package/lib/dataStoreContexts.js.map +1 -1
  155. package/lib/deltaManagerSummarizerProxy.d.ts +18 -6
  156. package/lib/deltaManagerSummarizerProxy.d.ts.map +1 -1
  157. package/lib/deltaManagerSummarizerProxy.js +36 -18
  158. package/lib/deltaManagerSummarizerProxy.js.map +1 -1
  159. package/lib/deltaScheduler.d.ts +1 -1
  160. package/lib/deltaScheduler.d.ts.map +1 -1
  161. package/lib/deltaScheduler.js.map +1 -1
  162. package/lib/gc/garbageCollection.d.ts +5 -12
  163. package/lib/gc/garbageCollection.d.ts.map +1 -1
  164. package/lib/gc/garbageCollection.js +47 -31
  165. package/lib/gc/garbageCollection.js.map +1 -1
  166. package/lib/gc/gcDefinitions.d.ts +27 -6
  167. package/lib/gc/gcDefinitions.d.ts.map +1 -1
  168. package/lib/gc/gcDefinitions.js.map +1 -1
  169. package/lib/gc/gcHelpers.d.ts +5 -4
  170. package/lib/gc/gcHelpers.d.ts.map +1 -1
  171. package/lib/gc/gcHelpers.js +12 -1
  172. package/lib/gc/gcHelpers.js.map +1 -1
  173. package/lib/gc/gcTelemetry.d.ts +14 -4
  174. package/lib/gc/gcTelemetry.d.ts.map +1 -1
  175. package/lib/gc/gcTelemetry.js +24 -21
  176. package/lib/gc/gcTelemetry.js.map +1 -1
  177. package/lib/gc/index.d.ts +2 -2
  178. package/lib/gc/index.d.ts.map +1 -1
  179. package/lib/gc/index.js +1 -1
  180. package/lib/gc/index.js.map +1 -1
  181. package/lib/index.d.ts +2 -2
  182. package/lib/index.d.ts.map +1 -1
  183. package/lib/index.js +1 -1
  184. package/lib/index.js.map +1 -1
  185. package/lib/{alpha.d.ts → legacy.d.ts} +3 -1
  186. package/lib/metadata.d.ts +2 -2
  187. package/lib/metadata.d.ts.map +1 -1
  188. package/lib/metadata.js.map +1 -1
  189. package/lib/opLifecycle/batchManager.d.ts +0 -1
  190. package/lib/opLifecycle/batchManager.d.ts.map +1 -1
  191. package/lib/opLifecycle/batchManager.js +0 -10
  192. package/lib/opLifecycle/batchManager.js.map +1 -1
  193. package/lib/opLifecycle/opDecompressor.d.ts.map +1 -1
  194. package/lib/opLifecycle/opDecompressor.js +6 -6
  195. package/lib/opLifecycle/opDecompressor.js.map +1 -1
  196. package/lib/opLifecycle/opGroupingManager.js +2 -2
  197. package/lib/opLifecycle/opGroupingManager.js.map +1 -1
  198. package/lib/opLifecycle/opSplitter.js +1 -1
  199. package/lib/opLifecycle/opSplitter.js.map +1 -1
  200. package/lib/opLifecycle/outbox.d.ts +0 -4
  201. package/lib/opLifecycle/outbox.d.ts.map +1 -1
  202. package/lib/opLifecycle/outbox.js +2 -34
  203. package/lib/opLifecycle/outbox.js.map +1 -1
  204. package/lib/packageVersion.d.ts +1 -1
  205. package/lib/packageVersion.js +1 -1
  206. package/lib/packageVersion.js.map +1 -1
  207. package/lib/pendingStateManager.d.ts +3 -2
  208. package/lib/pendingStateManager.d.ts.map +1 -1
  209. package/lib/pendingStateManager.js +18 -11
  210. package/lib/pendingStateManager.js.map +1 -1
  211. package/lib/public.d.ts +3 -0
  212. package/lib/scheduleManager.d.ts +1 -1
  213. package/lib/scheduleManager.d.ts.map +1 -1
  214. package/lib/scheduleManager.js.map +1 -1
  215. package/lib/summary/documentSchema.d.ts +3 -1
  216. package/lib/summary/documentSchema.d.ts.map +1 -1
  217. package/lib/summary/documentSchema.js +34 -16
  218. package/lib/summary/documentSchema.js.map +1 -1
  219. package/lib/summary/orderedClientElection.d.ts +1 -1
  220. package/lib/summary/orderedClientElection.d.ts.map +1 -1
  221. package/lib/summary/orderedClientElection.js +1 -1
  222. package/lib/summary/orderedClientElection.js.map +1 -1
  223. package/lib/summary/summarizer.d.ts +1 -2
  224. package/lib/summary/summarizer.d.ts.map +1 -1
  225. package/lib/summary/summarizer.js.map +1 -1
  226. package/lib/summary/summarizerClientElection.d.ts +1 -1
  227. package/lib/summary/summarizerClientElection.d.ts.map +1 -1
  228. package/lib/summary/summarizerClientElection.js.map +1 -1
  229. package/lib/summary/summarizerHeuristics.d.ts +1 -1
  230. package/lib/summary/summarizerHeuristics.d.ts.map +1 -1
  231. package/lib/summary/summarizerHeuristics.js.map +1 -1
  232. package/lib/summary/summarizerNode/summarizerNode.d.ts +4 -3
  233. package/lib/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
  234. package/lib/summary/summarizerNode/summarizerNode.js +4 -10
  235. package/lib/summary/summarizerNode/summarizerNode.js.map +1 -1
  236. package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts +2 -3
  237. package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
  238. package/lib/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
  239. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts +1 -2
  240. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
  241. package/lib/summary/summarizerNode/summarizerNodeWithGc.js +2 -9
  242. package/lib/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
  243. package/lib/summary/summarizerTypes.d.ts +2 -3
  244. package/lib/summary/summarizerTypes.d.ts.map +1 -1
  245. package/lib/summary/summarizerTypes.js.map +1 -1
  246. package/lib/summary/summaryCollection.d.ts +1 -1
  247. package/lib/summary/summaryCollection.d.ts.map +1 -1
  248. package/lib/summary/summaryCollection.js.map +1 -1
  249. package/lib/summary/summaryGenerator.d.ts +1 -2
  250. package/lib/summary/summaryGenerator.d.ts.map +1 -1
  251. package/lib/summary/summaryGenerator.js +4 -3
  252. package/lib/summary/summaryGenerator.js.map +1 -1
  253. package/lib/summary/summaryManager.d.ts.map +1 -1
  254. package/lib/summary/summaryManager.js +1 -1
  255. package/lib/summary/summaryManager.js.map +1 -1
  256. package/package.json +33 -57
  257. package/src/batchTracker.ts +1 -2
  258. package/src/channelCollection.ts +87 -35
  259. package/src/connectionTelemetry.ts +58 -3
  260. package/src/containerRuntime.ts +214 -222
  261. package/src/dataStore.ts +5 -2
  262. package/src/dataStoreContext.ts +1 -0
  263. package/src/dataStoreContexts.ts +13 -2
  264. package/src/deltaManagerSummarizerProxy.ts +43 -21
  265. package/src/deltaScheduler.ts +1 -2
  266. package/src/gc/garbageCollection.ts +64 -42
  267. package/src/gc/gcDefinitions.ts +22 -10
  268. package/src/gc/gcHelpers.ts +14 -1
  269. package/src/gc/gcTelemetry.ts +57 -50
  270. package/src/gc/index.ts +2 -1
  271. package/src/index.ts +2 -0
  272. package/src/metadata.ts +2 -2
  273. package/src/opLifecycle/README.md +4 -4
  274. package/src/opLifecycle/batchManager.ts +0 -14
  275. package/src/opLifecycle/opDecompressor.ts +12 -6
  276. package/src/opLifecycle/opGroupingManager.ts +2 -2
  277. package/src/opLifecycle/opSplitter.ts +1 -1
  278. package/src/opLifecycle/outbox.ts +2 -49
  279. package/src/packageVersion.ts +1 -1
  280. package/src/pendingStateManager.ts +28 -15
  281. package/src/scheduleManager.ts +1 -1
  282. package/src/summary/documentSchema.ts +52 -18
  283. package/src/summary/orderedClientElection.ts +5 -2
  284. package/src/summary/summarizer.ts +1 -1
  285. package/src/summary/summarizerClientElection.ts +1 -1
  286. package/src/summary/summarizerHeuristics.ts +1 -1
  287. package/src/summary/summarizerNode/summarizerNode.ts +3 -12
  288. package/src/summary/summarizerNode/summarizerNodeUtils.ts +2 -3
  289. package/src/summary/summarizerNode/summarizerNodeWithGc.ts +1 -10
  290. package/src/summary/summarizerTypes.ts +5 -3
  291. package/src/summary/summaryCollection.ts +1 -1
  292. package/src/summary/summaryGenerator.ts +19 -8
  293. package/src/summary/summaryManager.ts +5 -2
@@ -63,7 +63,11 @@ import {
63
63
  tagCodeArtifacts,
64
64
  } from "@fluidframework/telemetry-utils/internal";
65
65
 
66
- import { RuntimeHeaderData, defaultRuntimeHeaderData } from "./containerRuntime.js";
66
+ import {
67
+ DeletedResponseHeaderKey,
68
+ RuntimeHeaderData,
69
+ defaultRuntimeHeaderData,
70
+ } from "./containerRuntime.js";
67
71
  import {
68
72
  IDataStoreAliasMessage,
69
73
  channelToDataStore,
@@ -83,7 +87,8 @@ import { FluidDataStoreRegistry } from "./dataStoreRegistry.js";
83
87
  import {
84
88
  GCNodeType,
85
89
  detectOutboundRoutesViaDDSKey,
86
- trimLeadingAndTrailingSlashes,
90
+ IGCNodeUpdatedProps,
91
+ urlToGCNodePath,
87
92
  } from "./gc/index.js";
88
93
  import { ContainerMessageType, LocalContainerRuntimeMessage } from "./messageTypes.js";
89
94
  import { StorageServiceWithAttachBlobs } from "./storageServiceWithAttachBlobs.js";
@@ -163,6 +168,7 @@ export function wrapContext(context: IFluidParentContext): IFluidParentContext {
163
168
  getAudience: (...args) => {
164
169
  return context.getAudience(...args);
165
170
  },
171
+ // back-compat, to be removed in 2.0
166
172
  ensureNoDataModelChanges: (...args) => {
167
173
  return context.ensureNoDataModelChanges(...args);
168
174
  },
@@ -276,14 +282,7 @@ export class ChannelCollection implements IFluidDataStoreChannel, IDisposable {
276
282
  protected readonly baseSnapshot: ISnapshotTree | undefined,
277
283
  public readonly parentContext: IFluidParentContext,
278
284
  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,
285
+ private readonly gcNodeUpdated: (props: IGCNodeUpdatedProps) => void,
287
286
  private readonly isDataStoreDeleted: (nodePath: string) => boolean,
288
287
  private readonly aliasMap: Map<string, string>,
289
288
  provideEntryPoint: (runtime: ChannelCollection) => Promise<FluidObject>,
@@ -645,6 +644,7 @@ export class ChannelCollection implements IFluidDataStoreChannel, IDisposable {
645
644
  createProps?: any,
646
645
  loadingGroupId?: string,
647
646
  ) {
647
+ assert(loadingGroupId !== "", "loadingGroupId should not be the empty string");
648
648
  const context = new contextCtor({
649
649
  id,
650
650
  pkg,
@@ -876,17 +876,18 @@ export class ChannelCollection implements IFluidDataStoreChannel, IDisposable {
876
876
 
877
877
  // Notify that a GC node for the data store changed. This is used to detect if a deleted data store is
878
878
  // being used.
879
- this.gcNodeUpdated(
880
- `/${address}`,
881
- "Changed",
882
- message.timestamp,
883
- context.isLoaded ? context.packagePath : undefined,
884
- );
879
+ this.gcNodeUpdated({
880
+ node: { type: "DataStore", path: `/${address}` },
881
+ reason: "Changed",
882
+ timestampMs: message.timestamp,
883
+ packagePath: context.isLoaded ? context.packagePath : undefined,
884
+ });
885
885
  }
886
886
 
887
- public async getDataStore(
887
+ private async getDataStore(
888
888
  id: string,
889
889
  requestHeaderData: RuntimeHeaderData,
890
+ originalRequest: IRequest,
890
891
  ): Promise<IFluidDataStoreContextInternal> {
891
892
  const headerData = { ...defaultRuntimeHeaderData, ...requestHeaderData };
892
893
  if (
@@ -896,13 +897,15 @@ export class ChannelCollection implements IFluidDataStoreChannel, IDisposable {
896
897
  "Requested",
897
898
  "getDataStore",
898
899
  requestHeaderData,
900
+ originalRequest,
899
901
  )
900
902
  ) {
901
903
  // The requested data store has been deleted by gc. Create a 404 response exception.
902
- const request: IRequest = { url: id };
903
904
  throw responseToException(
904
- createResponseError(404, "DataStore was deleted", request),
905
- request,
905
+ createResponseError(404, "DataStore was deleted", originalRequest, {
906
+ [DeletedResponseHeaderKey]: true,
907
+ }),
908
+ originalRequest,
906
909
  );
907
910
  }
908
911
 
@@ -946,28 +949,69 @@ export class ChannelCollection implements IFluidDataStoreChannel, IDisposable {
946
949
  * Checks if the data store has been deleted by GC. If so, log an error.
947
950
  * @param id - The data store's id.
948
951
  * @param context - The data store context.
952
+ * @param deletedLogSuffix - Whether it was Changed or Requested (will go into the eventName)
949
953
  * @param callSite - The function name this is called from.
950
954
  * @param requestHeaderData - The request header information to log if the data store is deleted.
955
+ * @param originalRequest - The original request (could be for a child of the DataStore)
951
956
  * @returns true if the data store is deleted. Otherwise, returns false.
952
957
  */
953
958
  private checkAndLogIfDeleted(
954
959
  id: string,
955
960
  context: IFluidDataStoreContext | undefined,
956
- deletedLogSuffix: string,
961
+ deletedLogSuffix: "Changed" | "Requested",
957
962
  callSite: string,
958
963
  requestHeaderData?: RuntimeHeaderData,
964
+ originalRequest?: IRequest,
959
965
  ) {
960
966
  const dataStoreNodePath = `/${id}`;
961
967
  if (!this.isDataStoreDeleted(dataStoreNodePath)) {
962
968
  return false;
963
969
  }
964
970
 
971
+ const idToLog =
972
+ originalRequest !== undefined
973
+ ? urlToGCNodePath(originalRequest.url)
974
+ : dataStoreNodePath;
975
+
976
+ // Log the package details asynchronously since getInitialSnapshotDetails is async
977
+ const recentelyDeletedContext = this.contexts.getRecentlyDeletedContext(id);
978
+ if (recentelyDeletedContext !== undefined) {
979
+ recentelyDeletedContext
980
+ .getInitialSnapshotDetails()
981
+ .then((details) => {
982
+ return details.pkg.join("/");
983
+ })
984
+ .then(
985
+ (pkg) => ({ pkg, error: undefined }),
986
+ (error) => ({ pkg: undefined, error }),
987
+ )
988
+ .then(({ pkg, error }) => {
989
+ this.mc.logger.sendTelemetryEvent(
990
+ {
991
+ eventName: `GC_DeletedDataStore_PathInfo`,
992
+ ...tagCodeArtifacts({
993
+ id: idToLog,
994
+ pkg,
995
+ }),
996
+ callSite,
997
+ },
998
+ error,
999
+ );
1000
+ })
1001
+ .catch(() => {});
1002
+ }
1003
+
965
1004
  this.mc.logger.sendErrorEvent({
966
1005
  eventName: `GC_Deleted_DataStore_${deletedLogSuffix}`,
967
- ...tagCodeArtifacts({ id }),
1006
+ ...tagCodeArtifacts({ id: idToLog }),
968
1007
  callSite,
969
1008
  headers: JSON.stringify(requestHeaderData),
970
1009
  exists: context !== undefined,
1010
+ details: {
1011
+ url: originalRequest?.url,
1012
+ headers: JSON.stringify(originalRequest?.headers),
1013
+ aliased: this.aliasedDataStores.has(id),
1014
+ },
971
1015
  });
972
1016
  return true;
973
1017
  }
@@ -1214,6 +1258,16 @@ export class ChannelCollection implements IFluidDataStoreChannel, IDisposable {
1214
1258
  const dataStoreContext = this.contexts.get(dataStoreId);
1215
1259
  assert(dataStoreContext !== undefined, 0x2d7 /* No data store with specified id */);
1216
1260
 
1261
+ if (dataStoreContext.isLoaded) {
1262
+ this.mc.logger.sendTelemetryEvent({
1263
+ eventName: "GC_DeletingLoadedDataStore",
1264
+ ...tagCodeArtifacts({
1265
+ id: dataStoreId,
1266
+ pkg: dataStoreContext.packagePath.join("/"),
1267
+ }),
1268
+ });
1269
+ }
1270
+
1217
1271
  dataStoreContext.delete();
1218
1272
  // Delete the contexts of unused data stores.
1219
1273
  this.contexts.delete(dataStoreId);
@@ -1355,31 +1409,29 @@ export class ChannelCollection implements IFluidDataStoreChannel, IDisposable {
1355
1409
  headerData.allowInactive = request.headers[AllowInactiveRequestHeaderKey];
1356
1410
  }
1357
1411
 
1358
- // We allow Tombstone requests for sub-DataStore objects
1412
+ // We allow Tombstone/Inactive requests for sub-DataStore objects
1359
1413
  if (requestForChild) {
1360
1414
  headerData.allowTombstone = true;
1415
+ headerData.allowInactive = true;
1361
1416
  }
1362
1417
 
1363
1418
  await this.waitIfPendingAlias(id);
1364
1419
  const internalId = this.internalId(id);
1365
- const dataStoreContext = await this.getDataStore(internalId, headerData);
1420
+ const dataStoreContext = await this.getDataStore(internalId, headerData, request);
1366
1421
 
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
1422
  // Get the initial snapshot details which contain the data store package path.
1371
1423
  const details = await dataStoreContext.getInitialSnapshotDetails();
1372
1424
 
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,
1425
+ // When notifying GC of this node being loaded, we only indicate the DataStore itself, not the full subDataStore url if applicable.
1426
+ // 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)
1427
+ this.gcNodeUpdated({
1428
+ node: { type: "DataStore", path: `/${id}` },
1429
+ reason: "Loaded",
1430
+ packagePath: details.pkg,
1380
1431
  request,
1381
1432
  headerData,
1382
- );
1433
+ });
1434
+
1383
1435
  const dataStore = await dataStoreContext.realize();
1384
1436
 
1385
1437
  const subRequest = requestParser.createSubRequest(1);
@@ -8,14 +8,15 @@ import { IDeltaManager } from "@fluidframework/container-definitions";
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 {