-
Notifications
You must be signed in to change notification settings - Fork 334
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
App-configurable compatibility options spec: CompatibilityOptions #4966
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,220 @@ | ||
App-configurable compatibility options | ||
=== | ||
|
||
# Background | ||
|
||
_This spec adds a CompatibilityOptions class to control behavior of servicing changes._ | ||
|
||
Apps using Windows App SDK have two choices today: use Windows App SDK as an | ||
automatically-updating framework package or use Windows App SDK in self-contained mode with no | ||
automatic updates. Apps which use the framework package automatically get fixes, which is great, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's not 'automatic updates' but WHO does the servicing. MSIX packages routinely get serviced by Microsoft and others (whoever gets an update to the PC first) vs self-contained copies are serviced by the app/developer. Apps using non-MSIX technologies may perform automatic updates of their dependencies, but it's entirely dependent on the app developer on when (or even if) to do so. SUGGESTION: ...in self-contained mode updated only if/when the containing application/publisher decides to update its copy of Windows App SDK. (or words to that effect) |
||
but they have a chance of being broken by a bug or subtle behavior change in a servicing update. | ||
Some apps choose self-contained mode to avoid that risk of an automatic servicing update breaking | ||
them. But even when apps choose self-contained mode, they may find that they can't update to a | ||
newer servicing release due to a bug or behavior change. Also, self-contained apps can't use | ||
features which require shared services, such as some Notification features delivered via the | ||
Singleton package. | ||
|
||
App-configurable compatibility is intended to prevent these problems, enabling apps to choose to | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 'App-configurable compatibility' - seems to be the catchy term for this feature. API naming should match? |
||
use the framework package with confidence they won't be broken. Also, apps which find a | ||
compatibility problem in a servicing release will still be able to move forward by temporarily | ||
disabling problematic changes. Even apps using self-contained can update to a new package with | ||
confidence that app-configurable compatibility will ensure a successful update. | ||
|
||
A new `CompatibilityOptions` class has APIs to control the behavior of servicing changes. | ||
There are also properties which can be set in the app's project file to automatically use the new | ||
APIs with the specified values. | ||
|
||
# API Pages | ||
|
||
## CompatibilityOptions class | ||
|
||
Configures which changes in Windows App SDK servicing releases are enabled. By default, all | ||
changes are enabled, but `CompatibilityOptions` can be used to lock the runtime behavior to a | ||
specified patch version or to disable specific changes: | ||
|
||
1. **Choose the patch version:** You can specify which servicing patch version's behavior you | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
API and XML refer to "patch mode". Different phrasing for same thing or there's a meaningful difference in the lingo? If same then please use consistent terminology. If not then please define "patch version" and "patch mode" so it's clear how they differ |
||
want to use. For example, your app can specify that it wants the 1.7.2 version behavior, which | ||
will have Windows App SDK run in that mode even if 1.7.3 or later is installed. This capability | ||
allows you to control when your app gets new fixes or behavior changes, even when not using | ||
self-contained mode. | ||
2. **Temporarily disable specific changes:** If your app encounters a problem with a specific | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
These changes are the developer's request or hint that, as you note, may not be disableable in time. But isn't that the same for patch version/mode? If I specify patch version = 1.7.2 and eventually update to use 1.8 isn't my previous 1.7 request irrelevant? The intent is "disable" means "disable...the things allowed to be disabled", which could change on each build (formerly disableable now aren't)? Hence the 'temporary'? Or no, once a 'disable' knob is present in a major.minor it will be supported disable-able forever in that major.minor? SUGGESTION: Remove 'Temporarily' |
||
change in a servicing update, you can disable just that change while still benefiting from the | ||
other changes or features in that update. (All changes are enabled by default for the patch | ||
version in use.) Disabling a change is a temporary measure which gives time for a fix to be | ||
released in a future Windows App SDK update or for you to implement an update in your app. | ||
|
||
Here's an example of using `CompatibilityOptions` to specify a patch version and disable a | ||
specific change: | ||
|
||
```c# | ||
void ApplyCompatibilityOptions() | ||
{ | ||
var compatibilityOptions = new CompatibilityOptions(); | ||
compatibilityOptions.PatchMode1 = new WindowsAppRuntimeVersion(1,7,3); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What if I specify a future version e.g. I specified Where are the rules for how specified version vs runtime/actual version spelled out? SUGGESTION: Expand this section with more details about versioning rules |
||
compatibilityOptions.PatchMode2 = new WindowsAppRuntimeVersion(1,8,2); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What if I'm running with 1.7.3 and only specified 1.8.anything? That's equivalent to specifying nothing? |
||
compatibilityOptions.DisabledChanges.Add(CompatibilityChange.HypotheticalChange); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What happens if I specify an unknown change? Silently ignored? Error? Debug message? Other? CONSIDER: Option(s) for developers to be aware of unknown inputs e.g.
or
|
||
compatibilityOptions.Apply(); | ||
} | ||
``` | ||
|
||
Note that CompatibilityOptions must be applied early in the process before any other Windows App | ||
SDK APIs are called, or right after initializing the Windows App Runtime. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
What does this mean? When does this occur? There is no Do you mean the bootstrapper APIs? Other APIs? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Does that include before any WinAppSDK 'auto-initializer' code is executed? |
||
|
||
### Specifying CompatibilityOptions in the app's project file | ||
|
||
You can also specify the patch version and disabled changes in the app's project file instead of | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "patch version" but XML and API (above) say "patch mode" Please use consistent terminology |
||
directly calling the CompatibilityOptions APIs. This approach has the advantage of ensuring the | ||
options are applied early at the proper timing. Here's an example of how to specify the patch | ||
version and disabled changes in the project file (such as `.csproj` or `.vcxproj`): | ||
|
||
```xml | ||
<PropertyGroup> | ||
<WindowsAppSDKRuntimePatchMode>1.7.3</WindowsAppSDKRuntimePatchMode> | ||
<WindowsAppSDKRuntimePatchMode2>1.8.2</WindowsAppSDKRuntimePatchMode2> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is |
||
<WindowsAppSDKDisabledChanges>HypotheticalChange, OtherHypotheticalChange</WindowsAppSDKDisabledChanges> | ||
</PropertyGroup> | ||
``` | ||
|
||
The `WindowsAppSDKDisabledChanges` property is a comma-separated list of `CompatibilityChange` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Why not multiple elements? e.g.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Comma-separated? So semi-colons or other characters are errors?
Whitespace is signficant? Are any of these errors or all equivalent?
|
||
values to disable. | ||
|
||
### Behavior with no PatchMode specified | ||
|
||
If no `PatchMode1` or `PatchMode2` is specified, or if neither value matches the major.minor | ||
version of the runtime being used, then the runtime will use the latest patch version. In other | ||
words, the runtime will run with all servicing changes enabled, which is the same behavior as | ||
Windows App SDK 1.6 and earlier. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Phrasing of 1.6 mention is confusing. The intent is the latest behavior is enabled, just like before this API existed? SUGGESTION: "In other words, the runtime will run with all servicing changes enabled (just like how Windows App SDK worked before this API existed)." |
||
|
||
## CompatibilityOptions.PatchMode1 | ||
|
||
Optional patch mode to use if the runtime version matches the major.minor version. If the runtime | ||
version does not match the specified major.minor version, this value is ignored. | ||
|
||
Instead of directly using this API, this patch mode could be specified in the app's project file, | ||
like this: | ||
|
||
```xml | ||
<PropertyGroup> | ||
<WindowsAppSDKRuntimePatchMode>1.7.3</WindowsAppSDKRuntimePatchMode> | ||
</PropertyGroup> | ||
``` | ||
|
||
If your app is not in the process of transitioning to a new version of the Windows App SDK, you | ||
should only set this one patch mode. | ||
|
||
## CompatibilityOptions.PatchMode2 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
or in code via similar e.g. in *.vcxproj
and in code
|
||
|
||
Optional patch mode to use if the runtime version matches the major.minor version. If the runtime | ||
version does not match the specified major.minor version, this value is ignored. | ||
|
||
This property enables setting a second patch mode to help apps transitioning to a new version of | ||
the Windows App SDK. This is a convenience to allow the patch modes for both the old and new | ||
version to be specified during the transition. Apps not in the process of transitioning should | ||
only set the one patch mode they want to use. | ||
|
||
Setting both patch modes for the same major.minor version, such as 1.7.3 and 1.7.4, is not allowed | ||
and will generate an error during `Apply()`. | ||
|
||
Instead of directly using this API, this patch mode could be specified in the app's project file, | ||
like this: | ||
|
||
```xml | ||
<PropertyGroup> | ||
<WindowsAppSDKRuntimePatchMode2>1.8.2</WindowsAppSDKRuntimePatchMode2> | ||
</PropertyGroup> | ||
``` | ||
|
||
## CompatibilityOptions.DisabledChanges | ||
|
||
Optional list of specific servicing changes to disable. | ||
|
||
If you encounter a problem with a specific change in a servicing update, you can disable just that | ||
change by adding it to the `DisabledChanges` list before calling `Apply`, or by specifying it in | ||
your app's project file: | ||
```xml | ||
<PropertyGroup> | ||
<WindowsAppSDKDisabledChanges>HypotheticalChange, OtherHypotheticalChange</WindowsAppSDKDisabledChanges> | ||
</PropertyGroup> | ||
``` | ||
|
||
The [release notes](https://learn.microsoft.com/windows/apps/windows-app-sdk/stable-channel) for | ||
the Windows App SDK will list the name of each change that can be disabled. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can a list be provided in the SDK for build-time reference? e.g. Add
|
||
|
||
Note that disabling a change is a temporary measure which gives time for a fix to be released in a | ||
future Windows App SDK update or for you to implement an update in your app. You should report | ||
changes you disable if you believe it to be a bug in the Windows App SDK. This will help the | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are disabled changes reported via insights? |
||
Windows App SDK team to understand the impact of the change and prioritize a fix. You can report | ||
issues on the [WindowsAppSDK GitHub repo](https://github.com/microsoft/WindowsAppSDK/issues/new?template=bug-report.yaml). | ||
|
||
The capability to disable a change is **not** available across new Windows App SDK stable | ||
releases (such as 1.7.x to 1.8.x), so this does not allow you to permanently disable an | ||
intentional behavior change. Also, new stable releases, such as 1.8.0, start with no changes | ||
available to disable -- this capability only applies to disabling targeted servicing changes | ||
added in servicing releases. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This implies Then shouldn't these be named This gets more to policy how we name these (Hypothetical)Changes but strong guidance from the start is best. |
||
|
||
## CompatibilityOptions.Apply | ||
|
||
Apply the set compatibility options to the runtime. | ||
|
||
Note that CompatibilityOptions must be applied early in the process before any other Windows App | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. SUGGESTION: NOTE: `CompatibilityOptions MUST be...
|
||
SDK APIs are called, or right after initializing the Windows App Runtime. The options must be set | ||
early before the configuration is locked for the lifetime of the process. Since the Windows App | ||
Runtime needs to run with a consistent configuration, it will lock the configuration when it needs | ||
to ensure the configuration will no longer change. Calling `Apply` will also lock the | ||
configuration. | ||
|
||
If the configuration has already been locked, calling `Apply` will throw an `E_ILLEGAL_STATE_CHANGE` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is that a way to 'Reset` or 'Unapply' the configuration? OR no, 'till process death do you part? |
||
exception if the options differ from the locked configuration. It is okay to call `Apply` multiple | ||
times with the same configuration, such as if the process had initialized and used the Windows | ||
App Runtime earlier and is reinitializing for additional use. | ||
|
||
# API Details | ||
|
||
```c# (but really MIDL3) | ||
namespace Microsoft.Windows.ApplicationModel.WindowsAppRuntime | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missing API contract SUGGESTION:
|
||
{ | ||
/// The set of servicing changes that can be disabled. | ||
enum CompatibilityChange | ||
{ | ||
None = 0, /// do not use this value | ||
|
||
// Add real changes here: | ||
|
||
// 1.7.1 | ||
// HypotheticalChange, | ||
// OtherHypotheticalChange, | ||
// ... | ||
}; | ||
|
||
/// Represents a version of the Windows App Runtime. | ||
struct WindowsAppRuntimeVersion | ||
{ | ||
UInt32 Major; | ||
UInt32 Minor; | ||
UInt32 Patch; | ||
}; | ||
|
||
/// This object is used by the app to configure any desired compatibility options | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. By the "app" or "process"? Can OOP WinRT servers use this API? Are OOP WinRT servers apps? SUGGESTION: This object is used by the process... |
||
/// for Windows App Runtime behavior of changes added in servicing updates. This | ||
/// object is only used to set the runtime behavior and can't be used to query the | ||
/// applied options. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why no query API? Let me guess: An app specifying this knows what it's doing so it doesn't have to query at runtime. Question: What are class libraries supposed to do? Lacking a query API creates issues for library authors. How does a library know current process' behavior? They don't control the process/environment they run in (not the app). Would that amount to...?
|
||
runtimeclass CompatibilityOptions | ||
{ | ||
CompatibilityOptions(); | ||
|
||
/// An optional patch mode to use if the runtime version matches the major.minor version. | ||
WindowsAppRuntimeVersion PatchMode1 { get; set; }; | ||
|
||
/// An optional patch mode to use if the runtime version matches the major.minor version. | ||
WindowsAppRuntimeVersion PatchMode2 { get; set; }; | ||
|
||
/// An optional list of specific servicing changes to disable. | ||
IVector<CompatibilityChange> DisabledChanges{ get; }; | ||
|
||
/// Apply the compatibility options to the runtime. | ||
void Apply(); | ||
} | ||
} | ||
``` | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
RuntimeCompatibilityOptions
?AppConfigurableCompatibility
?(Naming, hard :-()