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

fix: Rename the old server before update #9585

Merged
merged 1 commit into from Jul 13, 2021

Conversation

lnicola
Copy link
Member

@lnicola lnicola commented Jul 12, 2021

Kinda' fixes #6602

@lnicola
Copy link
Member Author

lnicola commented Jul 12, 2021

r? @wxb1ank

const entries = await vscode.workspace.fs.readDirectory(serverDir);
for (const [entry, _] of entries) {
try {
const parsedPath = path.parse(entry);
Copy link
Member Author

Choose a reason for hiding this comment

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

Not sure what entry is here.

@wxb1ank
Copy link
Contributor

wxb1ank commented Jul 12, 2021

Sorry if I'm missing something, but how is temporarily renaming the server to 'stale' different than replacing it with the newly downloaded one? I haven't tested, but if one or more server instances are running, won't this always cause EPERM?

@lnicola
Copy link
Member Author

lnicola commented Jul 12, 2021

It seems that you actually can rename a running executable on Windows. But yeah, this is untested otherwise.

@wxb1ank
Copy link
Contributor

wxb1ank commented Jul 12, 2021

I feel like we wouldn't have run into the original permission error if that were the case. IMO, the simplest thing to do here is to check specifically for EPERM and log something ala "Failed to overwrite the old server executable. Are there instances currently running?". Needing to update RA while it's running seems like a niche case to me.

@lnicola
Copy link
Member Author

lnicola commented Jul 12, 2021

Yeah, I'd agree, but this seems to bother a lot of people. So while it's not a full solution, at least it might take us 90% of the way there.

@wxb1ank
Copy link
Contributor

wxb1ank commented Jul 12, 2021

Well, the code LGTM otherwise. The first Google result I found on this topic implied this couldn't be done, but this suggests otherwise? I'll try and test this later today or tomorrow.

editors/code/src/net.ts Outdated Show resolved Hide resolved
@wxb1ank
Copy link
Contributor

wxb1ank commented Jul 12, 2021

I tested with two VS Code windows open. One was running RA in the background while the other attempted to update.

DEBUG [7/12/2021, 5:57:01 PM]: Downloading file of 254131 bytes size from https://github.com/rust-analyzer/rust-analyzer/releases/download/nightly/rust-analyzer.vsix to c:\Users\wxblank\AppData\Roaming\Code\User\globalStorage\matklad.rust-analyzer\rust-analyzer169d3161c8
ERROR [7/12/2021, 5:57:02 PM]: Cannot rename running instance: EntryNotFound (FileSystemError) (FileSystemError): Error: ENOENT: no such file or directory, rename 'c:\Users\wxblank\AppData\Roaming\Code\User\globalStorage\matklad.rust-analyzer\rust-analyzer.vsix' -> 'c:\Users\wxblank\AppData\Roaming\Code\User\globalStorage\matklad.rust-analyzer\rust-analyzer-stale-169d3161c8.vsix'
ERROR [7/12/2021, 5:57:02 PM]: Bootstrap error [Error: ENOENT: no such file or directory, open 'c:\Users\wxblank\AppData\Roaming\Code\User\globalStorage\matklad.rust-analyzer\rust-analyzer.vsix',    at h (file:///C:/Program Files/Microsoft VS Code/resources/app/out/vs/code/electron-browser/sharedProcess/sharedProcessMain.js:54:176162),    at file:///C:/Program Files/Microsoft VS Code/resources/app/out/vs/code/electron-browser/sharedProcess/sharedProcessMain.js:54:177561,    at C:\Program Files\Microsoft VS Code\resources\app\node_modules.asar\yauzl\index.js:34:21,    at FSReqCallback.oncomplete (fs.js:171:23)]

https://github.com/rust-analyzer/rust-analyzer/blob/5280b6d84c4fc727d055b02239d631963264cb2b/editors/code/src/net.ts#L127
It seems this doesn't work. VS Code docs strike again! EntryNotFound was thrown instead of the expected FileNotFound. We could just hardcode the first one instead, but I think a more resilient solution is as follows:

  1. Catch and ignore this particular error.
  2. Catch and handle the error from replacing the old binary with the new, downloaded one. Currently, we don't catch this one at all, and I think it's the reason I logged a bootstrap error. However, I'm a little confused why I get an error at all.

@wxb1ank
Copy link
Contributor

wxb1ank commented Jul 12, 2021

With the following:

// Try to rename a running server to avoid EPERM on Windows
// NB: this can lead to issues if a running Code instance tries to restart the server.
try {
    await vscode.workspace.fs.rename(opts.dest, oldServerPath, { overwrite: true });
    log.info(`Renamed old server binary ${opts.dest.fsPath} to ${oldServerPath.fsPath}`);
} catch (err) {

}

try {
    await vscode.workspace.fs.rename(tempFilePath, opts.dest, { overwrite: true });
} catch (err) {
    log.error(`Failed to replace the old binary with the new one: ${err}`);
}

I no longer receive the previous error, and the update seems to go smoothly (with the old RA instance still active).

@lnicola
Copy link
Member Author

lnicola commented Jul 13, 2021

I ended up checking for both, to avoid showing an error when there's no existing binary, but still complain when something happens. Of course vscode.workspace.fs.stat also throws on missing files.

Also, thanks a lot for giving this a try!

@lnicola lnicola marked this pull request as ready for review July 13, 2021 06:12
@lnicola
Copy link
Member Author

lnicola commented Jul 13, 2021

I think I want to merge this today so we can test it a little before next week (unless someone r-'es it, of course).

@matklad
Copy link
Member

matklad commented Jul 13, 2021

bors r+

@bors
Copy link
Contributor

bors bot commented Jul 13, 2021

@bors bors bot merged commit f6896f8 into rust-lang:master Jul 13, 2021
@lnicola lnicola deleted the rename-server-update branch July 13, 2021 11:13
@lnicola lnicola changed the title Rename the old server before update fix: Rename the old server before update Jul 13, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Failed to download: EPERM: operation not permitted
3 participants