@fluidframework/container-runtime 2.0.0-internal.3.0.1 → 2.0.0-internal.3.0.3

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 (74) hide show
  1. package/dist/containerRuntime.d.ts +1 -1
  2. package/dist/containerRuntime.d.ts.map +1 -1
  3. package/dist/containerRuntime.js +58 -34
  4. package/dist/containerRuntime.js.map +1 -1
  5. package/dist/dataStoreContext.d.ts +12 -0
  6. package/dist/dataStoreContext.d.ts.map +1 -1
  7. package/dist/dataStoreContext.js +43 -5
  8. package/dist/dataStoreContext.js.map +1 -1
  9. package/dist/garbageCollection.d.ts +5 -4
  10. package/dist/garbageCollection.d.ts.map +1 -1
  11. package/dist/garbageCollection.js +15 -6
  12. package/dist/garbageCollection.js.map +1 -1
  13. package/dist/garbageCollectionConstants.d.ts +2 -0
  14. package/dist/garbageCollectionConstants.d.ts.map +1 -1
  15. package/dist/garbageCollectionConstants.js +3 -1
  16. package/dist/garbageCollectionConstants.js.map +1 -1
  17. package/dist/opLifecycle/opDecompressor.d.ts +4 -0
  18. package/dist/opLifecycle/opDecompressor.d.ts.map +1 -1
  19. package/dist/opLifecycle/opDecompressor.js +42 -3
  20. package/dist/opLifecycle/opDecompressor.js.map +1 -1
  21. package/dist/opLifecycle/outbox.d.ts.map +1 -1
  22. package/dist/opLifecycle/outbox.js +3 -2
  23. package/dist/opLifecycle/outbox.js.map +1 -1
  24. package/dist/packageVersion.d.ts +1 -1
  25. package/dist/packageVersion.js +1 -1
  26. package/dist/packageVersion.js.map +1 -1
  27. package/dist/summaryFormat.d.ts +19 -0
  28. package/dist/summaryFormat.d.ts.map +1 -1
  29. package/dist/summaryFormat.js.map +1 -1
  30. package/dist/summaryGenerator.d.ts.map +1 -1
  31. package/dist/summaryGenerator.js +1 -1
  32. package/dist/summaryGenerator.js.map +1 -1
  33. package/lib/containerRuntime.d.ts +1 -1
  34. package/lib/containerRuntime.d.ts.map +1 -1
  35. package/lib/containerRuntime.js +58 -34
  36. package/lib/containerRuntime.js.map +1 -1
  37. package/lib/dataStoreContext.d.ts +12 -0
  38. package/lib/dataStoreContext.d.ts.map +1 -1
  39. package/lib/dataStoreContext.js +45 -7
  40. package/lib/dataStoreContext.js.map +1 -1
  41. package/lib/garbageCollection.d.ts +5 -4
  42. package/lib/garbageCollection.d.ts.map +1 -1
  43. package/lib/garbageCollection.js +16 -7
  44. package/lib/garbageCollection.js.map +1 -1
  45. package/lib/garbageCollectionConstants.d.ts +2 -0
  46. package/lib/garbageCollectionConstants.d.ts.map +1 -1
  47. package/lib/garbageCollectionConstants.js +2 -0
  48. package/lib/garbageCollectionConstants.js.map +1 -1
  49. package/lib/opLifecycle/opDecompressor.d.ts +4 -0
  50. package/lib/opLifecycle/opDecompressor.d.ts.map +1 -1
  51. package/lib/opLifecycle/opDecompressor.js +42 -3
  52. package/lib/opLifecycle/opDecompressor.js.map +1 -1
  53. package/lib/opLifecycle/outbox.d.ts.map +1 -1
  54. package/lib/opLifecycle/outbox.js +3 -2
  55. package/lib/opLifecycle/outbox.js.map +1 -1
  56. package/lib/packageVersion.d.ts +1 -1
  57. package/lib/packageVersion.js +1 -1
  58. package/lib/packageVersion.js.map +1 -1
  59. package/lib/summaryFormat.d.ts +19 -0
  60. package/lib/summaryFormat.d.ts.map +1 -1
  61. package/lib/summaryFormat.js.map +1 -1
  62. package/lib/summaryGenerator.d.ts.map +1 -1
  63. package/lib/summaryGenerator.js +1 -1
  64. package/lib/summaryGenerator.js.map +1 -1
  65. package/package.json +19 -53
  66. package/src/containerRuntime.ts +99 -51
  67. package/src/dataStoreContext.ts +64 -5
  68. package/src/garbageCollection.ts +24 -9
  69. package/src/garbageCollectionConstants.ts +3 -0
  70. package/src/opLifecycle/opDecompressor.ts +49 -2
  71. package/src/opLifecycle/outbox.ts +3 -2
  72. package/src/packageVersion.ts +1 -1
  73. package/src/summaryFormat.ts +22 -0
  74. package/src/summaryGenerator.ts +9 -5
@@ -6,6 +6,8 @@
6
6
  import { decompress } from "lz4js";
7
7
  import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
8
8
  import { assert, IsoBuffer, Uint8ArrayToString } from "@fluidframework/common-utils";
9
+ import { ChildLogger } from "@fluidframework/telemetry-utils";
10
+ import { ITelemetryLogger } from "@fluidframework/common-definitions";
9
11
  import { CompressionAlgorithms } from "../containerRuntime";
10
12
  import { IMessageProcessingResult } from "./definitions";
11
13
 
@@ -21,13 +23,18 @@ export class OpDecompressor {
21
23
  private activeBatch = false;
22
24
  private rootMessageContents: any | undefined;
23
25
  private processedCount = 0;
26
+ private readonly logger;
27
+
28
+ constructor(logger: ITelemetryLogger) {
29
+ this.logger = ChildLogger.create(logger, "OpDecompressor");
30
+ }
24
31
 
25
32
  public processMessage(message: ISequencedDocumentMessage): IMessageProcessingResult {
26
33
  assert(
27
34
  message.compression === undefined || message.compression === CompressionAlgorithms.lz4,
28
35
  0x511 /* Only lz4 compression is supported */);
29
36
 
30
- if (message.metadata?.batch === true && message.compression === CompressionAlgorithms.lz4) {
37
+ if (message.metadata?.batch === true && this.isCompressed(message)) {
31
38
  // Beginning of a compressed batch
32
39
  assert(this.activeBatch === false, 0x4b8 /* shouldn't have multiple active batches */);
33
40
  if (message.compression) {
@@ -74,7 +81,7 @@ export class OpDecompressor {
74
81
  };
75
82
  }
76
83
 
77
- if (message.metadata?.batch === undefined && message.compression === CompressionAlgorithms.lz4) {
84
+ if (message.metadata?.batch === undefined && this.isCompressed(message)) {
78
85
  // Single compressed message
79
86
  assert(this.activeBatch === false, 0x4ba /* shouldn't receive compressed message in middle of a batch */);
80
87
 
@@ -94,6 +101,46 @@ export class OpDecompressor {
94
101
  state: "Skipped",
95
102
  };
96
103
  }
104
+
105
+ private isCompressed(message: ISequencedDocumentMessage) {
106
+ if (message.compression === CompressionAlgorithms.lz4) {
107
+ return true;
108
+ }
109
+
110
+ /**
111
+ * Back-compat self healing mechanism for ADO:3538, as loaders from
112
+ * version client_v2.0.0-internal.1.2.0 to client_v2.0.0-internal.2.2.0 do not
113
+ * support adding the proper compression metadata to compressed messages submitted
114
+ * by the runtime. Should be removed after the loader reaches sufficient saturation
115
+ * for a version greater or equal than client_v2.0.0-internal.2.2.0.
116
+ *
117
+ * The condition holds true for compressed messages, regardless of metadata. We are ultimately
118
+ * looking for a message with a single property `packedContents` inside `contents`, of type 'string'
119
+ * with a base64 encoded value.
120
+ */
121
+ try {
122
+ if (
123
+ typeof message.contents === "object" &&
124
+ Object.keys(message.contents).length === 1 &&
125
+ message.contents?.packedContents !== undefined &&
126
+ typeof message.contents?.packedContents === "string" &&
127
+ message.contents.packedContents.length > 0 &&
128
+ IsoBuffer.from(message.contents.packedContents, "base64").toString("base64") ===
129
+ message.contents.packedContents
130
+ ) {
131
+ this.logger.sendTelemetryEvent({
132
+ eventName: "LegacyCompression",
133
+ type: message.type,
134
+ batch: message.metadata?.batch,
135
+ });
136
+ return true;
137
+ }
138
+ } catch (err) {
139
+ return false;
140
+ }
141
+
142
+ return false;
143
+ }
97
144
  }
98
145
 
99
146
  // We should not be mutating the input message nor its metadata
@@ -114,8 +114,9 @@ export class Outbox {
114
114
  private compressBatch(batch: IBatch): IBatch {
115
115
  if (batch.content.length === 0
116
116
  || this.params.config.compressionOptions === undefined
117
- || this.params.config.compressionOptions.minimumBatchSizeInBytes > batch.contentSizeInBytes) {
118
- // Nothing to do if the batch is empty or if compression is disabled or if we don't need to compress
117
+ || this.params.config.compressionOptions.minimumBatchSizeInBytes > batch.contentSizeInBytes
118
+ || this.params.containerContext.submitBatchFn === undefined) {
119
+ // Nothing to do if the batch is empty or if compression is disabled or not supported, or if we don't need to compress
119
120
  return batch;
120
121
  }
121
122
 
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/container-runtime";
9
- export const pkgVersion = "2.0.0-internal.3.0.1";
9
+ export const pkgVersion = "2.0.0-internal.3.0.3";
@@ -89,15 +89,37 @@ export interface ICreateContainerMetadata {
89
89
  createContainerTimestamp?: number;
90
90
  }
91
91
 
92
+ /** @see IGCMetadata.gcFeatureMatrix */
93
+ export interface GCFeatureMatrix {
94
+ /**
95
+ * The Tombstone Generation value in effect when this file was created.
96
+ * Gives a way for an app to disqualify old files from GC Tombstone enforcement
97
+ * Provided via Container Runtime Options
98
+ */
99
+ tombstoneGeneration?: number;
100
+ }
101
+
92
102
  export type GCVersion = number;
93
103
  export interface IGCMetadata {
94
104
  /**
95
105
  * The version of the GC code that was run to generate the GC data that is written in the summary.
106
+ * If the persisted value doesn't match the current value in the code, saved GC data will be discarded and regenerated from scratch.
96
107
  * Also, used to determine whether GC is enabled for this container or not:
97
108
  * - A value of 0 or undefined means GC is disabled.
98
109
  * - A value greater than 0 means GC is enabled.
99
110
  */
100
111
  readonly gcFeature?: GCVersion;
112
+
113
+ /**
114
+ * Numerical indication of feature support as of file creation time, used to determine feature availability over time.
115
+ * This info may come from multiple sources (FF code, config service, app via Container Runtime Options),
116
+ * and pertains to aspects of the document that may be fixed for its lifetime.
117
+ *
118
+ * For each dimension, if the persisted value is less than the currently provided value,
119
+ * then this file does not support the corresponding feature as currently implemented.
120
+ */
121
+ readonly gcFeatureMatrix?: GCFeatureMatrix;
122
+
101
123
  /**
102
124
  * Tells whether the GC sweep phase is enabled for this container.
103
125
  * - True means sweep phase is enabled.
@@ -205,11 +205,15 @@ export class SummaryGenerator {
205
205
  timeSinceLastSummary,
206
206
  };
207
207
 
208
- const summarizeEvent = PerformanceEvent.start(logger, {
209
- eventName: "Summarize",
210
- refreshLatestAck,
211
- ...summarizeTelemetryProps,
212
- });
208
+ const summarizeEvent = PerformanceEvent.start(
209
+ logger,
210
+ {
211
+ eventName: "Summarize",
212
+ refreshLatestAck,
213
+ ...summarizeTelemetryProps,
214
+ },
215
+ { start: true, end: true, cancel: "generic" },
216
+ );
213
217
 
214
218
  // Helper functions to report failures and return.
215
219
  const getFailMessage =