Skip to content
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

(compat) Added supported features and generation across the Loader / Runtime boundary #22877

Merged
merged 20 commits into from
Jan 24, 2025

Conversation

agarwal-navin
Copy link
Contributor

@agarwal-navin agarwal-navin commented Oct 22, 2024

Description

Added supportedFeatures and generationproperties to Runtime and Loader layer boundary. These will be used to validate that the layers are compatible.
These two properties along with pkgVersion are added to a ILayerCompatDetails interface. ContainterContext and ContainerRuntime implements this interface provider and uses the provider pattern to access it from the other object. The interface is internal and is not exposed since this in an internal implementation.
pkgVersion is includes in the error / warning logs to give additional context to users as to what the incompatible version combination is.
Also, added a ILayerCompatSupportRequirements interface that has properties that a layer requires other layer to be at to be compatible.

Supported features

  • Both the Runtime and Loader layers have a supportedFeatures property that includes a set of features that a layer supports. This is advertised to the other layer at the layer boundary.
  • Both the layers have a requiredFeatures array that includes a set of features that it requires the other layer to support in order to be compatible. Note that this is internal to that layer and is not advertised.
  • At runtime, each layer validates that all the entries in requiredFeatures is present in the supportedFeatures of the other layer. If not, it closes the container with a usage error that says layers are not compatible.
  • Any change that adds new behavior or changes existing behavior across a layer boundary must add an entry to the supported features set. For example, changes such as "move writing protocol tree to summary from Loader to Runtime" should add an entry to the supported features set.

Generation

  • In addition to supported features, a generation is also added to both the layers. This is advertised to the other layer at the layer boundary.
  • Generation is an integer which will be incremented every month. It will be used to validate compatibility more strictly (time-based) than supported features where layers are incompatible only if there are unsupported features.
    Note: The logic to update the generation will be added in a later PR. See AB#27054 for a proposed solution.
  • One key reason for adding generation is to have a clear cut off point where we officially stop supporting layer combinations. Our compat tests will test combinations up to this cut off point. The idea is that we test what we support and whatever we don't test should not be supported. This will help us achieve that.
  • Say that Runtime / Loader compatibility is N months. We can start throwing warnings when the layers are almost N-months apart saying that this combination is not supported. This will give applications an early signal that layers are about to be incompatible and they can take necessary steps. We can also choose to close the container if we decide to be strict about the layer combinations.
  • Both the layers have a minSupportedGeneration that it needs the other layer to be at. Note that this is internal to that layer and is not advertised.
  • At runtime, each layer validates that the generation of the other layer is >= minSupportedGeneration.
  • For example, say that the Runtime is at generation 20 and has a minSupportedGeneration of 8 for the Loader layer (12 month support window). If it sees that Loader's generation is lower than 8, the layers are incompatible.

Backwards compatibility

To support older layers before layer compat enforcement is introduced, the minSupportedGeneration is set to 0 whereas generation starts at 1. For older layers that did not implement ILayerCompatDetails, their generation is set to 0 and supported features is set to an empty set. So, their generation is compatible until we update the minSupportedGeneration.

AB#20805

@agarwal-navin agarwal-navin changed the title Added generation and supported features Added generation and supported features across the Loader / Runtime boundary Oct 22, 2024
@github-actions github-actions bot added area: loader Loader related issues area: runtime Runtime related issues public api change Changes to a public API base: main PRs targeted against main branch labels Oct 22, 2024
@agarwal-navin agarwal-navin changed the title Added generation and supported features across the Loader / Runtime boundary Prototype: Added generation and supported features across the Loader / Runtime boundary Oct 22, 2024
@agarwal-navin agarwal-navin marked this pull request as ready for review December 19, 2024 00:56
@Copilot Copilot bot review requested due to automatic review settings December 19, 2024 00:56
@agarwal-navin agarwal-navin requested a review from a team as a code owner December 19, 2024 00:56
@agarwal-navin agarwal-navin changed the title Prototype: Added generation and supported features across the Loader / Runtime boundary Added generation and supported features across the Loader / Runtime boundary Dec 19, 2024

Choose a reason for hiding this comment

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

Copilot reviewed 5 out of 14 changed files in this pull request and generated no comments.

Files not reviewed (9)
  • packages/runtime/container-runtime/package.json: Language not supported
  • packages/runtime/container-runtime/src/test/containerRuntime.spec.ts: Evaluated as low risk
  • packages/common/container-definitions/src/runtime.ts: Evaluated as low risk
  • packages/common/core-utils/src/index.ts: Evaluated as low risk
  • packages/common/core-utils/src/layerCompat.ts: Evaluated as low risk
  • packages/common/container-definitions/api-report/container-definitions.legacy.alpha.api.md: Evaluated as low risk
  • packages/runtime/container-runtime/src/test/types/validateContainerRuntimePrevious.generated.ts: Evaluated as low risk
  • packages/loader/container-loader/src/containerContext.ts: Evaluated as low risk
  • packages/runtime/container-runtime/api-report/container-runtime.legacy.alpha.api.md: Evaluated as low risk
Comments suppressed due to low confidence (1)

packages/loader/container-loader/src/container.ts:529

  • The new compatibility checks introduced in validateRuntimeCompatibility are not covered by tests. Please add unit tests to ensure this functionality works as intended.
private validateRuntimeCompatibility(
@markfields
Copy link
Member

a layer validates that its generation is greater than or equal to the minimum supported generation required by the other layer

I expected that each layer would take the other layer's generation and then decide if it suits it. This way it's always the newer layer that fails, rather than the older layer. As it is, you'll always be constrained by the older layer's understanding of the world. This is fine when everyone speak the same language, but if you ever want to change the semantics, it may prove inconvenient. If it's the newer client deciding compatibility, you can write new logic of any kind and it immediately takes effect. If it's the older, you have to keep playing by the older rules until the new logic saturates.

e.g. I'll be curious to see how you fail for clients who pre-date this stuff. I bet it won't be the older client who bails, because it doesn't know any better.

@anthony-murphy anthony-murphy self-assigned this Dec 23, 2024
@@ -163,6 +168,12 @@ const savedContainerEvent = "saved";

const packageNotFactoryError = "Code package does not implement IRuntimeFactory";

/**
* The current generation of the Loader. This is used to determine compatibility between other layers.
Copy link
Contributor

Choose a reason for hiding this comment

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

The current generation of the Loader. This is used to determine it's compatibility with other layers.

Copy link
Contributor

Choose a reason for hiding this comment

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

Consider adding recommendation in notes here on when and how this value should be updated.

@agarwal-navin agarwal-navin changed the title Added generation and supported features across the Loader / Runtime boundary Added supported features and generation across the Loader / Runtime boundary Jan 8, 2025

`supportedFeatures` is deprecated in `IContainerContext`

This was an optional property that was used internally to communicate features supported by the Loader layer to Runtime. This has been replaced with an internal only functionality.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
This was an optional property that was used internally to communicate features supported by the Loader layer to Runtime. This has been replaced with an internal only functionality.
This was an optional property that was used internally to communicate features supported by the Loader layer to Runtime. This has been replaced with an internal-only functionality.

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:
  170508 links
    1603 destination URLs
    1842 URLs ignored
       0 warnings
       0 errors


@agarwal-navin agarwal-navin merged commit 4c06412 into microsoft:main Jan 24, 2025
35 checks passed
@agarwal-navin agarwal-navin deleted the enforceLayerCompat branch January 24, 2025 00:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: loader Loader related issues area: runtime Runtime related issues base: main PRs targeted against main branch changeset-present public api change Changes to a public API
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants