-
Notifications
You must be signed in to change notification settings - Fork 326
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
DeploymentManager spec update for the new Repair API #2869
base: main
Are you sure you want to change the base?
Conversation
65cfd5a
to
ac61f62
Compare
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.
DON'T CHECKIN until API Review
…b.com/microsoft/WindowsAppSDK into user/sachinta/DeploymentRepairAPISpec
architecture needed are derived from the current WinAppSDK Framework package. | ||
|
||
Since both the Main _and_ the Singleton packages will be repaired, it is possible that Main package | ||
repair has failed and Initialize returns with PackageRepairFailed status (OR) it is possible that |
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.
What does "(OR)" mean here? "or"?
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.
It is just "or". I should probably just use "or" to avoid such confusion.
repair has failed and Initialize returns with PackageRepairFailed status (OR) it is possible that | ||
Main package is repaired successfully but the Singleton package repair has failed and Initialize | ||
returns with repair has failed and Initialize returns with PackageRepairFailed status (OR) it is | ||
possible that status. In both cases, the returned WindowsAppRuntimeStatus will contain the error of |
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.
both cases
I think it just listed 3 cases
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.
It's actually just 2 cases only.
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.
I see three cases in the text (separated by "OR"):
- it is possible that Main package repair has failed and Initialize returns with PackageRepairFailed status
- it is possible that Main package is repaired successfully but the Singleton package repair has failed and Initialize returns with repair has failed and Initialize returns with PackageRepairFailed status
- it is possible that status
Not sure what 3 is trying to say.
repair has failed and Initialize returns with PackageRepairFailed status (OR) it is possible that | ||
Main package is repaired successfully but the Singleton package repair has failed and Initialize | ||
returns with repair has failed and Initialize returns with PackageRepairFailed status (OR) it is | ||
possible that status. In both cases, the returned WindowsAppRuntimeStatus will contain the error of |
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.
possible that status
Looks like there was more sentence intended here
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.
Yes, I need to rectify that. Not sure how I ended up with that incomplete sentence there. But I wanted to mean "Main's repair could fail" or "Main repair succeeded but Singleton repair could fail".
@@ -143,18 +161,16 @@ by using DeploymentInitializeOptions object and setting ForceDeployment option b | |||
this API. This option when set will shut down the application(s) associated with WinAppSDK packages, | |||
update the WinAppSDK packages and restart the application(s). |
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.
If I don't set ForceDeployment true, the deploy will fail? And then the app should interact with the to say "on next reboot" or some such?
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.
If the packaged app doesn't call Initialize() or Repair() with ForceDeployment set and if the current install is actually an update because an older package version is already installed, then yes it does fail with an error that reads "Package in Use". There is no further story to it. If the intention of the developer is to use ForceDeployment eventually, then there is no reason to wait for the first call of Initialize to fail before calling it again with ForceDeployment set this time. The developer could as well have passed it in the first call of Initialize or Repair itself.
Explained what happens when ForceDeployment is set in your next feedback comment in detail.
framework package and all dependent packages that are currently in use will be re-installed, after | ||
they shut down, to refer to the updated framework package. | ||
Framework package and all dependent packages that are currently in use will be re-installed, after | ||
they shut down, to refer to the updated Framework package. |
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.
after they shut down
Does this mean it will force the apps currently using the package to shut down, or does this mean that the Initialize() call could block indefinitely?
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.
It will only force the Main, Singleton and DDLM packages to shut down in order to update Main, Singleton and DDLM packages (ex: PushNotifications would be shutdown as it's part of Singleton package) and the shutdown packages are restarted automatically by the OS platform after their updates are complete (and in cases such as PushNotifictions which would need explicit reboot as it's a com server, we do reboot it after the update in Initialize()/Repair()).
It doesn't shutdown the WinAppSDK framework package dependent packaged apps and installs the higher version of the framework package side by side without uninstalling the older version. It does update the WinAppSDK framework package dependent packaged apps (in their package graph) to point to higher version of the framework package, once they are shutdown by the user. Once all references to older version of the framework package are updated to refer to the higher version of it, the older version is then completely uninstalled by the OS platform.
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.
What if an app is currently using Main/Singleton/DDLM package (and I set Force)? What happens to the app?
} | ||
``` | ||
|
||
Here's the previous example extended with the `Show UI on error` option: |
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.
This example doesn't match the above logic; the logic shows UI, the example doesn't. If the UI built in to the API and explains to the user what the problem is? Or if the logic is correct and the app needs to show UI, it's awkward because they can't use WinAppSDK to show the UI
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.
Yes, the UI shown is built into the API explaining the problem to the user (currently via MessageBox()
)
/// WindowsAppSDK main and singleton packages will be shut down forcibly if they are | ||
/// currently in use, when registering the WinAppSDK packages. | ||
/// WinAppSDK Main and Singleton packages will be shut down forcibly if they are | ||
/// currently in use, when initializing the WindowsAppRuntime. |
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.
So when you start my app, you might see some other apps disappear? Is there any kind of interaction with the user first?
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.
No. Please see one of the above comments for detailed explanation on ForceDeployment. In short, ForceDeployment only shuts down WinAppSDK packages that are dependent on it's framework packages (ex: Main, Singleton and DDLM). It doesn't shut down any non-WinAppSDK packages that declared dependency on WinAppSDK framework package.
they shut down, to refer to the updated Framework package. | ||
|
||
```C# | ||
if (DeploymentManager.GetStatus().Status == DeploymentStatus.PackageInstallRequired) |
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.
This is in the DeploymentRepairOptions section, so this should be checking for == DeploymentStatus.PackageRepairRequired right?
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.
Yes. Need to check for == DeploymentStatus.PackageRepairRequired. Thanks for pointing that out.
the system? | ||
3. How do I repair the already installed WinAppSDK Main and Singleton packages, if needed ? |
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.
Why do we need Repair to be a distinct action than Install/Initialize, instead of having developers [re]install the packages whenever they're "broken". This is something of a breaking change since we'd previously told developers to Initialize for any status other than .OK, right?
The manual method to repair by "reinstalling from msdn downloads page" is identical for install and repair. Why is the full-trust-app method different?
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.
Intialize installs/re-installs WinAppSDK Main and Singleton packages only when needed (i.e. when one of the packages is not installed or if one of them is in identified bad state). Thus, avoiding the unnecessary perf overhead of the unconditional re-install in every launch of the WinAppSDK dependent Packaged app.
Repair, on the other hand, re-installs those packages unconditionally. This API is important because there are many bad states a package can be in but only a few of them could be identified by Initialize and fix. Hence, we need Developers to just able to call Repair in cases where the WinAppSDK features aren't working due to a bad state that Initialize couldn't identify and fix it.
This is not a breaking change. Because the current usage of Initialize as detailed in the code sample in this spec prior to the current PR would still work for Initialize API (i.e. up until 1.2 WinAppSDK release). But the changes to code samples in this PR show a better recommended method in calling Initialize and Repair API conditionally, that developers can adopt with 1.3+ WinAppSDK release.
Manual method of using WindowsAppRuntimeInstall.exe can now, starting with 1.2 WinAppSDK release, use repair option explicitly. Once again, this is due to the desire to avoid unnecessary re-installs in default install path (ex: as complained by PowerToys team).
current WinAppSDK Framework package. | ||
|
||
Since both the Main _and_ the Singleton packages may need to be installed, it is possible that Main | ||
package install has failed and Initialize returns with PackageInstallFailed state (OR) it is |
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.
What happens if I try to Repair() a package that's in PackageInstallFailed state? That seems like a natural inclination ("I did Initialize() and it's in some error state now, I guess that means it's broken so I should fix it. Fix -> repair. Call Repair()"). Are we providing DeploymentResult properties that tell the developer they called the wrong method?
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.
Repair() essentially provides an unconditional core functionality of Initialize() - which is to install WindowsAppSDK Main and Singleton licenses and packages. So, if Repair() is tried when Initialize() fails, then it is effectively a retry of Initialize(). If the underlying issue for PackageInstallFailed is transient, then Repair() may succeed. Otherwise, it will continue to be PackageInstallFailed.
No, DeploymentResult doesn't have any property that calls out wrong method usage. Because calling Repair() when Initialize() fails is not a wrong method.
architecture needed are derived from the current WinAppSDK Framework package. | ||
|
||
Since both the Main _and_ the Singleton packages will be repaired, it is possible that Main package | ||
repair has failed and Initialize returns with PackageRepairFailed status (OR) it is possible that |
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.
In this paragraph here, "Initialize returns with PackageRepairFailed status" should actually be "Repair returns with PackageRepairFailed status" at 2 instances.
// for the Status. | ||
} | ||
else if (result.Status == DeploymentStatus.PackageRepairRequired || | ||
result.Status == DeploymentStatus.Unknown) |
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.
what if the status is PackageInstallFailed ? Shouldn't I want to Repair() it in that case? (Since repair is unconditional core functionality of Initialize, is PackageInstallFailed a special-case or subset of PackageRepairRequired?)
// WindowsAppRuntime. result.ExtendedError has the error code that has the reason | ||
// for the Status. | ||
// WindowsAppRuntime is either not installed or not in a good state (can't be both at same time). | ||
if (result.Status == DeploymentStatus.PackageInstallRequired) |
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.
What happens if an app developer upgrades to WinAppSDK 1.3 but forgets to update this part of their code? In other words, what happens if the app just calls Initialize for all non-OK deployment statuses instead of calling Repair sometimes?
I hope the answer is "Everything still works, though maybe less efficiently than if you had used Repair."
// for the Status. | ||
} | ||
else if (result.Status == DeploymentStatus.PackageRepairRequired || | ||
result.Status == DeploymentStatus.Unknown) |
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.
Suppose in WinAppSDK version 1.9 we add a new DeploymentStatus. This code will ignore all new DeploymentStatus error codes. Should it treat all unknown DeploymentStatus values the same as Unknown?
As written, it means that adding a new DeploymentStatus is a breaking change.
again. | ||
Once the Main and Singleton packages have been deployed, they generally do not need to be deployed | ||
again. If a user were to remove the Main or Singleton package, the API can be used to reinstall them | ||
again. If there is anything wrong with installed Main and Singleton packages, use Repair API to try |
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.
What does "anything wrong" mean? Does it mean "Any DeploymentStatus other than DeploymentStatus.Ok"?
Because that's not what the sample code does. It calls Repair only for selected DeploymentStatus values, not for "anything wrong".
|
||
```C# | ||
if (DeploymentManager.GetStatus().Status != DeploymentStatus.Ok) | ||
if (DeploymentManager.GetStatus().Status == DeploymentStatus.PackageInstallRequired) |
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.
This does not do what the previous text recommends. Previous text says, "If there is anything wrong with installed Main and Singleton packages, use Repair API to try and repair them." But in this code, we don't call Repair for "anything wrong". In fact, we're not calling Repair at all!
@@ -167,12 +183,13 @@ they shut down, to refer to the updated framework package. | |||
// These should be run on a separate thread so as not to hang your app while the | |||
// packages deploy. | |||
var initializeTask = Task.Run(() => DeploymentManager.Initialize(deploymentInitializeOptions)); | |||
//...do other work while the repair is running... |
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.
The comment says "repair", but the method we called was "Initialize".
Either the code should be "Repair", to match the comment; or the comment should say "initialize" to match the code.
if (DeploymentManager.GetStatus().Status == DeploymentStatus.PackageRepairRequired || | ||
DeploymentManager.GetStatus().Status == DeploymentStatus.Unknown) | ||
{ | ||
// Repair will always attempt to repair WindowsAppRuntime regardless of it's state. |
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.
// Repair will always attempt to repair WindowsAppRuntime regardless of it's state. | |
// Repair will always attempt to repair WindowsAppRuntime regardless of its state. |
|
||
```C# | ||
if (DeploymentManager.GetStatus().Status == DeploymentStatus.PackageRepairRequired || | ||
DeploymentManager.GetStatus().Status == DeploymentStatus.Unknown) |
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.
Is it right to call GetStatus()
twice? Could the status change between the two calls?
When the API is updating Framework package and ForceDeployment option is set, then all dependent | ||
packages that are NOT currently in use will be immediately re-installed to refer to the updated | ||
Framework package and all dependent packages that are currently in use will be re-installed, after | ||
they shut down, to refer to the updated Framework package. |
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.
Wait, I thought the first paragraph in this section said that if you force deployment, then we don't want for the users to exit the apps; we shut down the apps immediately. But here, we wait for the apps to shut down naturally.
Or is "after they shut down" saying "after we shut them down" (rather than the app shutting down on its own)? Could use some clarity about whether the shutdown is immediate or eventual.
var deploymentRepairOptions = new DeploymentRepairOptions(); | ||
deploymentRepairOptions.ForceDeployment = true; | ||
|
||
// Repair will always attempt to repair WindowsAppRuntime regardless of it's state. |
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.
// Repair will always attempt to repair WindowsAppRuntime regardless of it's state. | |
// Repair will always attempt to repair WindowsAppRuntime regardless of its state. |
DeploymentManager::Repair(...) | ||
{ | ||
// Only needed supported in packaged processes | ||
IF IsPackagedProcess() |
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.
Test seems backwards.
…oymentRepairAPISpec
…b.com/microsoft/WindowsAppSDK into user/sachinta/DeploymentRepairAPISpec
@sachintaMSFT Is this stale or what's the latest update on this? |
Deployment Manager Spec update to add the new Repair API for 1.3 release. Hence, incrementing the DeploymentContract to version 4.