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

Adopt new extension host restart lifecycle #180514

Closed
bpasero opened this issue Apr 21, 2023 · 12 comments
Closed

Adopt new extension host restart lifecycle #180514

bpasero opened this issue Apr 21, 2023 · 12 comments
Assignees
Labels
custom-editors Custom editor API (webview based editors) debt Code quality issues extension-host Extension host issues notebook on-testplan
Milestone

Comments

@bpasero
Copy link
Member

bpasero commented Apr 21, 2023

Synopsis
We allow the extension host to be restarted in certain cases. Today this happens without any support for asking components whether they can support a restart and so issues arise.

#180513 introduces a new IExtensionService.onWillStop event that listeners can veto(boolean | Promise<boolean>), for example:

// sync
extensionService.onWillStop(e => e.veto(true, 'component id'));

// async
extensionService.onWillStop(e => e.veto(Promise.resolve(true), 'component id'));

This allows to:

  • veto the restart and thus prevent it
  • prolong the restart until work has finished without preventing the restart

In addition the method IExtensionService.stopExtensionHosts() is now a Promise<boolean> and callers must await the result before proceeding. For example:

const stopped = await this.extensionService.stopExtensionHosts();
if (!stopped) {
  return;
}

Related Issues
Some components cannot support EH restart without doing some operation first before the EH goes down, for example:

Adoption

  • Notebook component should make sure dirty and untitled notebooks are saved before the EH restarts @rebornix
  • Custom editor component should make sure dirty and untitled custom editors are saved @mjbvz
  • Workspace trust needs to adopt the new boolean return type of stopExtensionHosts here @lszomoru
  • Profiles need to adopt the new boolean return type of stopExtensionHosts here @sandy081
@bpasero bpasero added the debt Code quality issues label Apr 21, 2023
@bpasero bpasero added this to the On Deck milestone Apr 21, 2023
@bpasero bpasero changed the title Adopt extension host lifecycle Adopt new extension host restrt lifecycle Apr 21, 2023
@bpasero bpasero changed the title Adopt new extension host restrt lifecycle Adopt new extension host restart lifecycle Apr 21, 2023
@bpasero bpasero added extension-host Extension host issues custom-editors Custom editor API (webview based editors) notebook labels Apr 21, 2023
@rebornix
Copy link
Member

Notebook component should make sure dirty and untitled notebooks are saved before the EH restarts @rebornix
Custom editor component should make sure dirty and untitled custom editors are saved @mjbvz

@bpasero I'm wondering if this can be done in one level up, for example, implement the saving all logic in FileWorkingCopyManager so we don't have to try to trigger saving from notebook or custom editor component.

@bpasero
Copy link
Member Author

bpasero commented Apr 22, 2023

But FileWorkingCopyManager has no knowledge about extensions or the extension host restarting. I do not think it should have a dependency to extensions service or stop it from restarting.

@sandy081
Copy link
Member

@bpasero Would like to see the end - end flow with this API - Lets say user switches the profile and one of the components veto it. In this case what does user see? If user decides to veto (cancel) it, what is expected to do by the component triggering the action to stop extension hosts. May be instead of returning a boolean value, does it makes sense to throw a cancellation error?

@bpasero
Copy link
Member Author

bpasero commented May 15, 2023

In this case what does user see?

Nothing, the operation is stopped. Compare this with closing a dirty editor and pressing "Cancel"

If user decides to veto (cancel) it, what is expected to do by the component triggering the action to stop extension hosts.

The expectation is to then not restart the extension host and unwind anything that was done as part of the flow (if any). Here is how workspaces do it:

async enterWorkspace(workspaceUri: URI): Promise<void> {
const stopped = await this.extensionService.stopExtensionHosts();
if (!stopped) {
return;
}

@sandy081
Copy link
Member

In this case what does user see?

I am more particular about the dialog shown by the components for vetoing. For example, what kind of dialog Notebooks show? This dialog shall have the information about the user action and not the internal details like extension host is being restarted. I am expecting in the profile switch scenario, the veto dialog shall say something like Would you like to save the notebook before switching the profile? If so, the stopExtensionHosts api shall take additional context as an input so that the listeners will provide the context in the dialog.

@bpasero
Copy link
Member Author

bpasero commented May 15, 2023

Yeah I like that, maybe as part of the call to stopExtensionHosts we could pass in a string that the components can use to show as details of the dialog. Or are you suggesting to turn it around and let components return the strings and let the extension service show the dialog?

@sandy081
Copy link
Member

maybe as part of the call to stopExtensionHosts we could pass in a string that the components can use to show as details of the dialog.

I think, this is better for the components

@bpasero
Copy link
Member Author

bpasero commented May 15, 2023

Adding a new reason property to the event in: #182523

I think its good that a component opens a dialog because a component will have to deal with all the buttons and actions. Components can now show reason as dialog details.

bpasero added a commit that referenced this issue May 15, 2023
* extension host - add reason property and adopt (#180514)

* lint
mjbvz added a commit to mjbvz/vscode that referenced this issue May 15, 2023
@bpasero
Copy link
Member Author

bpasero commented May 17, 2023

Thinking that the extension service should inform the user on veto, like so:

image

The first message is the reason for why the extension host is restarted and should read well so please adopt accordingly @sandy081 and @lszomoru .

The second details message lists the reason why the operation was blocked and should also read accordingly @mjbvz and @rebornix

bpasero added a commit that referenced this issue May 17, 2023
* extension host - show reason when veto (#180514)

* adopt messages
mjbvz added a commit that referenced this issue May 18, 2023
* Adopt ext host restart for custom editors

For #180514

* Show notification when restart is vetoed
sandy081 added a commit that referenced this issue May 19, 2023
Adopt Adopt new extension host restart lifecycle #180514
@sandy081 sandy081 removed their assignment May 19, 2023
@sandy081
Copy link
Member

@bpasero
Copy link
Member Author

bpasero commented May 22, 2023

Thanks, I think we only miss workspace trust and notebooks 🙏

bpasero added a commit that referenced this issue May 25, 2023
* Adopt new extension host restart lifecycle (#180514)

* adopt for notebooks

* fix tests
@bpasero
Copy link
Member Author

bpasero commented May 25, 2023

I think this is in very good shape now. Workspace trust transition cannot be fully cancelled, but the data loss scenario is mitigated with the veto support we have.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
custom-editors Custom editor API (webview based editors) debt Code quality issues extension-host Extension host issues notebook on-testplan
Projects
None yet
Development

No branches or pull requests

6 participants