Be able to shutdown/restart app from web interface #41

Closed
danielb2 opened this Issue Oct 10, 2012 · 12 comments

Comments

Projects
None yet
3 participants
@danielb2

When I checked the app now, it said there's a new version. But I had to grep for the pid to shut it down after updating the gem. It would be nice to just be able to restart/shutdown the app from the web interface.

@bobthecow

This comment has been minimized.

Show comment
Hide comment
@bobthecow

bobthecow Oct 10, 2012

Owner

That's another place better documentation would help :)

genghisapp --kill
Owner

bobthecow commented Oct 10, 2012

That's another place better documentation would help :)

genghisapp --kill
@danielb2

This comment has been minimized.

Show comment
Hide comment
@danielb2

danielb2 Oct 10, 2012

Documentation is to be avoided at all costs. Assume documentation will never be read :)

Make it obvious in the app.

I've read one book so now I'm an expert! (http://www.amazon.com/Design-Everyday-Things-Donald-Norman/dp/0465067107)

I use several apps that has the feature. It's nice.

Documentation is to be avoided at all costs. Assume documentation will never be read :)

Make it obvious in the app.

I've read one book so now I'm an expert! (http://www.amazon.com/Design-Everyday-Things-Donald-Norman/dp/0465067107)

I use several apps that has the feature. It's nice.

@chuckbutler

This comment has been minimized.

Show comment
Hide comment
@chuckbutler

chuckbutler Oct 16, 2012

Agreed - If i had full control over the app via the interface I would appreciate it that much more.

Agreed - If i had full control over the app via the interface I would appreciate it that much more.

@bobthecow

This comment has been minimized.

Show comment
Hide comment
@bobthecow

bobthecow Nov 24, 2012

Owner

I could shut down the app via the web interface, but restarting it is another story. How about something like this instead?

Owner

bobthecow commented Nov 24, 2012

I could shut down the app via the web interface, but restarting it is another story. How about something like this instead?

@danielb2

This comment has been minimized.

Show comment
Hide comment
@danielb2

danielb2 Nov 24, 2012

There are plenty of web apps that do this... check sickbeard.com, etc. Granted, they're in python, but you should be able to handle it. The display is definitely better than before tho :)

There are plenty of web apps that do this... check sickbeard.com, etc. Granted, they're in python, but you should be able to handle it. The display is definitely better than before tho :)

@bobthecow

This comment has been minimized.

Show comment
Hide comment
@bobthecow

bobthecow Nov 24, 2012

Owner

It's more a question of whether it's realistic than whether it's possible. Genghis runs as:

  • A PHP file under *AMP.
  • A PHP file with php-fpm.
  • A standalone PHP CLI app.
  • A standalone Sinatra app (ruby genghis.rb)
  • A Sinatra app via Rack.
  • A Sinatra app mounted in a subpath of other apps (e.g. Rails 3).
  • A standalone executable, which is simply a wrapper around the Sinatra app.
  • A daemonized version of the standalone executable.

Of all of these, the only one where an in-browser restart could both be supported and make sense is the last one, and then, only if it's not running under Windows because Windows has fork() issues.

And to top that all off, the "restart" would need to be supported by forking just after daemonizing, but before loading and starting the Sinatra app, and keeping both the parent and child thread around so when the child receives a "restart" command it could send a HUP to its parent which would then spawn off a new child process with the new code, and really what it comes down to is that one spot where it should all be supported is a different project and you ought to go ask them to add restart support ;)

Owner

bobthecow commented Nov 24, 2012

It's more a question of whether it's realistic than whether it's possible. Genghis runs as:

  • A PHP file under *AMP.
  • A PHP file with php-fpm.
  • A standalone PHP CLI app.
  • A standalone Sinatra app (ruby genghis.rb)
  • A Sinatra app via Rack.
  • A Sinatra app mounted in a subpath of other apps (e.g. Rails 3).
  • A standalone executable, which is simply a wrapper around the Sinatra app.
  • A daemonized version of the standalone executable.

Of all of these, the only one where an in-browser restart could both be supported and make sense is the last one, and then, only if it's not running under Windows because Windows has fork() issues.

And to top that all off, the "restart" would need to be supported by forking just after daemonizing, but before loading and starting the Sinatra app, and keeping both the parent and child thread around so when the child receives a "restart" command it could send a HUP to its parent which would then spawn off a new child process with the new code, and really what it comes down to is that one spot where it should all be supported is a different project and you ought to go ask them to add restart support ;)

@danielb2

This comment has been minimized.

Show comment
Hide comment
@danielb2

danielb2 Nov 24, 2012

I'm not sure what the difference between realistic and possible in this context is. Regardless, could the restart not simply be a system call which does: genghisapp --kill && genghisapp ?

Here's how sickbeard, a python app handles it:

def saveAndShutdown(restart=False):

    halt()

    saveAll()

    logger.log(u"Killing cherrypy")
    cherrypy.engine.exit()

    if CREATEPID:
        logger.log(u"Removing pidfile " + str(PIDFILE))
        os.remove(PIDFILE)

    if restart:
        install_type = versionCheckScheduler.action.install_type

        popen_list = []

        if install_type in ('git', 'source'):
            popen_list = [sys.executable, MY_FULLNAME]
        elif install_type == 'win':
            if hasattr(sys, 'frozen'):
                # c:\dir\to\updater.exe 12345 c:\dir\to\sickbeard.exe
                popen_list = [os.path.join(PROG_DIR, 'updater.exe'), str(PID), sys.executable]
            else:
                logger.log(u"Unknown SB launch method, please file a bug report about this", logger.
ERROR)
                popen_list = [sys.executable, os.path.join(PROG_DIR, 'updater.py'), str(PID), sys.executable, MY_FULLNAME ]

        if popen_list:
            popen_list += MY_ARGS
            if '--nolaunch' not in popen_list:
                popen_list += ['--nolaunch']
            logger.log(u"Restarting Sick Beard with " + str(popen_list))
            subprocess.Popen(popen_list, cwd=os.getcwd())

    os._exit(0)

I'm not sure what the difference between realistic and possible in this context is. Regardless, could the restart not simply be a system call which does: genghisapp --kill && genghisapp ?

Here's how sickbeard, a python app handles it:

def saveAndShutdown(restart=False):

    halt()

    saveAll()

    logger.log(u"Killing cherrypy")
    cherrypy.engine.exit()

    if CREATEPID:
        logger.log(u"Removing pidfile " + str(PIDFILE))
        os.remove(PIDFILE)

    if restart:
        install_type = versionCheckScheduler.action.install_type

        popen_list = []

        if install_type in ('git', 'source'):
            popen_list = [sys.executable, MY_FULLNAME]
        elif install_type == 'win':
            if hasattr(sys, 'frozen'):
                # c:\dir\to\updater.exe 12345 c:\dir\to\sickbeard.exe
                popen_list = [os.path.join(PROG_DIR, 'updater.exe'), str(PID), sys.executable]
            else:
                logger.log(u"Unknown SB launch method, please file a bug report about this", logger.
ERROR)
                popen_list = [sys.executable, os.path.join(PROG_DIR, 'updater.py'), str(PID), sys.executable, MY_FULLNAME ]

        if popen_list:
            popen_list += MY_ARGS
            if '--nolaunch' not in popen_list:
                popen_list += ['--nolaunch']
            logger.log(u"Restarting Sick Beard with " + str(popen_list))
            subprocess.Popen(popen_list, cwd=os.getcwd())

    os._exit(0)
@bobthecow

This comment has been minimized.

Show comment
Hide comment
@bobthecow

bobthecow Feb 28, 2013

Owner

Here's how Unicorn (a ruby webserver) handles it: https://github.com/defunkt/unicorn/blob/master/lib/unicorn/http_server.rb#L400-L455

It is possible to do this, but the functionality really belongs in Vegas, the library Genghis uses to run "as an app". Genghis doesn't have access to the pid, it doesn't know what command line arguments it was called with. From Genghis' point of view, it's just running as a sinatra app. All the details like this are handled by Vegas.

Owner

bobthecow commented Feb 28, 2013

Here's how Unicorn (a ruby webserver) handles it: https://github.com/defunkt/unicorn/blob/master/lib/unicorn/http_server.rb#L400-L455

It is possible to do this, but the functionality really belongs in Vegas, the library Genghis uses to run "as an app". Genghis doesn't have access to the pid, it doesn't know what command line arguments it was called with. From Genghis' point of view, it's just running as a sinatra app. All the details like this are handled by Vegas.

@bobthecow bobthecow closed this Feb 28, 2013

@danielb2

This comment has been minimized.

Show comment
Hide comment
@danielb2

danielb2 Feb 28, 2013

Out of curiousity, was anything filed with Vegas so you could potentially do this moving forward?

Out of curiousity, was anything filed with Vegas so you could potentially do this moving forward?

@bobthecow

This comment has been minimized.

Show comment
Hide comment
@bobthecow

bobthecow Feb 28, 2013

Owner

I did not. I'll re-open this issue so I remember to when I get a minute, or you can feel free to do it :)

The proper answer is probably for Vegas to trap SIGHUP and reload its configuration. Then a running process (e.g. Genghis) could signal this:

Process.kill 'HUP', Process.pid
Owner

bobthecow commented Feb 28, 2013

I did not. I'll re-open this issue so I remember to when I get a minute, or you can feel free to do it :)

The proper answer is probably for Vegas to trap SIGHUP and reload its configuration. Then a running process (e.g. Genghis) could signal this:

Process.kill 'HUP', Process.pid

@bobthecow bobthecow reopened this Feb 28, 2013

@danielb2

This comment has been minimized.

Show comment
Hide comment
@danielb2

danielb2 Feb 28, 2013

I would but I really don't feel I know enough about Vegas to know what I'm asking for :/

I would but I really don't feel I know enough about Vegas to know what I'm asking for :/

@bobthecow bobthecow referenced this issue in quirkey/vegas Feb 28, 2013

Open

Vegas should trap 'HUP' and restart. #18

@bobthecow

This comment has been minimized.

Show comment
Hide comment
@bobthecow

bobthecow Feb 28, 2013

Owner

Done. Now I'll close this one :)

Owner

bobthecow commented Feb 28, 2013

Done. Now I'll close this one :)

@bobthecow bobthecow closed this Feb 28, 2013

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment