Upgrade improvements and refactor shutdown process #20

Closed
alexliebowitz wants to merge 7 commits from upgrades-2 into master
alexliebowitz commented 2017-03-22 12:38:21 +01:00 (Migrated from github.com)
  • Manually call xdg-open instead of using shell.openItem(), which doesn't reliably work from the main process
  • If there's a connection error or timeout when asking the daemon to close, fall back on trying to force kill any copies of the daemon that are running

Outstanding issues before ready to merge:

  • Finish testing
  • Try on Windows (all of the known issues have to do with the logic of killing the daemon and restarting, so there shouldn't be anything huge that comes up here)
    • Will need to have Jack help get a dev install going on a Windows VM. Haven't done that since we switched to Electron
  • xdg-open doesn't work reliably if you're not the same user as the package manager. shell.openItem() would have the same problem as it ultimately just calls xdg-open. We should probably at least detect this scenario and do something different, e.g. reveal the file instead of open it, and display a notice that you'll have to click the file to start the upgrade.
    • This is an independent thing and isn't blocking merge.
- Manually call `xdg-open` instead of using `shell.openItem()`, which doesn't reliably work from the main process - If there's a connection error or timeout when asking the daemon to close, fall back on trying to force kill any copies of the daemon that are running Outstanding issues before ready to merge: - Finish testing - Try on Windows (all of the known issues have to do with the logic of killing the daemon and restarting, so there shouldn't be anything huge that comes up here) - Will need to have Jack help get a dev install going on a Windows VM. Haven't done that since we switched to Electron - `xdg-open` doesn't work reliably if you're not the same user as the package manager. `shell.openItem()` would have the same problem as it ultimately just calls xdg-open. We should probably at least detect this scenario and do something different, e.g. reveal the file instead of open it, and display a notice that you'll have to click the file to start the upgrade. - This is an independent thing and isn't blocking merge.
lyoshenka (Migrated from github.com) reviewed 2017-03-23 16:31:26 +01:00
@ -89,2 +173,4 @@
}
// Quit when all windows are closed.
lyoshenka (Migrated from github.com) commented 2017-03-23 16:30:02 +01:00

does this work on osx and windows? or is this only called on linux?

does this work on osx and windows? or is this only called on linux?
lyoshenka (Migrated from github.com) commented 2017-03-23 16:31:16 +01:00

also, i find it hard to believe that we cant tell whether this worked or failed

also, i find it hard to believe that we cant tell whether this worked or failed
lyoshenka (Migrated from github.com) commented 2017-03-23 16:17:39 +01:00

wait, so this will to force-kill all daemons no matter what, even if the appropriate daemon was stopped successfully?

wait, so this will to force-kill all daemons no matter what, even if the appropriate daemon was stopped successfully?
alexliebowitz (Migrated from github.com) reviewed 2017-03-23 17:06:17 +01:00
@ -89,2 +173,4 @@
}
// Quit when all windows are closed.
alexliebowitz (Migrated from github.com) commented 2017-03-23 17:06:17 +01:00

It's called everywhere, but yesterday I factored this out and made it choose the command based on OS. That'll go up with my next set of changes.

Re: checking if it worked or failed, we can detect some failure conditions (where the installer or package manager completely fails to launch, arguably the least likely scenario) by seeing if the process returns with an error status code. But we can't detect anything that happens after that, like getting that weird dialog box because of a user mismatch. But you're right, I'll add a check for an error code.

It's called everywhere, but yesterday I factored this out and made it choose the command based on OS. That'll go up with my next set of changes. Re: checking if it worked or failed, we can detect _some_ failure conditions (where the installer or package manager completely fails to launch, arguably the least likely scenario) by seeing if the process returns with an error status code. But we can't detect anything that happens after that, like getting that weird dialog box because of a user mismatch. But you're right, I'll add a check for an error code.
alexliebowitz (Migrated from github.com) reviewed 2017-03-23 17:16:24 +01:00
alexliebowitz (Migrated from github.com) commented 2017-03-23 17:16:24 +01:00

The problem is that we don't know which one is the appropriate one, unless we launched it, which we didn't necessarily.

We talked about finding the process listening on 5279 instead, but we don't want to risk killing someone else's process.

Hmm... what if we combined both: we keep this code to get a list of pids for all running lbrynet-daemons, then find the process listening on 5279, confirm it's in the list of daemon pids, then kill just that one? That should handle every scenario except the case where someone made their own app that happens be called "lbrynet-daemon" and also runs on 5279, in which case it's kind of their problem :P

The problem is that we don't know which one is the appropriate one, unless we launched it, which we didn't necessarily. We talked about finding the process listening on 5279 instead, but we don't want to risk killing someone else's process. Hmm... what if we combined both: we keep this code to get a list of pids for all running lbrynet-daemons, then find the process listening on 5279, confirm it's in the list of daemon pids, then kill just that one? That should handle every scenario except the case where someone made their own app that happens be called "lbrynet-daemon" and also runs on 5279, in which case it's kind of their problem :P
lyoshenka (Migrated from github.com) reviewed 2017-03-23 18:58:11 +01:00
lyoshenka (Migrated from github.com) commented 2017-03-23 18:58:11 +01:00

im still confused. we have client, which is the connection to the daemon that we use for everything. we call daemon_stop on it. your comment says we could get an error because the daemon is already stopped. if the daemon is already stopped, then we're good, right? why do we then try to kill all the running daemons?

im still confused. we have `client`, which is the connection to the daemon that we use for everything. we call `daemon_stop` on it. your comment says `we could get an error because the daemon is already stopped`. if the daemon is already stopped, then we're good, right? why do we then try to kill all the running daemons?
lyoshenka (Migrated from github.com) reviewed 2017-03-23 18:58:56 +01:00
@ -89,2 +173,4 @@
}
// Quit when all windows are closed.
lyoshenka (Migrated from github.com) commented 2017-03-23 18:58:56 +01:00

gotcha

gotcha
alexliebowitz (Migrated from github.com) reviewed 2017-03-23 19:20:55 +01:00
alexliebowitz (Migrated from github.com) commented 2017-03-23 19:20:55 +01:00

It could be either way. The daemon process could be open but still it's refusing connections, or timing out, or giving 500 errors. Even if the error is "connection refused," it could be frozen but still have the port bound. There's no way to know for sure, just from the response to that call, whether we successfully killed it. But we could get pretty much the same effect by looking at all running processes called "lbrynet-daemon" and finding the one that is listening on 5279 (if any).

On a related note, even in the case where we spawned the daemon ourselves, we don't know if that's the one that we're talking to. I believe jayson does a separate HTTP request for every call, so it's possible that we started the daemon, it crashed, and the user manually started a new one.

It could be either way. The daemon process could be open but still it's refusing connections, or timing out, or giving 500 errors. Even if the error is "connection refused," it could be frozen but still have the port bound. There's no way to know for sure, just from the response to that call, whether we successfully killed it. But we could get pretty much the same effect by looking at all running processes called "lbrynet-daemon" and finding the one that is listening on 5279 (if any). On a related note, even in the case where we spawned the daemon ourselves, we don't know if that's the one that we're talking to. I believe jayson does a separate HTTP request for every call, so it's possible that we started the daemon, it crashed, and the user manually started a new one.
alexliebowitz (Migrated from github.com) reviewed 2017-03-24 00:42:29 +01:00
@ -65,3 +121,4 @@
app.on('ready', function(){
launchDaemonIfNotRunning();
alexliebowitz (Migrated from github.com) commented 2017-03-24 00:42:29 +01:00

We could probably use Promises to simplify the shutdown process so we're not calling quitNow in so many places, but for now my goal is to make the logic extremely explicit and easy to reason about.

We could probably use Promises to simplify the shutdown process so we're not calling quitNow in so many places, but for now my goal is to make the logic extremely explicit and easy to reason about.
lyoshenka (Migrated from github.com) reviewed 2017-03-24 02:39:55 +01:00
lyoshenka (Migrated from github.com) commented 2017-03-24 02:39:55 +01:00

You sure about that last part? I'm pretty sure that if the daemon crashes, the app will close. See https://github.com/lbryio/lbry-app/blob/master/app/main.js#L46

You sure about that last part? I'm pretty sure that if the daemon crashes, the app will close. See https://github.com/lbryio/lbry-app/blob/master/app/main.js#L46
lyoshenka (Migrated from github.com) reviewed 2017-03-24 02:51:36 +01:00
lyoshenka (Migrated from github.com) left a comment

didnt run this yet (tell me when its ready ready), but it definitely feels like you understand the shutdown process better

didnt run this yet (tell me when its ready ready), but it definitely feels like you understand the shutdown process better
@ -18,0 +53,4 @@
['/fi', `Imagename eq ${name}.exe`, '/nh'],
{encoding: 'utf8'}
).stdout;
return tasklistOut.match(/[^\n]+/g).map((line) => line.split(/\s+/)[1]); // Second column of every non-empty line
lyoshenka (Migrated from github.com) commented 2017-03-24 02:42:37 +01:00

What does this mean? Did not display?

What does this mean? `Did not display`?
@ -65,3 +121,4 @@
app.on('ready', function(){
launchDaemonIfNotRunning();
lyoshenka (Migrated from github.com) commented 2017-03-24 02:43:32 +01:00

is this cross-platform?

is this cross-platform?
@ -98,12 +184,15 @@ app.on('window-all-closed', () => {
lyoshenka (Migrated from github.com) commented 2017-03-24 02:45:40 +01:00

reminder to remove this before merging

reminder to remove this before merging
lyoshenka (Migrated from github.com) commented 2017-03-24 02:47:15 +01:00

we dont need this anymore?

we dont need this anymore?
lyoshenka (Migrated from github.com) commented 2017-03-24 02:48:34 +01:00

should now be msi?

should now be msi?
alexliebowitz (Migrated from github.com) reviewed 2017-03-24 02:58:11 +01:00
alexliebowitz (Migrated from github.com) commented 2017-03-24 02:58:11 +01:00

Good point. Scratch that part. (Not sure if that actually means anything needs to change with the logic here, though.)

Good point. Scratch that part. (Not sure if that actually means anything needs to change with the logic here, though.)
alexliebowitz (Migrated from github.com) reviewed 2017-03-24 03:01:18 +01:00
@ -18,0 +53,4 @@
['/fi', `Imagename eq ${name}.exe`, '/nh'],
{encoding: 'utf8'}
).stdout;
return tasklistOut.match(/[^\n]+/g).map((line) => line.split(/\s+/)[1]); // Second column of every non-empty line
alexliebowitz (Migrated from github.com) commented 2017-03-24 03:01:18 +01:00

No idea where that came from. Maybe just a copy-and-paste error. I meant for it to say something like "did not intentionally quit daemon, so scheduling quit."

No idea where that came from. Maybe just a copy-and-paste error. I meant for it to say something like "did not intentionally quit daemon, so scheduling quit."
alexliebowitz (Migrated from github.com) reviewed 2017-03-24 03:06:26 +01:00
alexliebowitz (Migrated from github.com) commented 2017-03-24 03:06:26 +01:00

I was going on Job's old comment about how the installer is now an MSI (deleted in this PR). But I guess that was written before we switched to Electron, and we're back to an exe.

I was going on Job's old comment about how the installer is now an MSI (deleted in this PR). But I guess that was written before we switched to Electron, and we're back to an exe.
alexliebowitz (Migrated from github.com) reviewed 2017-03-24 03:09:07 +01:00
@ -65,3 +121,4 @@
app.on('ready', function(){
launchDaemonIfNotRunning();
alexliebowitz (Migrated from github.com) commented 2017-03-24 03:09:07 +01:00

It'll work on Mac and Linux. Still thinking about Windows.

It'll work on Mac and Linux. Still thinking about Windows.
alexliebowitz (Migrated from github.com) reviewed 2017-03-24 03:29:20 +01:00
alexliebowitz (Migrated from github.com) commented 2017-03-24 03:29:20 +01:00

Nope. The UI used to request the quit after an upgrade, but it was moved into upgrade() here in the main process.

Nope. The UI used to request the quit after an upgrade, but it was moved into upgrade() here in the main process.
lyoshenka commented 2017-03-26 14:43:53 +02:00 (Migrated from github.com)

merged

merged

Pull request closed

Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: LBRYCommunity/lbry-desktop#20
No description provided.