Skip to content

Hot exit empty workspace support#16303

Merged
Tyriar merged 29 commits intomasterfrom
tyriar/hot_exit/empty_workspaces
Dec 3, 2016
Merged

Hot exit empty workspace support#16303
Tyriar merged 29 commits intomasterfrom
tyriar/hot_exit/empty_workspaces

Conversation

@Tyriar
Copy link
Member

@Tyriar Tyriar commented Dec 1, 2016

Fixes #13733

@Tyriar
Copy link
Member Author

Tyriar commented Dec 1, 2016

@bpasero I managed to get empty workspaces working, it's just super rough. I'd love some feedback on the general approach and position of things, specifically:

  • Passing vscodeWindowId around inside IWindowConfiguration
  • Including vscodeWindowId in IEnvironmentService
  • The name of vscodeWindowId (it needs to be distinct from VSCodeWindow.id)
  • The format of vscodeWindowId: Date.now().toString(). I was also considered crypto.randomBytes (might be too slow) and Math.random() (overkill if Date.now() can guarantee uniqueness)
  • The handling of emptyToOpen

I'll be polishing this tomorrow and will probably stay up so we can get this in before the weekend.

extensionDevelopmentPath?: string;
allowFullscreen?: boolean;
titleBarStyle?: 'native' | 'custom';
vscodeWindowId?: string;
Copy link
Member

Choose a reason for hiding this comment

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

@Tyriar I would suggest to call this id and instead fix all users of the current id property to use vscodeWindows.win.id because that makes it very clear what ID is being asked.

// TODO: There's an extra empty workspace opening when restoring an empty workspace (sometimes)
emptyToRestore.forEach(vscodeWindowId => {
const configuration = this.toConfiguration(openConfig);
configuration.vscodeWindowId = vscodeWindowId;
Copy link
Member

Choose a reason for hiding this comment

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

@Tyriar why is this done here and not inside the toConfiguration method?

configuration.vscodeWindowId = vscodeWindow.vscodeWindowId;
if (!configuration.extensionDevelopmentPath) {
// TODO: Cover closing a folder/existing window case
this.backupService.pushEmptyWorkspaceBackupWindowIdSync(configuration.vscodeWindowId);
Copy link
Member

Choose a reason for hiding this comment

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

@Tyriar I suggest to move this up to the place where we already call pushWorkspaceBackupPathsSync so that we have it in one place. doing this from toConfiguration is very weird. As a caller of this method I would expect to get a configuration object but as a side effect I am writing to the backup folder??

pushWorkspaceBackupPathsSync(workspaces: Uri[]): void;

// TODO: Doc
pushEmptyWorkspaceBackupWindowIdSync(vscodeWindowId: string): void;
Copy link
Member

Choose a reason for hiding this comment

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

@Tyriar maybe merge both methods into one and the return type can either be a path to a workspace or a window id? might make the naming easier.


execPath: string;
appRoot: string;
vscodeWindowId: string;
Copy link
Member

Choose a reason for hiding this comment

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

@Tyriar we cannot really add this here because environment service is agnostic to windows, we have one in the shared process as well as the CLI. I suggest to put this into the IWindowService on the renderer side.

@bpasero
Copy link
Member

bpasero commented Dec 1, 2016

@Tyriar do we actually need to come up with and pass around a window id only to know from where to restore backups? Why not let the backup service deal with it:

  • from the main side you already open as many empty workspaces as you had dirty files in empty workspaces
  • my backup restorer asks the backup service for a list of backup files to open
  • the backup service could simply ask the main side: hey give me the contents of one of the empty workspace backup folder
  • if you have more than one empty workspace, just use the index of the window as it is known to windows.ts to distinguish or keep in memory somewhere that you gave one window a set of backups already

Just a thought...

// Backup File Service
const workspace = this.contextService.getWorkspace();
serviceCollection.set(IBackupFileService, this.instantiationService.createInstance(BackupFileService, workspace ? workspace.resource : null));
serviceCollection.set(IBackupFileService, this.instantiationService.createInstance(BackupFileService, this.windowService.getCurrentWindowId()));
Copy link
Member

Choose a reason for hiding this comment

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

@Tyriar why not let backup file service depend on windows service to get the ID?

Copy link
Member Author

Choose a reason for hiding this comment

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

It could, and it did prior to 85bf25f. Aren't less deps generally a good thing?

if (emptyToRestore.length > 0) {
emptyToRestore.forEach(backupFolder => {
const configuration = this.toConfiguration(openConfig, null, null, null, null, backupFolder);
const browserWindow = this.openInBrowserWindow(configuration, openInNewWindow, openInNewWindow ? void 0 : openConfig.windowToUse);
Copy link
Member

Choose a reason for hiding this comment

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

@Tyriar we always want each of these windows to open inside a new window so I suggest to just call

const browserWindow = this.openInBrowserWindow(configuration, true /* new window */);

In the same way as we do for restoring folders.

Copy link
Member Author

Choose a reason for hiding this comment

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

}
}

this.backupService.registerWindowForBackups(vscodeWindow.id, !configuration.workspacePath, configuration.backupFolder, configuration.workspacePath);
Copy link
Member

Choose a reason for hiding this comment

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

@Tyriar are you missing the check for openConfig.cli.extensionDevelopmentPath on purpose here?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, moved it to registerWindowForBackups so it was handled by the BackupMainService. Now that you mentioned it though, that was there for a good reason, thanks for pointing that out 👍

Copy link
Member Author

Choose a reason for hiding this comment

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

perfWindowLoadTime?: number;

workspacePath?: string;
backupFolder?: string;
Copy link
Member

Choose a reason for hiding this comment

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

@Tyriar suggest backupPath to keep naming consistent

Copy link
Member Author

Choose a reason for hiding this comment

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

I removed this specific member in 10c1211

On the naming, folder is used in some placed because it's only folder, as opposed to the full path.

Copy link
Member

Choose a reason for hiding this comment

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

Got it.

if (emptyToOpen.length > 0) {
if (emptyToRestore.length > 0) {
emptyToRestore.forEach(backupFolder => {
const configuration = this.toConfiguration(openConfig, null, null, null, null, backupFolder);
Copy link
Member

Choose a reason for hiding this comment

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

@Tyriar something is weird about backupFolder. As someone that tries to understand the code I would assume every window has an associated backupFolder. but that is not true, only the empty windows to restore have it. I would make this more obvious. Maybe remove the property from IWindowConfiguration and just pass it into openInBrowserWindow method? Also needs a clearer name to make its meaning more obvious.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done 10c1211

emptyToRestore.forEach(emptyWorkspaceBackupFolder => {
const configuration = this.toConfiguration(openConfig, null, null, null, null);
const browserWindow = this.openInBrowserWindow(configuration, openInNewWindow, openInNewWindow ? void 0 : openConfig.windowToUse, emptyWorkspaceBackupFolder);
const browserWindow = this.openInBrowserWindow(configuration, true /* new window */, openInNewWindow ? void 0 : openConfig.windowToUse, emptyWorkspaceBackupFolder);
Copy link
Member

Choose a reason for hiding this comment

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

@Tyriar I would not assume we have a windowToUse in this case ever?

Copy link
Member Author

Choose a reason for hiding this comment

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

👍 d661321

@@ -51,11 +51,6 @@ export class BackupMainService implements IBackupMainService {
}

public registerWindowForBackups(windowId: number, isEmptyWorkspace: boolean, backupFolder?: string, workspacePath?: string): void {
Copy link
Member

Choose a reason for hiding this comment

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

@Tyriar I didnt know you had this check in here, I am also fine leaving it there to keep this knowledge inside the service!

Copy link
Member Author

Choose a reason for hiding this comment

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

That was my thinking, didn't we want to keep that check outside though due to the config in IEnvironmentService potentially being stale or something?

Copy link
Member

Choose a reason for hiding this comment

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

Hm yeah maybe. We can leave it there for now. The problem is that the main side only ever has one environment service and so a second window would not answer this check correctly.

@Tyriar Tyriar merged commit d5349d2 into master Dec 3, 2016
@Tyriar Tyriar deleted the tyriar/hot_exit/empty_workspaces branch December 3, 2016 04:13
@github-actions github-actions bot locked and limited conversation to collaborators Mar 27, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Hot Exit: Support hot exit on empty workspaces

3 participants