semi graceful reload

606 views
Skip to first unread message

David Birdsong

unread,
Aug 27, 2010, 2:33:39 PM8/27/10
to python-...@googlegroups.com
I wrote up a handler to help me with graceful reloads. The idea is to
release the socket but let the ioloop finish handling requests in a
best effort manner. I have tornado hanging off of a supervisord, so
exiting '10' will trigger it to restart a new tornado -might be a
small delay there, but the socket should be free for the new tornado
to start up.

I think I have this right that the child will inherit all the fd's
without issue and continue to write out responses. Thirty seconds is
the best effort part. Any feedback?

class ReloadHandler(tornado.web.RequestHandler):
def get(self):
global http_server # this be defined in a global scope obviously,
is it accessible anywhere else from within the handler?
self.write('Reloading\n')
self.finish()

http_server.stop()
p = os.fork()
if p:
os._exit(10)
exit_at = time.time() + 30000 / 1000.0

loop = tornado.ioloop.IOLoop.instance()
loop.add_timeout(exit_at, functools.partial(sys.exit, 0))

Ben Darnell

unread,
Aug 27, 2010, 3:23:37 PM8/27/10
to python-...@googlegroups.com
On Fri, Aug 27, 2010 at 11:33 AM, David Birdsong
<david.b...@gmail.com> wrote:
> I wrote up a handler to help me with graceful reloads.  The idea is to
> release the socket but let the ioloop finish handling requests in a
> best effort manner.  I have tornado hanging off of a supervisord, so
> exiting '10' will trigger it to restart a new tornado -might be a
> small delay there, but the socket should be free for the new tornado
> to start up.
>
> I think I have this right that the child will inherit all the fd's
> without issue and continue to write out responses.  Thirty seconds is
> the best effort part.  Any feedback?

The socket file descriptors will be inherited, but there are issues
with inheriting epoll/kqueue objects across processes. For writes it
could be OK since the next time you produce output the fd will be
re-added to the IOLoop, but I think any reads in progress (for file
uploads, etc) could get dropped.

>
> class ReloadHandler(tornado.web.RequestHandler):
>  def get(self):
>    global http_server # this be defined in a global scope obviously,
> is it accessible anywhere else from within the handler?

No, I don't think it is. Maybe we could put it in as an attribute of
the HTTPRequest.

-Ben

Reply all
Reply to author
Forward
0 new messages