Skip to content
This repository has been archived by the owner on Jul 5, 2023. It is now read-only.

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

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

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

danielb2 opened this issue Oct 10, 2012 · 12 comments
Labels

Comments

@danielb2
Copy link

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
Copy link
Owner

That's another place better documentation would help :)

genghisapp --kill

@danielb2
Copy link
Author

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.

@lazypower
Copy link

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

@bobthecow
Copy link
Owner

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

@danielb2
Copy link
Author

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
Copy link
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 ;)

@danielb2
Copy link
Author

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
Copy link
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.

@danielb2
Copy link
Author

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

@bobthecow
Copy link
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

@bobthecow bobthecow reopened this Feb 28, 2013
@danielb2
Copy link
Author

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

@bobthecow
Copy link
Owner

Done. Now I'll close this one :)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

3 participants