Skip to content

Implement Hot Exit#14115

Merged
Tyriar merged 71 commits intomasterfrom
tyriar/hot_exit/14068_load_backups_on_main_process
Nov 11, 2016
Merged

Implement Hot Exit#14115
Tyriar merged 71 commits intomasterfrom
tyriar/hot_exit/14068_load_backups_on_main_process

Conversation

@Tyriar
Copy link
Copy Markdown
Contributor

@Tyriar Tyriar commented Oct 20, 2016

@Tyriar Tyriar added the workbench-hot-exit Preservation of unsaved changes across restarts label Oct 20, 2016
@Tyriar Tyriar added this to the October 2016 milestone Oct 20, 2016
@mention-bot
Copy link
Copy Markdown

@Tyriar, thanks for your PR! By analyzing the history of the files in this pull request, we identified @bpasero, @joaomoreno and @egamma to be potential reviewers.

@Tyriar Tyriar changed the title Load backup resources exclusively on main process Fix various hot exit issues Oct 20, 2016
@bpasero
Copy link
Copy Markdown
Member

bpasero commented Oct 21, 2016

@Tyriar there are merge conflicts?

@bpasero
Copy link
Copy Markdown
Member

bpasero commented Oct 21, 2016

I merged.

@IEventService private eventService: IEventService,
@ITextFileService private textFileService: ITextFileService,
@IBackupService private backupService: IBackupService
@IBackupFileService private backupFileService: IBackupFileService
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Unused member

Comment thread src/vs/code/electron-main/windows.ts Outdated
return path.workspacePath;
}
return platform.isLinux ? path.workspacePath : path.workspacePath.toLowerCase();
const workspacesWithBackups = this.backupService.getWorkspaceBackupPathsSync();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

As reported in a different issue that code should really move out of the open() method and only be used from the first startup code. Otherwise it makes it very hard to understand what this method is actually doing (it is already quite complex).

) {
super();
this.resource = resource;
this.restoreResource = restoreResource;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

As mentioned before I think we can get rid of the restoreResource also for untitled. The untitled model should go to the backup service and ask for available backups with the resource URI, similar to how text files now ask.

this.backupPromises.push(promise);

return promise;
// TODO: Introduce an event on IUntitledEditorService so this can be moved to BackupModelService?
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Yes, please!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@IFileService private fileService: IFileService,
@IConfigurationService private configurationService: IConfigurationService
@IConfigurationService private configurationService: IConfigurationService,
@IBackupService private backupService: IBackupService,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Unused service?

return false; // the backup went smoothly, no veto
});
});
if (this.backupService.isHotExitEnabled) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Let the backup service listen to the lifecycle method and do it in there. Here I would only check if hot exit is enabled to see if confirmation is needed.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I did this first but regardless there needs to be some communication between the 2 services. BackupService needs to essentially be run both before (check if hot exit) and after (cleanup backups) TextFileService.beforeShutdown. Also the shutdown event doesn't work as it has to be synchronous and BackupService,cleanupBackupsBeforeShutdown is async.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ok maybe textFileServices should use eventing or similar so that we can further decouple this into the backup service.

}

return this.cleanupBackupsBeforeShutdown();
return this.backupService.cleanupBackupsBeforeShutdown(); // all good, no veto
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

All of the cleanupBackupsBeforeShutdown should move out into the backup service that itself should listen to lifecycle events.


this.fileService.discardBackup(this.resource);
// TODO: Can this be moved to BackupModelService?
this.backupFileService.discardAndDeregisterResource(this.resource);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Yes, I suggest another event on the service maybe when this model gets disposed.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

return true;
}

public get onModelContentChanged(): Event<TextFileModelChangeEvent> {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I see the need for an event when untitled or text files are changing so that the backup service can do its business, however I fear that this comes at the cost of spam: you will see many model content change events while the user is typing, so basically each key press will trigger this event. Performance should always be something to be concerned of, especially when it is typing performance we are talking about.

Some ideas:

  • buffer the model content change event and only start to emit the change after a certain delay
  • do not always create an event object to send around

I think buffering would be a good idea anyway because backups should also not be created without some delay.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@bpasero
Copy link
Copy Markdown
Member

bpasero commented Oct 21, 2016

@Tyriar looking a lot better. I like the direction. My only concern besides the comments I added is about the amount of events that are being sent now while typing. See my comment in the review on that topic.

@Tyriar Tyriar force-pushed the tyriar/hot_exit/14068_load_backups_on_main_process branch from fcf9dba to f8ed5aa Compare October 21, 2016 20:19
@Tyriar Tyriar changed the title Fix various hot exit issues Implement Hot Exit Oct 21, 2016
@bpasero
Copy link
Copy Markdown
Member

bpasero commented Nov 10, 2016

@Tyriar replied to your comments, let me know when I should review again.

@Tyriar
Copy link
Copy Markdown
Contributor Author

Tyriar commented Nov 11, 2016

@bpasero ready for another review! If you consider any of these issues to be must fix before merge please label them with important. I want to polish the PR then merge it so we can start getting some testing from Insiders and move to smaller changes that are easier to work with. Thanks 😃

fs.mkdirSync(this.backupHome);
}
fs.writeFileSync(this.workspacesJsonPath, JSON.stringify(this.workspacesJsonContent));
} catch (ex) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@Tyriar maybe add at least some logging here to be able to find out about issues more easily.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@@ -0,0 +1,164 @@
/*---------------------------------------------------------------------------------------------
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@Tyriar there are still warnings in this file

@bpasero
Copy link
Copy Markdown
Member

bpasero commented Nov 11, 2016

@Tyriar only few comments left. my assumption is that you extracted the bigger feedback I gave into issues to look into and that is fine so that we can continue on master in these.

@Tyriar
Copy link
Copy Markdown
Contributor Author

Tyriar commented Nov 11, 2016

Fix warnings in 97371ad (not sure why I can't reply to that comment).

@Tyriar
Copy link
Copy Markdown
Contributor Author

Tyriar commented Nov 11, 2016

@bpasero yes we've been tracking all the comments in issues, the important ones have are in the November milestone.

@Tyriar
Copy link
Copy Markdown
Contributor Author

Tyriar commented Nov 11, 2016

Got the go ahead from @bpasero to merge, all tests are passing and did a manual smoke test on Mac and Windows to double check nothing has regressed since our internal test the other day. Merging! 🎆

@Tyriar Tyriar merged commit 022ee04 into master Nov 11, 2016
@Tyriar Tyriar deleted the tyriar/hot_exit/14068_load_backups_on_main_process branch November 11, 2016 20:18
const workspacesWithBackups = this.backupService.getWorkspaceBackupPaths();

workspacesWithBackups.forEach(workspacePath => {
if (!fs.existsSync(workspacePath)) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@Tyriar would it be possible that we have a backup workspace without backups to restore? maybe we should add more checks here that a backup workspace path should only cause a window to open if it has backups, otherwise it gets deleted. I am thinking of situations where we the backup workspace gets out of sync with the backups within (for whatever reason - e.g. crash). This would prevent bugs where multiple windows just open even though there are no backups.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

continued in #15499

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Commented on #15499.

delete configuration.filesToCreate;
delete configuration.filesToDiff;

// Update untitled files to restore so they come through in the reloaded window
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@Tyriar I am thinking more and more that untitled editors with backups should not be loaded from the main side but rather from the window itself. Files for example restore because we store their state into local storage (via IEditorInputFactory - see https://github.com/Microsoft/vscode/blob/master/src/vs/workbench/common/editor/editorStacksModel.ts#L621).

If we add a factory for untitled editors, we would just rely on that to bring the untitled back on reopen. It would also fix the issue that untitled would reopen at the right location where they where before.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I filed #15498 to continue the discussion

return;
}

const untitledToRestore = this.backupService.getWorkspaceUntitledFileBackupsSync(Uri.file(workspacePath)).map(filePath => {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@Tyriar same comment here about how to restore untitled files. This would not be needed if untitled had input factory.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

continued in #15498

}

// Register new paths for backup
this.backupService.pushWorkspaceBackupPathsSync(iPathsToOpen.filter(p => p.workspacePath).map(p => Uri.file(p.workspacePath)));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@Tyriar should this only happen if hot exit is enabled in settings?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It should still happen so that it gets recorded and restored if there was a crash.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Got it.

};
});

// Add any untitled files to be restored from backup
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@Tyriar again this would not be needed if we had untitled editor factory.

@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

workbench-hot-exit Preservation of unsaved changes across restarts

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants