@fluidframework/container-runtime 2.0.0-internal.7.3.0 → 2.0.0-internal.8.0.0

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 (271) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/api-extractor-lint.json +13 -0
  3. package/api-extractor.json +9 -1
  4. package/api-report/container-runtime.api.md +123 -123
  5. package/dist/blobManager.d.ts +4 -4
  6. package/dist/blobManager.d.ts.map +1 -1
  7. package/dist/blobManager.js.map +1 -1
  8. package/dist/container-runtime-alpha.d.ts +1444 -0
  9. package/dist/container-runtime-beta.d.ts +292 -0
  10. package/dist/container-runtime-public.d.ts +292 -0
  11. package/dist/container-runtime-untrimmed.d.ts +1792 -0
  12. package/dist/containerRuntime.d.ts +36 -66
  13. package/dist/containerRuntime.d.ts.map +1 -1
  14. package/dist/containerRuntime.js +68 -104
  15. package/dist/containerRuntime.js.map +1 -1
  16. package/dist/dataStore.js +0 -12
  17. package/dist/dataStore.js.map +1 -1
  18. package/dist/dataStoreRegistry.d.ts +1 -1
  19. package/dist/dataStoreRegistry.js +1 -1
  20. package/dist/dataStoreRegistry.js.map +1 -1
  21. package/dist/dataStores.d.ts +10 -15
  22. package/dist/dataStores.d.ts.map +1 -1
  23. package/dist/dataStores.js +77 -40
  24. package/dist/dataStores.js.map +1 -1
  25. package/dist/gc/garbageCollection.d.ts +41 -13
  26. package/dist/gc/garbageCollection.d.ts.map +1 -1
  27. package/dist/gc/garbageCollection.js +215 -78
  28. package/dist/gc/garbageCollection.js.map +1 -1
  29. package/dist/gc/gcConfigs.d.ts.map +1 -1
  30. package/dist/gc/gcConfigs.js +34 -37
  31. package/dist/gc/gcConfigs.js.map +1 -1
  32. package/dist/gc/gcDefinitions.d.ts +121 -46
  33. package/dist/gc/gcDefinitions.d.ts.map +1 -1
  34. package/dist/gc/gcDefinitions.js +26 -18
  35. package/dist/gc/gcDefinitions.js.map +1 -1
  36. package/dist/gc/gcHelpers.d.ts +18 -25
  37. package/dist/gc/gcHelpers.d.ts.map +1 -1
  38. package/dist/gc/gcHelpers.js +29 -45
  39. package/dist/gc/gcHelpers.js.map +1 -1
  40. package/dist/gc/gcTelemetry.d.ts +0 -5
  41. package/dist/gc/gcTelemetry.d.ts.map +1 -1
  42. package/dist/gc/gcTelemetry.js +14 -42
  43. package/dist/gc/gcTelemetry.js.map +1 -1
  44. package/dist/gc/gcUnreferencedStateTracker.d.ts +11 -5
  45. package/dist/gc/gcUnreferencedStateTracker.d.ts.map +1 -1
  46. package/dist/gc/gcUnreferencedStateTracker.js +43 -19
  47. package/dist/gc/gcUnreferencedStateTracker.js.map +1 -1
  48. package/dist/gc/index.d.ts +1 -1
  49. package/dist/gc/index.d.ts.map +1 -1
  50. package/dist/gc/index.js +4 -5
  51. package/dist/gc/index.js.map +1 -1
  52. package/dist/index.d.ts +15 -3
  53. package/dist/index.d.ts.map +1 -1
  54. package/dist/index.js +16 -6
  55. package/dist/index.js.map +1 -1
  56. package/dist/messageTypes.d.ts +15 -7
  57. package/dist/messageTypes.d.ts.map +1 -1
  58. package/dist/messageTypes.js +6 -1
  59. package/dist/messageTypes.js.map +1 -1
  60. package/dist/opLifecycle/definitions.d.ts +1 -1
  61. package/dist/opLifecycle/definitions.js.map +1 -1
  62. package/dist/packageVersion.d.ts +1 -1
  63. package/dist/packageVersion.js +1 -1
  64. package/dist/packageVersion.js.map +1 -1
  65. package/dist/pendingStateManager.d.ts +1 -0
  66. package/dist/pendingStateManager.d.ts.map +1 -1
  67. package/dist/pendingStateManager.js +1 -0
  68. package/dist/pendingStateManager.js.map +1 -1
  69. package/dist/summary/orderedClientElection.d.ts +1 -1
  70. package/dist/summary/orderedClientElection.js.map +1 -1
  71. package/dist/summary/runWhileConnectedCoordinator.d.ts +2 -2
  72. package/dist/summary/runWhileConnectedCoordinator.js +1 -1
  73. package/dist/summary/runWhileConnectedCoordinator.js.map +1 -1
  74. package/dist/summary/summarizer.d.ts +1 -13
  75. package/dist/summary/summarizer.d.ts.map +1 -1
  76. package/dist/summary/summarizer.js +1 -47
  77. package/dist/summary/summarizer.js.map +1 -1
  78. package/dist/summary/summarizerTypes.d.ts +30 -30
  79. package/dist/summary/summarizerTypes.js.map +1 -1
  80. package/dist/summary/summaryCollection.d.ts +10 -10
  81. package/dist/summary/summaryCollection.js +1 -1
  82. package/dist/summary/summaryCollection.js.map +1 -1
  83. package/dist/summary/summaryFormat.d.ts +3 -3
  84. package/dist/summary/summaryFormat.js.map +1 -1
  85. package/lib/blobManager.d.ts +4 -4
  86. package/lib/blobManager.d.ts.map +1 -1
  87. package/lib/blobManager.js.map +1 -1
  88. package/lib/container-runtime-alpha.d.ts +1444 -0
  89. package/lib/container-runtime-beta.d.ts +292 -0
  90. package/lib/container-runtime-public.d.ts +292 -0
  91. package/lib/container-runtime-untrimmed.d.ts +1792 -0
  92. package/lib/containerRuntime.d.ts +36 -66
  93. package/lib/containerRuntime.d.ts.map +1 -1
  94. package/lib/containerRuntime.js +69 -104
  95. package/lib/containerRuntime.js.map +1 -1
  96. package/lib/dataStore.js +0 -12
  97. package/lib/dataStore.js.map +1 -1
  98. package/lib/dataStoreRegistry.d.ts +1 -1
  99. package/lib/dataStoreRegistry.js +1 -1
  100. package/lib/dataStoreRegistry.js.map +1 -1
  101. package/lib/dataStores.d.ts +10 -15
  102. package/lib/dataStores.d.ts.map +1 -1
  103. package/lib/dataStores.js +80 -43
  104. package/lib/dataStores.js.map +1 -1
  105. package/lib/gc/garbageCollection.d.ts +41 -13
  106. package/lib/gc/garbageCollection.d.ts.map +1 -1
  107. package/lib/gc/garbageCollection.js +217 -80
  108. package/lib/gc/garbageCollection.js.map +1 -1
  109. package/lib/gc/gcConfigs.d.ts.map +1 -1
  110. package/lib/gc/gcConfigs.js +37 -40
  111. package/lib/gc/gcConfigs.js.map +1 -1
  112. package/lib/gc/gcDefinitions.d.ts +121 -46
  113. package/lib/gc/gcDefinitions.d.ts.map +1 -1
  114. package/lib/gc/gcDefinitions.js +25 -17
  115. package/lib/gc/gcDefinitions.js.map +1 -1
  116. package/lib/gc/gcHelpers.d.ts +18 -25
  117. package/lib/gc/gcHelpers.d.ts.map +1 -1
  118. package/lib/gc/gcHelpers.js +27 -43
  119. package/lib/gc/gcHelpers.js.map +1 -1
  120. package/lib/gc/gcTelemetry.d.ts +0 -5
  121. package/lib/gc/gcTelemetry.d.ts.map +1 -1
  122. package/lib/gc/gcTelemetry.js +15 -43
  123. package/lib/gc/gcTelemetry.js.map +1 -1
  124. package/lib/gc/gcUnreferencedStateTracker.d.ts +11 -5
  125. package/lib/gc/gcUnreferencedStateTracker.d.ts.map +1 -1
  126. package/lib/gc/gcUnreferencedStateTracker.js +43 -19
  127. package/lib/gc/gcUnreferencedStateTracker.js.map +1 -1
  128. package/lib/gc/index.d.ts +1 -1
  129. package/lib/gc/index.d.ts.map +1 -1
  130. package/lib/gc/index.js +1 -1
  131. package/lib/gc/index.js.map +1 -1
  132. package/lib/index.d.ts +15 -3
  133. package/lib/index.d.ts.map +1 -1
  134. package/lib/index.js +16 -2
  135. package/lib/index.js.map +1 -1
  136. package/lib/messageTypes.d.ts +15 -7
  137. package/lib/messageTypes.d.ts.map +1 -1
  138. package/lib/messageTypes.js +6 -1
  139. package/lib/messageTypes.js.map +1 -1
  140. package/lib/opLifecycle/definitions.d.ts +1 -1
  141. package/lib/opLifecycle/definitions.js.map +1 -1
  142. package/lib/packageVersion.d.ts +1 -1
  143. package/lib/packageVersion.js +1 -1
  144. package/lib/packageVersion.js.map +1 -1
  145. package/lib/pendingStateManager.d.ts +1 -0
  146. package/lib/pendingStateManager.d.ts.map +1 -1
  147. package/lib/pendingStateManager.js +1 -0
  148. package/lib/pendingStateManager.js.map +1 -1
  149. package/lib/summary/orderedClientElection.d.ts +1 -1
  150. package/lib/summary/orderedClientElection.js.map +1 -1
  151. package/lib/summary/runWhileConnectedCoordinator.d.ts +2 -2
  152. package/lib/summary/runWhileConnectedCoordinator.js +1 -1
  153. package/lib/summary/runWhileConnectedCoordinator.js.map +1 -1
  154. package/lib/summary/summarizer.d.ts +1 -13
  155. package/lib/summary/summarizer.d.ts.map +1 -1
  156. package/lib/summary/summarizer.js +1 -47
  157. package/lib/summary/summarizer.js.map +1 -1
  158. package/lib/summary/summarizerTypes.d.ts +30 -30
  159. package/lib/summary/summarizerTypes.js.map +1 -1
  160. package/lib/summary/summaryCollection.d.ts +10 -10
  161. package/lib/summary/summaryCollection.js +1 -1
  162. package/lib/summary/summaryCollection.js.map +1 -1
  163. package/lib/summary/summaryFormat.d.ts +3 -3
  164. package/lib/summary/summaryFormat.js.map +1 -1
  165. package/package.json +46 -19
  166. package/src/blobManager.ts +5 -5
  167. package/src/containerRuntime.ts +93 -141
  168. package/src/dataStore.ts +1 -15
  169. package/src/dataStoreRegistry.ts +1 -1
  170. package/src/dataStores.ts +140 -69
  171. package/src/gc/garbageCollection.md +14 -15
  172. package/src/gc/garbageCollection.ts +256 -96
  173. package/src/gc/gcConfigs.ts +50 -52
  174. package/src/gc/gcDefinitions.ts +137 -52
  175. package/src/gc/gcHelpers.ts +31 -52
  176. package/src/gc/gcTelemetry.ts +16 -57
  177. package/src/gc/gcUnreferencedStateTracker.ts +61 -22
  178. package/src/gc/index.ts +6 -4
  179. package/src/index.ts +19 -2
  180. package/src/messageTypes.ts +19 -4
  181. package/src/opLifecycle/definitions.ts +1 -1
  182. package/src/packageVersion.ts +1 -1
  183. package/src/pendingStateManager.ts +1 -0
  184. package/src/summary/orderedClientElection.ts +1 -1
  185. package/src/summary/runWhileConnectedCoordinator.ts +2 -2
  186. package/src/summary/summarizer.ts +2 -51
  187. package/src/summary/summarizerTypes.ts +30 -30
  188. package/src/summary/summaryCollection.ts +10 -10
  189. package/src/summary/summaryFormat.ts +3 -3
  190. package/dist/id-compressor/appendOnlySortedMap.d.ts +0 -124
  191. package/dist/id-compressor/appendOnlySortedMap.d.ts.map +0 -1
  192. package/dist/id-compressor/appendOnlySortedMap.js +0 -318
  193. package/dist/id-compressor/appendOnlySortedMap.js.map +0 -1
  194. package/dist/id-compressor/finalSpace.d.ts +0 -29
  195. package/dist/id-compressor/finalSpace.d.ts.map +0 -1
  196. package/dist/id-compressor/finalSpace.js +0 -62
  197. package/dist/id-compressor/finalSpace.js.map +0 -1
  198. package/dist/id-compressor/idCompressor.d.ts +0 -54
  199. package/dist/id-compressor/idCompressor.d.ts.map +0 -1
  200. package/dist/id-compressor/idCompressor.js +0 -495
  201. package/dist/id-compressor/idCompressor.js.map +0 -1
  202. package/dist/id-compressor/identifiers.d.ts +0 -32
  203. package/dist/id-compressor/identifiers.d.ts.map +0 -1
  204. package/dist/id-compressor/identifiers.js +0 -15
  205. package/dist/id-compressor/identifiers.js.map +0 -1
  206. package/dist/id-compressor/index.d.ts +0 -13
  207. package/dist/id-compressor/index.d.ts.map +0 -1
  208. package/dist/id-compressor/index.js +0 -32
  209. package/dist/id-compressor/index.js.map +0 -1
  210. package/dist/id-compressor/persistanceUtilities.d.ts +0 -22
  211. package/dist/id-compressor/persistanceUtilities.d.ts.map +0 -1
  212. package/dist/id-compressor/persistanceUtilities.js +0 -43
  213. package/dist/id-compressor/persistanceUtilities.js.map +0 -1
  214. package/dist/id-compressor/sessionSpaceNormalizer.d.ts +0 -46
  215. package/dist/id-compressor/sessionSpaceNormalizer.d.ts.map +0 -1
  216. package/dist/id-compressor/sessionSpaceNormalizer.js +0 -80
  217. package/dist/id-compressor/sessionSpaceNormalizer.js.map +0 -1
  218. package/dist/id-compressor/sessions.d.ts +0 -115
  219. package/dist/id-compressor/sessions.d.ts.map +0 -1
  220. package/dist/id-compressor/sessions.js +0 -305
  221. package/dist/id-compressor/sessions.js.map +0 -1
  222. package/dist/id-compressor/utilities.d.ts +0 -52
  223. package/dist/id-compressor/utilities.d.ts.map +0 -1
  224. package/dist/id-compressor/utilities.js +0 -169
  225. package/dist/id-compressor/utilities.js.map +0 -1
  226. package/lib/id-compressor/appendOnlySortedMap.d.ts +0 -124
  227. package/lib/id-compressor/appendOnlySortedMap.d.ts.map +0 -1
  228. package/lib/id-compressor/appendOnlySortedMap.js +0 -314
  229. package/lib/id-compressor/appendOnlySortedMap.js.map +0 -1
  230. package/lib/id-compressor/finalSpace.d.ts +0 -29
  231. package/lib/id-compressor/finalSpace.d.ts.map +0 -1
  232. package/lib/id-compressor/finalSpace.js +0 -58
  233. package/lib/id-compressor/finalSpace.js.map +0 -1
  234. package/lib/id-compressor/idCompressor.d.ts +0 -54
  235. package/lib/id-compressor/idCompressor.d.ts.map +0 -1
  236. package/lib/id-compressor/idCompressor.js +0 -491
  237. package/lib/id-compressor/idCompressor.js.map +0 -1
  238. package/lib/id-compressor/identifiers.d.ts +0 -32
  239. package/lib/id-compressor/identifiers.d.ts.map +0 -1
  240. package/lib/id-compressor/identifiers.js +0 -11
  241. package/lib/id-compressor/identifiers.js.map +0 -1
  242. package/lib/id-compressor/index.d.ts +0 -13
  243. package/lib/id-compressor/index.d.ts.map +0 -1
  244. package/lib/id-compressor/index.js +0 -13
  245. package/lib/id-compressor/index.js.map +0 -1
  246. package/lib/id-compressor/persistanceUtilities.d.ts +0 -22
  247. package/lib/id-compressor/persistanceUtilities.d.ts.map +0 -1
  248. package/lib/id-compressor/persistanceUtilities.js +0 -34
  249. package/lib/id-compressor/persistanceUtilities.js.map +0 -1
  250. package/lib/id-compressor/sessionSpaceNormalizer.d.ts +0 -46
  251. package/lib/id-compressor/sessionSpaceNormalizer.d.ts.map +0 -1
  252. package/lib/id-compressor/sessionSpaceNormalizer.js +0 -76
  253. package/lib/id-compressor/sessionSpaceNormalizer.js.map +0 -1
  254. package/lib/id-compressor/sessions.d.ts +0 -115
  255. package/lib/id-compressor/sessions.d.ts.map +0 -1
  256. package/lib/id-compressor/sessions.js +0 -290
  257. package/lib/id-compressor/sessions.js.map +0 -1
  258. package/lib/id-compressor/utilities.d.ts +0 -52
  259. package/lib/id-compressor/utilities.d.ts.map +0 -1
  260. package/lib/id-compressor/utilities.js +0 -151
  261. package/lib/id-compressor/utilities.js.map +0 -1
  262. package/src/id-compressor/README.md +0 -3
  263. package/src/id-compressor/appendOnlySortedMap.ts +0 -366
  264. package/src/id-compressor/finalSpace.ts +0 -67
  265. package/src/id-compressor/idCompressor.ts +0 -630
  266. package/src/id-compressor/identifiers.ts +0 -42
  267. package/src/id-compressor/index.ts +0 -26
  268. package/src/id-compressor/persistanceUtilities.ts +0 -58
  269. package/src/id-compressor/sessionSpaceNormalizer.ts +0 -83
  270. package/src/id-compressor/sessions.ts +0 -405
  271. package/src/id-compressor/utilities.ts +0 -190
@@ -14,7 +14,6 @@ import {
14
14
  import { RuntimeHeaderData } from "../containerRuntime";
15
15
  import { ICreateContainerMetadata } from "../summary";
16
16
  import {
17
- disableSweepLogKey,
18
17
  GCNodeType,
19
18
  UnreferencedState,
20
19
  IGarbageCollectorConfigs,
@@ -143,6 +142,21 @@ export class GCTelemetryTracker {
143
142
 
144
143
  const nodeStateTracker = this.getNodeStateTracker(nodeUsageProps.id);
145
144
  const nodeType = this.getNodeType(nodeUsageProps.id);
145
+ const timeout = (() => {
146
+ switch (nodeStateTracker?.state) {
147
+ case UnreferencedState.Inactive:
148
+ return this.configs.inactiveTimeoutMs;
149
+ case UnreferencedState.TombstoneReady:
150
+ return this.configs.sweepTimeoutMs;
151
+ case UnreferencedState.SweepReady:
152
+ return (
153
+ this.configs.sweepTimeoutMs &&
154
+ this.configs.sweepTimeoutMs + this.configs.sweepGracePeriodMs
155
+ );
156
+ default:
157
+ return undefined;
158
+ }
159
+ })();
146
160
  const {
147
161
  usageType,
148
162
  currentReferenceTimestampMs,
@@ -160,10 +174,7 @@ export class GCTelemetryTracker {
160
174
  ? nodeUsageProps.currentReferenceTimestampMs -
161
175
  nodeStateTracker.unreferencedTimestampMs
162
176
  : -1,
163
- timeout:
164
- nodeStateTracker?.state === UnreferencedState.Inactive
165
- ? this.configs.inactiveTimeoutMs
166
- : this.configs.sweepTimeoutMs,
177
+ timeout,
167
178
  ...tagCodeArtifacts({ id: untaggedId, fromId: untaggedFromId }),
168
179
  ...propsToLog,
169
180
  ...this.createContainerMetadata,
@@ -392,58 +403,6 @@ export class GCTelemetryTracker {
392
403
  }
393
404
  this.pendingEventsQueue = [];
394
405
  }
395
-
396
- /**
397
- * For nodes that are ready to sweep, log an event for now. Until we start running sweep which deletes objects,
398
- * this will give us a view into how much deleted content a container has.
399
- */
400
- public logSweepEvents(
401
- logger: ITelemetryLoggerExt,
402
- currentReferenceTimestampMs: number,
403
- unreferencedNodesState: Map<string, UnreferencedStateTracker>,
404
- completedGCRuns: number,
405
- lastSummaryTime?: number,
406
- ) {
407
- if (
408
- this.mc.config.getBoolean(disableSweepLogKey) === true ||
409
- this.configs.sweepTimeoutMs === undefined
410
- ) {
411
- return;
412
- }
413
-
414
- const deletedNodeIds: string[] = [];
415
- for (const [nodeId, nodeStateTracker] of unreferencedNodesState) {
416
- if (nodeStateTracker.state !== UnreferencedState.SweepReady) {
417
- return;
418
- }
419
-
420
- const nodeType = this.getNodeType(nodeId);
421
- if (nodeType !== GCNodeType.DataStore && nodeType !== GCNodeType.Blob) {
422
- return;
423
- }
424
-
425
- // Log deleted event for each node only once to reduce noise in telemetry.
426
- const uniqueEventId = `Deleted-${nodeId}`;
427
- if (this.loggedUnreferencedEvents.has(uniqueEventId)) {
428
- return;
429
- }
430
- this.loggedUnreferencedEvents.add(uniqueEventId);
431
- deletedNodeIds.push(nodeId);
432
- }
433
-
434
- if (deletedNodeIds.length > 0) {
435
- logger.sendTelemetryEvent({
436
- eventName: "GC_SweepReadyObjects_Delete",
437
- details: JSON.stringify({
438
- timeout: this.configs.sweepTimeoutMs,
439
- completedGCRuns,
440
- lastSummaryTime,
441
- ...this.createContainerMetadata,
442
- }),
443
- ...tagCodeArtifacts({ id: JSON.stringify(deletedNodeIds) }),
444
- });
445
- }
446
- }
447
406
  }
448
407
 
449
408
  /**
@@ -4,6 +4,7 @@
4
4
  */
5
5
 
6
6
  import { assert, Timer } from "@fluidframework/core-utils";
7
+ import { validatePrecondition } from "@fluidframework/telemetry-utils";
7
8
  import { UnreferencedState } from "./gcDefinitions";
8
9
 
9
10
  /** A wrapper around common-utils Timer that requires the timeout when calling start/restart */
@@ -26,7 +27,7 @@ class TimerWithNoDefaultTimeout extends Timer {
26
27
 
27
28
  /**
28
29
  * Helper class that tracks the state of an unreferenced node such as the time it was unreferenced and if it can
29
- * be deleted by the sweep phase.
30
+ * be tombstoned or deleted by the sweep phase.
30
31
  */
31
32
  export class UnreferencedStateTracker {
32
33
  private _state: UnreferencedState = UnreferencedState.Active;
@@ -36,6 +37,8 @@ export class UnreferencedStateTracker {
36
37
 
37
38
  /** Timer to indicate when an unreferenced object is considered Inactive */
38
39
  private readonly inactiveTimer: TimerWithNoDefaultTimeout;
40
+ /** Timer to indicate when an unreferenced object is Tombstone-Ready */
41
+ private readonly tombstoneTimer: TimerWithNoDefaultTimeout;
39
42
  /** Timer to indicate when an unreferenced object is Sweep-Ready */
40
43
  private readonly sweepTimer: TimerWithNoDefaultTimeout;
41
44
 
@@ -45,32 +48,49 @@ export class UnreferencedStateTracker {
45
48
  private readonly inactiveTimeoutMs: number,
46
49
  /** The current reference timestamp used to track how long this node has been unreferenced for. */
47
50
  currentReferenceTimestampMs: number,
48
- /** The time after which node transitions to SweepReady state; undefined if session expiry is disabled. */
49
- private readonly sweepTimeoutMs: number | undefined,
51
+ /** The time after which node transitions to TombstoneReady state; undefined if session expiry is disabled. */
52
+ private readonly tombstoneTimeoutMs: number | undefined,
53
+ /** The delay from TombstoneReady to SweepReady (only applies if tombstoneTimeoutMs is defined) */
54
+ private readonly sweepGracePeriodMs: number,
50
55
  ) {
51
- if (this.sweepTimeoutMs !== undefined) {
52
- assert(
53
- this.inactiveTimeoutMs <= this.sweepTimeoutMs,
54
- 0x3b0 /* inactive timeout must not be greater than the sweep timeout */,
55
- );
56
- }
56
+ validatePrecondition(
57
+ this.tombstoneTimeoutMs === undefined ||
58
+ this.tombstoneTimeoutMs >= this.inactiveTimeoutMs,
59
+ "inactiveTimeoutMs must not be greater than the tombstoneTimeoutMs",
60
+ );
57
61
 
58
62
  this.sweepTimer = new TimerWithNoDefaultTimeout(() => {
59
63
  this._state = UnreferencedState.SweepReady;
60
64
  assert(
61
- !this.inactiveTimer.hasTimer,
62
- 0x3b1 /* inactiveTimer still running after sweepTimer fired! */,
65
+ !this.inactiveTimer.hasTimer && !this.tombstoneTimer.hasTimer,
66
+ 0x863 /* inactiveTimer or tombstoneTimer still running after sweepTimer fired! */,
63
67
  );
64
68
  });
65
69
 
70
+ this.tombstoneTimer = new TimerWithNoDefaultTimeout(() => {
71
+ this._state = UnreferencedState.TombstoneReady;
72
+ assert(
73
+ !this.inactiveTimer.hasTimer,
74
+ 0x864 /* inactiveTimer still running after tombstoneTimer fired! */,
75
+ ); // aka 0x3b1
76
+
77
+ if (this.sweepGracePeriodMs > 0) {
78
+ // After the node becomes tombstone ready, start the sweep timer after which the node will be ready for sweep.
79
+ this.sweepTimer.restart(this.sweepGracePeriodMs);
80
+ } else {
81
+ this._state = UnreferencedState.SweepReady;
82
+ }
83
+ });
84
+
66
85
  this.inactiveTimer = new TimerWithNoDefaultTimeout(() => {
67
86
  this._state = UnreferencedState.Inactive;
68
87
 
69
- // After the node becomes inactive, start the sweep timer after which the node will be ready for sweep.
70
- if (this.sweepTimeoutMs !== undefined) {
71
- this.sweepTimer.restart(this.sweepTimeoutMs - this.inactiveTimeoutMs);
88
+ // After the node becomes inactive, start the tombstone timer after which the node will be ready for tombstone.
89
+ if (this.tombstoneTimeoutMs !== undefined) {
90
+ this.tombstoneTimer.restart(this.tombstoneTimeoutMs - this.inactiveTimeoutMs);
72
91
  }
73
92
  });
93
+
74
94
  this.updateTracking(currentReferenceTimestampMs);
75
95
  }
76
96
 
@@ -78,21 +98,39 @@ export class UnreferencedStateTracker {
78
98
  public updateTracking(currentReferenceTimestampMs: number) {
79
99
  const unreferencedDurationMs = currentReferenceTimestampMs - this.unreferencedTimestampMs;
80
100
 
81
- // If the node has been unreferenced for sweep timeout amount of time, update the state to SweepReady.
82
- if (this.sweepTimeoutMs !== undefined && unreferencedDurationMs >= this.sweepTimeoutMs) {
101
+ // Below we will set the appropriate timer (or none). Any running timers are superceded by the new currentReferenceTimestampMs
102
+ this.clearTimers();
103
+
104
+ // If the node has been unreferenced long enough, update the state to SweepReady.
105
+ if (
106
+ this.tombstoneTimeoutMs !== undefined &&
107
+ unreferencedDurationMs >= this.tombstoneTimeoutMs + this.sweepGracePeriodMs
108
+ ) {
83
109
  this._state = UnreferencedState.SweepReady;
84
- this.clearTimers();
85
110
  return;
86
111
  }
87
112
 
88
- // If the node has been unreferenced for inactive timeoutMs amount of time, update the state to inactive.
89
- // Also, start a timer for the sweep timeout.
113
+ // If the node has been unreferenced long enough, update the state to TombstoneReady.
114
+ // Also, start a timer for the remainder of the sweep delay.
115
+ if (
116
+ this.tombstoneTimeoutMs !== undefined &&
117
+ unreferencedDurationMs >= this.tombstoneTimeoutMs
118
+ ) {
119
+ this._state = UnreferencedState.TombstoneReady;
120
+
121
+ this.sweepTimer.restart(
122
+ this.tombstoneTimeoutMs + this.sweepGracePeriodMs - unreferencedDurationMs,
123
+ );
124
+ return;
125
+ }
126
+
127
+ // If the node has been unreferenced for long enough, update the state to inactive.
128
+ // Also, start a timer for the remainder of the tombstone timeout.
90
129
  if (unreferencedDurationMs >= this.inactiveTimeoutMs) {
91
130
  this._state = UnreferencedState.Inactive;
92
- this.inactiveTimer.clear();
93
131
 
94
- if (this.sweepTimeoutMs !== undefined) {
95
- this.sweepTimer.restart(this.sweepTimeoutMs - unreferencedDurationMs);
132
+ if (this.tombstoneTimeoutMs !== undefined) {
133
+ this.tombstoneTimer.restart(this.tombstoneTimeoutMs - unreferencedDurationMs);
96
134
  }
97
135
  return;
98
136
  }
@@ -103,6 +141,7 @@ export class UnreferencedStateTracker {
103
141
 
104
142
  private clearTimers() {
105
143
  this.inactiveTimer.clear();
144
+ this.tombstoneTimer.clear();
106
145
  this.sweepTimer.clear();
107
146
  }
108
147
 
package/src/gc/index.ts CHANGED
@@ -7,13 +7,12 @@ export { GarbageCollector } from "./garbageCollection";
7
7
  export {
8
8
  nextGCVersion,
9
9
  defaultInactiveTimeoutMs,
10
+ defaultSweepGracePeriodMs,
10
11
  defaultSessionExpiryDurationMs,
11
- disableSweepLogKey,
12
12
  GCNodeType,
13
13
  gcTestModeKey,
14
- gcTombstoneGenerationOptionName,
15
- gcThrowOnTombstoneLoadOptionName,
16
- gcSweepGenerationOptionName,
14
+ gcDisableThrowOnTombstoneLoadOptionName,
15
+ gcGenerationOptionName,
17
16
  GCFeatureMatrix,
18
17
  GCVersion,
19
18
  gcVersionUpgradeToV4Key,
@@ -24,6 +23,8 @@ export {
24
23
  IGCMetadata,
25
24
  IGCResult,
26
25
  IGCRuntimeOptions,
26
+ IMarkPhaseStats,
27
+ ISweepPhaseStats,
27
28
  IGCStats,
28
29
  oneDayMs,
29
30
  runGCKey,
@@ -34,6 +35,7 @@ export {
34
35
  disableDatastoreSweepKey,
35
36
  UnreferencedState,
36
37
  throwOnTombstoneLoadOverrideKey,
38
+ GarbageCollectionMessage,
37
39
  } from "./gcDefinitions";
38
40
  export {
39
41
  cloneGCData,
package/src/index.ts CHANGED
@@ -23,7 +23,6 @@ export {
23
23
  DefaultSummaryConfiguration,
24
24
  ICompressionRuntimeOptions,
25
25
  CompressionAlgorithms,
26
- TEST_requestSummarizer,
27
26
  } from "./containerRuntime";
28
27
  export {
29
28
  ContainerMessageType,
@@ -40,6 +39,8 @@ export {
40
39
  GCFeatureMatrix,
41
40
  GCVersion,
42
41
  IGCRuntimeOptions,
42
+ IMarkPhaseStats,
43
+ ISweepPhaseStats,
43
44
  IGCStats,
44
45
  } from "./gc";
45
46
  export {
@@ -91,5 +92,21 @@ export {
91
92
  IRetriableFailureResult,
92
93
  ISummarizeEventProps,
93
94
  } from "./summary";
94
- export { isStableId, generateStableId, assertIsStableId } from "./id-compressor";
95
95
  export { IChunkedOp, unpackRuntimeMessage } from "./opLifecycle";
96
+
97
+ // Re-exports for backwards compatibility.
98
+ // Will be removed in the future.
99
+ export {
100
+ /**
101
+ * @deprecated Import from `@fluidframework/id-compressor` instead.
102
+ */
103
+ assertIsStableId,
104
+ /**
105
+ * @deprecated Import from `@fluidframework/id-compressor` instead.
106
+ */
107
+ generateStableId,
108
+ /**
109
+ * @deprecated Import from `@fluidframework/id-compressor` instead.
110
+ */
111
+ isStableId,
112
+ } from "@fluidframework/id-compressor";
@@ -8,13 +8,14 @@ import {
8
8
  IEnvelope,
9
9
  InboundAttachMessage,
10
10
  IAttachMessage,
11
- IdCreationRange,
12
11
  } from "@fluidframework/runtime-definitions";
12
+ import type { IdCreationRange } from "@fluidframework/id-compressor";
13
13
  import { IDataStoreAliasMessage } from "./dataStore";
14
+ import { GarbageCollectionMessage } from "./gc";
14
15
  import { IChunkedOp } from "./opLifecycle";
15
16
 
16
17
  /**
17
- * @public
18
+ * @internal
18
19
  */
19
20
  export enum ContainerMessageType {
20
21
  // An op to be delivered to store
@@ -41,6 +42,12 @@ export enum ContainerMessageType {
41
42
  * See the [IdCompressor README](./id-compressor/README.md) for more details.
42
43
  */
43
44
  IdAllocation = "idAllocation",
45
+
46
+ /**
47
+ * Garbage collection specific op. This is sent by the summarizer client when GC runs. It's used to synchronize GC
48
+ * state across all clients.
49
+ */
50
+ GC = "GC",
44
51
  }
45
52
 
46
53
  /**
@@ -71,7 +78,8 @@ export interface IContainerRuntimeMessageCompatDetails {
71
78
  * IMPORTANT: when creating one to be serialized, set the properties in the order they appear here.
72
79
  * This way stringified values can be compared.
73
80
  */
74
- interface TypedContainerRuntimeMessage<TType extends ContainerMessageType, TContents> {
81
+ interface TypedContainerRuntimeMessage<TType extends ContainerMessageType, TContents>
82
+ extends Partial<RecentlyAddedContainerRuntimeMessageDetails> {
75
83
  /** Type of the op, within the ContainerRuntime's domain */
76
84
  type: TType;
77
85
  /** Domain-specific contents, interpreted according to the type */
@@ -119,6 +127,10 @@ export type ContainerRuntimeIdAllocationMessage = TypedContainerRuntimeMessage<
119
127
  ContainerMessageType.IdAllocation,
120
128
  IdCreationRange
121
129
  >;
130
+ export type ContainerRuntimeGCMessage = TypedContainerRuntimeMessage<
131
+ ContainerMessageType.GC,
132
+ GarbageCollectionMessage
133
+ >;
122
134
 
123
135
  /**
124
136
  * Represents an unrecognized {@link TypedContainerRuntimeMessage}, e.g. a message from a future version of the container runtime.
@@ -147,6 +159,7 @@ export type InboundContainerRuntimeMessage =
147
159
  | ContainerRuntimeRejoinMessage
148
160
  | ContainerRuntimeAliasMessage
149
161
  | ContainerRuntimeIdAllocationMessage
162
+ | ContainerRuntimeGCMessage
150
163
  // Inbound messages may include unknown types from other clients, so we include that as a special case here
151
164
  | UnknownContainerRuntimeMessage;
152
165
 
@@ -159,6 +172,7 @@ export type LocalContainerRuntimeMessage =
159
172
  | ContainerRuntimeRejoinMessage
160
173
  | ContainerRuntimeAliasMessage
161
174
  | ContainerRuntimeIdAllocationMessage
175
+ | ContainerRuntimeGCMessage
162
176
  // In rare cases (e.g. related to stashed ops) we could have a local message of an unknown type
163
177
  | UnknownContainerRuntimeMessage;
164
178
 
@@ -170,7 +184,8 @@ export type OutboundContainerRuntimeMessage =
170
184
  | ContainerRuntimeBlobAttachMessage
171
185
  | ContainerRuntimeRejoinMessage
172
186
  | ContainerRuntimeAliasMessage
173
- | ContainerRuntimeIdAllocationMessage;
187
+ | ContainerRuntimeIdAllocationMessage
188
+ | ContainerRuntimeGCMessage;
174
189
 
175
190
  /**
176
191
  * An unpacked ISequencedDocumentMessage with the inner TypedContainerRuntimeMessage type/contents/etc
@@ -53,7 +53,7 @@ export interface IBatchCheckpoint {
53
53
  }
54
54
 
55
55
  /**
56
- * @public
56
+ * @internal
57
57
  */
58
58
  export interface IChunkedOp {
59
59
  chunkId: number;
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/container-runtime";
9
- export const pkgVersion = "2.0.0-internal.7.3.0";
9
+ export const pkgVersion = "2.0.0-internal.8.0.0";
@@ -331,6 +331,7 @@ export class PendingStateManager implements IDisposable {
331
331
  /**
332
332
  * Called when the Container's connection state changes. If the Container gets connected, it replays all the pending
333
333
  * states in its queue. This includes triggering resubmission of unacked ops.
334
+ * ! Note: successfully resubmitting an op that has been successfully sequenced is not possible due to checks in the ConnectionStateHandler (Loader layer)
334
335
  */
335
336
  public replayPendingStates() {
336
337
  assert(
@@ -227,7 +227,7 @@ export interface IOrderedClientElectionEvents extends IEvent {
227
227
 
228
228
  /**
229
229
  * Serialized state of IOrderedClientElection.
230
- * @public
230
+ * @alpha
231
231
  */
232
232
  export interface ISerializedElection {
233
233
  /** Sequence number at the time of the latest election. */
@@ -12,7 +12,7 @@ import {
12
12
 
13
13
  /**
14
14
  * Similar to AbortController, but using promise instead of events
15
- * @public
15
+ * @internal
16
16
  */
17
17
  export interface ICancellableSummarizerController extends ISummaryCancellationToken {
18
18
  stop(reason: SummarizerStopReason): void;
@@ -21,7 +21,7 @@ export interface ICancellableSummarizerController extends ISummaryCancellationTo
21
21
  /**
22
22
  * Can be useful in testing as well as in places where caller does not use cancellation.
23
23
  * This object implements ISummaryCancellationToken interface but cancellation is never leveraged.
24
- * @public
24
+ * @internal
25
25
  */
26
26
  export const neverCancelledSummaryToken: ISummaryCancellationToken = {
27
27
  cancelled: false,
@@ -13,13 +13,9 @@ import {
13
13
  UsageError,
14
14
  wrapErrorAndLog,
15
15
  } from "@fluidframework/telemetry-utils";
16
- import { ILoader, LoaderHeader } from "@fluidframework/container-definitions";
17
- import { DriverHeader } from "@fluidframework/driver-definitions";
18
- import { FluidObject, IFluidHandleContext, IRequest } from "@fluidframework/core-interfaces";
19
- import { responseToException } from "@fluidframework/runtime-utils";
16
+ import { IFluidHandleContext } from "@fluidframework/core-interfaces";
20
17
  import { ISummaryConfiguration } from "../containerRuntime";
21
18
  import { ICancellableSummarizerController } from "./runWhileConnectedCoordinator";
22
- import { summarizerClientType } from "./summarizerClientElection";
23
19
  import { SummaryCollection } from "./summaryCollection";
24
20
  import { RunningSummarizer } from "./runningSummarizer";
25
21
  import {
@@ -69,7 +65,7 @@ export const createSummarizingWarning = (errorMessage: string, logged: boolean)
69
65
  * Summarizer is responsible for coordinating when to generate and send summaries.
70
66
  * It is the main entry point for summary work.
71
67
  * It is created only by summarizing container (i.e. one with clientType === "summarizer")
72
- * @public
68
+ * @internal
73
69
  */
74
70
  export class Summarizer extends TypedEventEmitter<ISummarizerEvents> implements ISummarizer {
75
71
  public get ISummarizer() {
@@ -103,51 +99,6 @@ export class Summarizer extends TypedEventEmitter<ISummarizerEvents> implements
103
99
  this.logger = createChildLogger({ logger: this.runtime.logger, namespace: "Summarizer" });
104
100
  }
105
101
 
106
- /**
107
- * Creates a Summarizer and its underlying client.
108
- * Note that different implementations of ILoader will handle the URL differently.
109
- * ILoader provided by a ContainerRuntime is a RelativeLoader, which will treat URL's
110
- * starting with "/" as relative to the Container. The general ILoader
111
- * interface will expect an absolute URL and will not handle "/".
112
- * @param loader - the loader that resolves the request
113
- * @param url - the URL used to resolve the container
114
- * @deprecated Creating a summarizer is not a publicly supported API. Please remove all usage of this static method.
115
- */
116
- public static async create(loader: ILoader, url: string): Promise<ISummarizer> {
117
- const request: IRequest = {
118
- headers: {
119
- [LoaderHeader.cache]: false,
120
- [LoaderHeader.clientDetails]: {
121
- capabilities: { interactive: false },
122
- type: summarizerClientType,
123
- },
124
- [DriverHeader.summarizingClient]: true,
125
- [LoaderHeader.reconnect]: false,
126
- },
127
- url,
128
- };
129
-
130
- const resolvedContainer = await loader.resolve(request);
131
- let fluidObject: FluidObject<ISummarizer> | undefined;
132
-
133
- // Older containers may not have the "getEntryPoint" API
134
- // ! This check will need to stay until LTS of loader moves past 2.0.0-internal.7.0.0
135
- if (resolvedContainer.getEntryPoint !== undefined) {
136
- fluidObject = await resolvedContainer.getEntryPoint();
137
- } else {
138
- const response = await resolvedContainer.request({ url: "_summarizer" });
139
- if (response.status !== 200 || response.mimeType !== "fluid/object") {
140
- throw responseToException(response, request);
141
- }
142
- fluidObject = response.value;
143
- }
144
-
145
- if (fluidObject?.ISummarizer === undefined) {
146
- throw new UsageError("Fluid object does not implement ISummarizer");
147
- }
148
- return fluidObject.ISummarizer;
149
- }
150
-
151
102
  public async run(onBehalfOf: string): Promise<SummarizerStopReason> {
152
103
  try {
153
104
  return await this.runCore(onBehalfOf);