Skip to content

feat(container-runtime): Add fail fast mechanism if runtime options don't align with minVersionForCollab #24625

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 27 commits into from
Jun 6, 2025

Conversation

scottn12
Copy link
Contributor

@scottn12 scottn12 commented May 14, 2025

Description

This PR adds a fail-fast mechanism to the container-runtime if the runtime options passed in by the user "contradict" the minVersionForCollab passed in. Notably, we will not perform the fail fast check if the user does not explicitly pass in minVersionForCollab.

For example, if the customer sets minVersionForCollab to "1.0.0" and also sets enableGroupedBatching to true, then we will throw the following error: Runtime option enableGroupedBatching:true is not compatible with minVersionForCollab: 1.0.0.. This is because batching is only supported for clients running 2.0 or later, but minVersionForCollab implies that 1.x clients can collaborate.

This PR also renames an internal function getConfigsForCompatMode -> getConfigsForMinVersionForCollab to match our new terminology.

runtimeOptionsAffectingDocSchemaValidationMap

In compatUtils.ts, I added runtimeOptionsAffectingDocSchemaValidationMap. This map is similar to runtimeOptionsAffectingDocSchemaConfigMap which accomplishes a slightly different goal. The original map is used to set the default configuration for a given minVersionForCollab. However, this does not reflect the version in which that option can be safely enabled. For example, we currently never enable ID Compressor by default, but it's safe to enable for 2.x clients. For the purpose of validating if a feature is compatible with a given verison, we would use the new runtimeOptionsAffectingDocSchemaValidationMap

Having two separate maps to maintain whenever we add a new runtime option is not ideal, so I'm open to alternatives.

Misc

AB#37810

@github-actions github-actions bot added area: runtime Runtime related issues base: main PRs targeted against main branch labels May 14, 2025
@github-actions github-actions bot added the area: tests Tests to add, test infrastructure improvements, etc label May 15, 2025
@github-actions github-actions bot added the area: framework Framework is a tag for issues involving the developer framework. Eg Aqueduct label May 15, 2025
@github-actions github-actions bot added the public api change Changes to a public API label May 15, 2025
Copy link
Contributor

🔗 No broken links found! ✅

Your attention to detail is admirable.

linkcheck output


> fluid-framework-docs-site@0.0.0 ci:check-links /home/runner/work/FluidFramework/FluidFramework/docs
> start-server-and-test "npm run serve -- --no-open" 3000 check-links

1: starting server using command "npm run serve -- --no-open"
and when url "[ 'http://127.0.0.1:3000' ]" is responding with HTTP status code 200
running tests using command "npm run check-links"


> fluid-framework-docs-site@0.0.0 serve
> docusaurus serve --no-open

[SUCCESS] Serving "build" directory at: http://localhost:3000/

> fluid-framework-docs-site@0.0.0 check-links
> linkcheck http://localhost:3000 --skip-file skipped-urls.txt

Crawling...

Stats:
  210260 links
    1663 destination URLs
    1895 URLs ignored
       0 warnings
       0 errors


@github-actions github-actions bot removed area: framework Framework is a tag for issues involving the developer framework. Eg Aqueduct public api change Changes to a public API labels May 15, 2025
@github-actions github-actions bot removed the area: tests Tests to add, test infrastructure improvements, etc label May 15, 2025
@scottn12 scottn12 changed the title improvement(container-runtime): Add fail fast mechanism if runtime options contradict minVersionForCollab feat(container-runtime): Add fail fast mechanism if runtime options contradict minVersionForCollab May 15, 2025
@scottn12 scottn12 changed the title feat(container-runtime): Add fail fast mechanism if runtime options contradict minVersionForCollab feat(container-runtime): Add fail fast mechanism if runtime options don't align with minVersionForCollab May 15, 2025
@scottn12 scottn12 marked this pull request as ready for review May 16, 2025 17:47
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR introduces a fail-fast mechanism to ensure that runtime options passed into the container-runtime are compatible with the specified minVersionForCollab. Key changes include:

  • Adding validation logic (validateRuntimeOptions/getValidationForRuntimeOptions) to throw errors when incompatible runtime options are used.
  • Renaming internal functions and updating tests to align with the new terminology.
  • Introducing a new runtime options validation map to distinguish between config defaults and safe option values.

Reviewed Changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
packages/runtime/container-runtime/src/test/containerRuntime.spec.ts Updated tests for fail-fast behavior and renamed test descriptions.
packages/runtime/container-runtime/src/test/compatUtils.spec.ts Renamed tests to reflect new function names and added tests for runtime options validation.
packages/runtime/container-runtime/src/containerRuntime.ts Integrated the new validateRuntimeOptions call into the container runtime load flow.
packages/runtime/container-runtime/src/compatUtils.ts Renamed functions, added runtime options validation logic, and updated config maps for validation.

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@scottn12 scottn12 requested review from Abe27342 and jason-ha May 22, 2025 13:47
Comment on lines 333 to 334
// If the value is an object, we need to check if it matches any of the keys in the map
// Collect all versions for which the config entry is a subset of the value object
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can expound on this - maybe it belongs in function @remarks.
There feels like there is something funny here. But expanded comment could help.
If not clear and all cases are currently exact matches, maybe we should start there?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated comments and names in the latest commit. Let me know if things still feel unclear

if (
typeof key === "object" &&
key !== undefined &&
Object.entries(key).every(([k, v]) => value[k] === v)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When can typeof key be "object" and key be undefined?
Also, if typeof key is not "object", then that feels like a serious issue, no? (value and map key types should be the same)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right that typeof key (now typeof possibleConfigValue) should always be an "object". It should also never be undefined, and that check was unecessary so I removed it. The compiler isn't able to infer that possibleConfigValue should always be an object though, so I added an assert

@scottn12 scottn12 requested a review from jason-ha May 22, 2025 20:30
@scottn12 scottn12 requested a review from Abe27342 June 5, 2025 03:18
@scottn12 scottn12 merged commit e2582f1 into microsoft:main Jun 6, 2025
35 checks passed
Copy link
Contributor

@jason-ha jason-ha left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure about the merging of the two... given the outstanding recommendation to change the pre-existing config to use version major setup.
I guess that would mean that you have a validation function for values that change when the version crosses the threshold. Then you start with the given version to get to the validator. (The validator at each version is good until there is one found at a more recent version.)

Comment on lines +4045 to +4056
for (const runtimeOption of [
{ enableGroupedBatching: true },
{ enableGroupedBatching: true, compressionOptions: enabledCompressionConfig },
{ explicitSchemaControl: true },
{ gcOptions: { enableGCSweep: true } },
// Adding in an arbitrary entry into the IGCRuntimeOptions object
{ gcOptions: { enableGCSweep: true, sweepGracePeriodMs: 1 } },
{ enableRuntimeIdCompressor: "on" },
{ enableRuntimeIdCompressor: "delayed" },
{ createBlobPayloadPending: true },
{ flushMode: FlushMode.TurnBased },
]) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the array have as const satisfies IContainerRuntimeOptionsInternal[] after it?
(Why is there an as unknown as cast below?)

});
});
}
it("does not throw if minVersionForCollab is not set and the default is incompatible with runtimeOptions", async () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When you say, "the default is incompatible with runtimeOptions", what is "the default"?
It feels like you need runtime option that would always trigger exception independent of the minVersionForCollab in order to actually test.
I think "the default" may mean the setup of default runtime options corresponding to 2.0.0-defaults. So, if not setting is the thing, then specifying 2.0.0-defaults for minVersionForCollab should throw. Having that as a test would make the "not set" case meaningful. If 2.0.0-defaults does not throw, then the test case should be for that explicitly and for "not set" (that uses the default set).

it("minVersionForCollab not provided, with manual configs for each property", async () => {
it("minVersionForCollab not provided, with manual configs", async () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pre-existing for most cases: what is being validated?
I don't know how to judge the test changes. Why is this test change good and/or needed for these runtime changes?
Dump of the test cases prior to this:

    Container Runtime
      Default Configurations
        ✔ minVersionForCollab not provided
        ✔ throws when minVersionForCollab = 0.50.0
        ✔ throws when minVersionForCollab = 100.0.0
        ✔ minVersionForCollab = 1.0.0
        ✔ minVersionForCollab = 2.0.0-defaults ("default")
        ✔ minVersionForCollab = 2.0.0 (explicit)
        ✔ minVersionForCollab = 2.20.0
        ✔ minVersionForCollab not provided, with manual configs for each property
        ✔ all options unspecified
        ✔ all options explicitly undefined
        ✔ minVersionForCollab = pkgVersion

tells us very little.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: runtime Runtime related issues base: main PRs targeted against main branch
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants