How to handle RuntimeError("IOLoop is already running") ?

3,167 views
Skip to first unread message

黄魏

unread,
Aug 19, 2014, 11:13:17 PM8/19/14
to python-...@googlegroups.com
 File "/home/server_trunk/test/server/db/client.py", line 40, in _call_in_tornado
    return self.ioloop.run_sync(_coroutine)
  File "/usr/local/lib/python2.7/dist-packages/tornado/ioloop.py", line 413, in run_sync
    self.start()
  File "/usr/local/lib/python2.7/dist-packages/tornado/ioloop.py", line 704, in start
    raise RuntimeError("IOLoop is already running")

I have a HTTPServer, and start IOLoop in main.
When I need run_sync some gen.coroutine in web handle, the RuntimeError always be raise.
How to handle the error? and What the best pattern of wait coroutine in web handle?

Ben Darnell

unread,
Aug 20, 2014, 12:48:05 PM8/20/14
to Tornado Mailing List
On Tue, Aug 19, 2014 at 11:13 PM, 黄魏 <sir.hu...@gmail.com> wrote:
 File "/home/server_trunk/test/server/db/client.py", line 40, in _call_in_tornado
    return self.ioloop.run_sync(_coroutine)
  File "/usr/local/lib/python2.7/dist-packages/tornado/ioloop.py", line 413, in run_sync
    self.start()
  File "/usr/local/lib/python2.7/dist-packages/tornado/ioloop.py", line 704, in start
    raise RuntimeError("IOLoop is already running")

I have a HTTPServer, and start IOLoop in main.

run_sync is shorthand for starting and stopping the IOLoop; if you're starting the IOLoop in main you shouldn't also call run_sync. 
 
When I need run_sync some gen.coroutine in web handle, the RuntimeError always be raise.
How to handle the error? and What the best pattern of wait coroutine in web handle?

In general, any function that calls a coroutine should also be a coroutine and should use the 'yield' keyword.  See the docs at http://www.tornadoweb.org/en/stable/guide/coroutines.html
 

--
You received this message because you are subscribed to the Google Groups "Tornado Web Server" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python-tornad...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

黄魏

unread,
Aug 20, 2014, 11:04:39 PM8/20/14
to python-...@googlegroups.com, b...@bendarnell.com
tks for your reply.
in my app, I use msgpackrpc-python, it has `call` and `call_async` function to implement rpc call.
forgive me for obsession. `call_async` work well with tornado's coroutine, but i confused at `call` function how to integrated with coroutine.

def call(self, method, *args):
@tornado.gen.coroutine
def _coroutine():
ret = yield self.call_async(method, *args)
raise tornado.gen.Return(ret)
return self.ioloop.run_sync(_coroutine)

def call_async(self, method, *args):
future = self.client.call_async(method, *args)
return future

class TestHandler(RequestHandler):
@tornado.gen.coroutine
def get(self):
ret = yield call_async('sum',1,2) # it's ok

class TestHandler2(RequestHandler):
def get(self):
ret = call('sum', 1, 2) # it can be implemented ??





在 2014年8月21日星期四UTC+8上午12时48分05秒,Ben Darnell写道:

Ben Darnell

unread,
Aug 21, 2014, 9:53:32 AM8/21/14
to 黄魏, Tornado Mailing List
On Wed, Aug 20, 2014 at 11:04 PM, 黄魏 <sir.hu...@gmail.com> wrote:
tks for your reply.
in my app, I use msgpackrpc-python, it has `call` and `call_async` function to implement rpc call.
forgive me for obsession. `call_async` work well with tornado's coroutine, but i confused at `call` function how to integrated with coroutine.

While it's technically possible to do this (see how tornado.httpclient.HTTPClient does it by creating a new IOLoop to call run_sync on: https://github.com/tornadoweb/tornado/blob/master/tornado/httpclient.py#L54), it's probably not what you actually want.  To get the benefits of the event-driven concurrency model you must use asynchronous code everywhere, so in a tornado implementation of this protocol you probably want to leave the synchronous version of call() unimplemented and use call_async everywhere instead.

-Ben
Reply all
Reply to author
Forward
0 new messages