Skip to content

Commit 45d6683

Browse files
ConfigMap related cleanup and refactors (#25868)
## Description This adjust several ConfigMap related internal APIs and behaviors, making the code more strict about input and outputs.
1 parent fa022b2 commit 45d6683

File tree

7 files changed

+304
-200
lines changed

7 files changed

+304
-200
lines changed

packages/runtime/container-runtime/src/containerCompatibility.ts

Lines changed: 97 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
import {
1111
configValueToMinVersionForCollab,
1212
getConfigsForMinVersionForCollab,
13-
getValidationForRuntimeOptions,
13+
validateConfigMapOverrides,
1414
type ConfigMap,
1515
type ConfigValidationMap,
1616
} from "@fluidframework/runtime-utils/internal";
@@ -101,60 +101,66 @@ export type RuntimeOptionKeysThatRequireExplicitSchemaControl = keyof Omit<
101101
* default value for `enableGroupedBatching` will be true because clients running 2.0 or later will be able to understand the format changes associated
102102
* with the batching feature.
103103
*/
104-
const runtimeOptionsAffectingDocSchemaConfigMap = {
105-
enableGroupedBatching: {
106-
"1.0.0": false,
107-
"2.0.0-defaults": true,
108-
},
109-
compressionOptions: {
110-
"1.0.0": disabledCompressionConfig,
111-
"2.0.0-defaults": enabledCompressionConfig,
112-
},
113-
enableRuntimeIdCompressor: {
114-
// For IdCompressorMode, `undefined` represents a logical state (off).
115-
// However, to satisfy the Required<> constraint while
116-
// `exactOptionalPropertyTypes` is `false` (TODO: AB#8215), we need
117-
// to have it defined, so we trick the type checker here.
118-
"1.0.0": undefined,
119-
// We do not yet want to enable idCompressor by default since it will
120-
// increase bundle sizes, and not all customers will benefit from it.
121-
// Therefore, we will require customers to explicitly enable it. We
122-
// are keeping it as a DocSchema affecting option for now as this may
123-
// change in the future.
124-
},
125-
explicitSchemaControl: {
126-
"1.0.0": false,
127-
// This option's intention is to prevent 1.x clients from joining sessions
128-
// when enabled. This is set to true when the minVersionForCollab is set
129-
// to >=2.0.0 (explicitly). This is different than other 2.0 defaults
130-
// because it was not enabled by default prior to the implementation of
131-
// `minVersionForCollab`.
132-
// `defaultMinVersionForCollab` is set to "2.0.0-defaults" which "2.0.0"
133-
// does not satisfy to avoiding enabling this option by default as of
134-
// `minVersionForCollab` introduction, which could be unexpected.
135-
// Only enable as a default when `minVersionForCollab` is specified at
136-
// 2.0.0+.
137-
"2.0.0": true,
138-
},
139-
flushMode: {
140-
// Note: 1.x clients are compatible with TurnBased flushing, but here we elect to remain on Immediate flush mode
141-
// as a work-around for inability to send batches larger than 1Mb. Immediate flushing keeps batches smaller as
142-
// fewer messages will be included per flush.
143-
"1.0.0": FlushMode.Immediate,
144-
"2.0.0-defaults": FlushMode.TurnBased,
145-
},
146-
gcOptions: {
147-
"1.0.0": {},
148-
// Although sweep is supported in 2.x, it is disabled by default until minVersionForCollab>=3.0.0 to be extra safe.
149-
"3.0.0": { enableGCSweep: true },
150-
},
151-
createBlobPayloadPending: {
152-
// This feature is new and disabled by default. In the future we will enable it by default, but we have not
153-
// closed on the version where that will happen yet. Probably a .10 release since blob functionality is not
154-
// exposed on the `@public` API surface.
155-
"1.0.0": undefined,
156-
},
157-
} as const satisfies ConfigMap<RuntimeOptionsAffectingDocSchema>;
104+
const runtimeOptionsAffectingDocSchemaConfigMap: ConfigMap<RuntimeOptionsAffectingDocSchema> =
105+
{
106+
enableGroupedBatching: {
107+
"1.0.0": false,
108+
"2.0.0-defaults": true,
109+
},
110+
compressionOptions: {
111+
"1.0.0": disabledCompressionConfig,
112+
"2.0.0-defaults": enabledCompressionConfig,
113+
},
114+
enableRuntimeIdCompressor: {
115+
// For IdCompressorMode, `undefined` represents a logical state (off).
116+
// However, to satisfy the Required<> constraint while
117+
// `exactOptionalPropertyTypes` is `false` (TODO: AB#8215), we need
118+
// to have it defined, so we trick the type checker here.
119+
"1.0.0": undefined,
120+
// We do not yet want to enable idCompressor by default since it will
121+
// increase bundle sizes, and not all customers will benefit from it.
122+
// Therefore, we will require customers to explicitly enable it. We
123+
// are keeping it as a DocSchema affecting option for now as this may
124+
// change in the future.
125+
},
126+
explicitSchemaControl: {
127+
"1.0.0": false,
128+
// This option's intention is to prevent 1.x clients from joining sessions
129+
// when enabled. This is set to true when the minVersionForCollab is set
130+
// to >=2.0.0 (explicitly). This is different than other 2.0 defaults
131+
// because it was not enabled by default prior to the implementation of
132+
// `minVersionForCollab`.
133+
// `defaultMinVersionForCollab` is set to "2.0.0-defaults" which "2.0.0"
134+
// does not satisfy to avoiding enabling this option by default as of
135+
// `minVersionForCollab` introduction, which could be unexpected.
136+
// Only enable as a default when `minVersionForCollab` is specified at
137+
// 2.0.0+.
138+
"2.0.0": true,
139+
},
140+
flushMode: {
141+
// Note: 1.x clients are compatible with TurnBased flushing, but here we elect to remain on Immediate flush mode
142+
// as a work-around for inability to send batches larger than 1Mb. Immediate flushing keeps batches smaller as
143+
// fewer messages will be included per flush.
144+
"1.0.0": FlushMode.Immediate,
145+
"2.0.0-defaults": FlushMode.TurnBased,
146+
},
147+
gcOptions: {
148+
"1.0.0": {},
149+
// Although sweep is supported in 2.x, it is disabled by default until minVersionForCollab>=3.0.0 to be extra safe.
150+
// Note that enabling this is a significant change, that should likely be announced in the relevant version:
151+
// It would be bad if this simple caused the enablement when when the current package version passed this point without anyone being aware.
152+
// This is configuration targeting a future versions, which is not supported.
153+
// TODO: when preparing 3.0 (or at some later point), consider enabling this by default for clients 3.0 or newer
154+
// (and add user facing documentation indicating this is enabled by that version).
155+
// "3.0.0": { enableGCSweep: true },
156+
},
157+
createBlobPayloadPending: {
158+
// This feature is new and disabled by default. In the future we will enable it by default, but we have not
159+
// closed on the version where that will happen yet. Probably a .10 release since blob functionality is not
160+
// exposed on the `@public` API surface.
161+
"1.0.0": undefined,
162+
},
163+
};
158164

159165
/**
160166
* Keys of {@link ContainerRuntimeOptionsInternal} that require explicitSchemaControl to be enabled.
@@ -169,37 +175,39 @@ export const runtimeOptionKeysThatRequireExplicitSchemaControl = (
169175
);
170176
}) as RuntimeOptionKeysThatRequireExplicitSchemaControl[];
171177

172-
const runtimeOptionsAffectingDocSchemaConfigValidationMap = {
173-
enableGroupedBatching: configValueToMinVersionForCollab([
174-
[false, "1.0.0"],
175-
[true, "2.0.0-defaults"],
176-
]),
177-
compressionOptions: configValueToMinVersionForCollab([
178-
[{ ...disabledCompressionConfig }, "1.0.0"],
179-
[{ ...enabledCompressionConfig }, "2.0.0-defaults"],
180-
]),
181-
enableRuntimeIdCompressor: configValueToMinVersionForCollab([
182-
[undefined, "1.0.0"],
183-
["on", "2.0.0-defaults"],
184-
["delayed", "2.0.0-defaults"],
185-
]),
186-
explicitSchemaControl: configValueToMinVersionForCollab([
187-
[false, "1.0.0"],
188-
[true, "2.0.0-defaults"],
189-
]),
190-
flushMode: configValueToMinVersionForCollab([
191-
[FlushMode.Immediate, "1.0.0"],
192-
[FlushMode.TurnBased, "2.0.0-defaults"],
193-
]),
194-
gcOptions: configValueToMinVersionForCollab([
195-
[{ enableGCSweep: undefined }, "1.0.0"],
196-
[{ enableGCSweep: true }, "2.0.0-defaults"],
197-
]),
198-
createBlobPayloadPending: configValueToMinVersionForCollab([
199-
[undefined, "1.0.0"],
200-
[true, "2.40.0"],
201-
]),
202-
} as const satisfies ConfigValidationMap<RuntimeOptionsAffectingDocSchema>;
178+
// A lot of the information in this seems redundant with whats defined above. Might be nice to combine them somehow.
179+
const runtimeOptionsAffectingDocSchemaConfigValidationMap: ConfigValidationMap<RuntimeOptionsAffectingDocSchema> =
180+
{
181+
enableGroupedBatching: configValueToMinVersionForCollab([
182+
[false, "1.0.0"],
183+
[true, "2.0.0-defaults"],
184+
]),
185+
compressionOptions: configValueToMinVersionForCollab([
186+
[{ ...disabledCompressionConfig }, "1.0.0"],
187+
[{ ...enabledCompressionConfig }, "2.0.0-defaults"],
188+
]),
189+
enableRuntimeIdCompressor: configValueToMinVersionForCollab([
190+
[undefined, "1.0.0"],
191+
["on", "2.0.0-defaults"],
192+
["delayed", "2.0.0-defaults"],
193+
]),
194+
explicitSchemaControl: configValueToMinVersionForCollab([
195+
[false, "1.0.0"],
196+
[true, "2.0.0-defaults"],
197+
]),
198+
flushMode: configValueToMinVersionForCollab([
199+
[FlushMode.Immediate, "1.0.0"],
200+
[FlushMode.TurnBased, "2.0.0-defaults"],
201+
]),
202+
gcOptions: configValueToMinVersionForCollab([
203+
[{ enableGCSweep: undefined }, "1.0.0"],
204+
[{ enableGCSweep: true }, "2.0.0-defaults"],
205+
]),
206+
createBlobPayloadPending: configValueToMinVersionForCollab([
207+
[undefined, "1.0.0"],
208+
[true, "2.40.0"],
209+
]),
210+
};
203211

204212
/**
205213
* Returns the default RuntimeOptionsAffectingDocSchema configuration for a given minVersionForCollab.
@@ -210,9 +218,7 @@ export function getMinVersionForCollabDefaults(
210218
return getConfigsForMinVersionForCollab(
211219
minVersionForCollab,
212220
runtimeOptionsAffectingDocSchemaConfigMap,
213-
// This is a bad cast away from Partial that getConfigsForCompatMode provides.
214-
// ConfigMap should be restructured to provide RuntimeOptionsAffectingDocSchema guarantee.
215-
) as RuntimeOptionsAffectingDocSchema;
221+
);
216222
}
217223

218224
/**
@@ -224,9 +230,9 @@ export function validateRuntimeOptions(
224230
minVersionForCollab: MinimumVersionForCollab,
225231
runtimeOptions: Partial<ContainerRuntimeOptionsInternal>,
226232
): void {
227-
getValidationForRuntimeOptions<RuntimeOptionsAffectingDocSchema>(
233+
validateConfigMapOverrides<RuntimeOptionsAffectingDocSchema>(
228234
minVersionForCollab,
229-
runtimeOptions as Partial<RuntimeOptionsAffectingDocSchema>,
235+
runtimeOptions,
230236
runtimeOptionsAffectingDocSchemaConfigValidationMap,
231237
);
232238
}

packages/runtime/container-runtime/src/containerRuntime.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ import {
143143
isValidMinVersionForCollab,
144144
RequestParser,
145145
RuntimeHeaders,
146-
semanticVersionToMinimumVersionForCollab,
146+
validateMinimumVersionForCollab,
147147
seqFromTree,
148148
TelemetryContext,
149149
} from "@fluidframework/runtime-utils/internal";
@@ -1219,6 +1219,7 @@ export class ContainerRuntime
12191219
createBlobPayloadPending,
12201220
};
12211221

1222+
validateMinimumVersionForCollab(updatedMinVersionForCollab);
12221223
const runtime = new containerRuntimeCtor(
12231224
context,
12241225
registry,
@@ -1236,7 +1237,7 @@ export class ContainerRuntime
12361237
documentSchemaController,
12371238
featureGatesForTelemetry,
12381239
provideEntryPoint,
1239-
semanticVersionToMinimumVersionForCollab(updatedMinVersionForCollab),
1240+
updatedMinVersionForCollab,
12401241
requestHandler,
12411242
undefined, // summaryConfiguration
12421243
recentBatchInfo,

packages/runtime/container-runtime/src/summary/documentSchema.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,10 @@ export interface IDocumentSchemaInfo {
107107
* See {@link @fluidframework/container-runtime#LoadContainerRuntimeParams} for additional details on `minVersionForCollab`.
108108
*
109109
* @remarks
110-
* We use `SemanticVersion` instead of `MinimumVersionForCollab` since we may open future documents that with a
110+
* We use `SemanticVersion` instead of `MinimumVersionForCollab` since we may open future documents with a
111111
* minVersionForCollab version that `MinimumVersionForCollab` does not support.
112+
* Note that in such a case (where minVersionForCollab is not a valid `MinimumVersionForCollab`),
113+
* loading the document might not work since this version of the runtime may not support it.
112114
*/
113115
minVersionForCollab: SemanticVersion;
114116
}

packages/runtime/runtime-definitions/src/compatibilityDefinitions.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@
1212
*
1313
* Must be at least {@link @fluidframework/runtime-utils#lowestMinVersionForCollab} and cannot exceed the current version.
1414
*
15+
* {@link @fluidframework/runtime-utils#validateMinimumVersionForCollab} can be used to check these invariants at runtime.
16+
* Since TypeScript cannot enforce them all for literals in code,
17+
* it may be useful to use `validateMinimumVersionForCollab` values which may come from constants in the codebase typed as a `MinimumVersionForCollab`.
18+
*
1519
* @privateRemarks
1620
* Since this uses the semver notion of "greater" (which might not actually mean a later release, or supporting more features), care must be taken with how this is used.
1721
* See remarks for {@link @fluidframework/runtime-utils#MinimumMinorSemanticVersion} for more details.

0 commit comments

Comments
 (0)