Use asynchronous tornado code in regular python script

I have some asynchronous functions using tornado gen.coroutine , which I usually use as part of a tornado-based web application. However, I want to call some of them from a plain old python script to perform some administrative tasks. How to do it?

 from tornado import gen import some_internal_stuff @gen.coroutine def myfunc(x): y = yield some_internal_stuff.another_async_func(x) raise gen.Return(y) if __name__ == "__main__": # What do I put here to call myfunc(1) and get the async return value? pass 

Update:

A more specific example:

 from tornado import gen @gen.coroutine def another_async_func(x): print "aaf" raise gen.Return(x + 1) @gen.coroutine def myfunc(x): print "myfunc" y = yield another_async_func(x) print "back" raise gen.Return(y) def callback(y): print "Callback called with %d" % y if __name__ == "__main__": myfunc(1, callback=callback) 

The execution of these outputs:

 myfunc aaf 
+6
source share
2 answers

There is a built-in IOLoop method in IOLoop to start a single call and then stop the loop, so it's pretty simple to add an event loop to a simple python script if you have a tornado in PYTHONPATH.

With a concrete example:

 from tornado import gen, ioloop @gen.coroutine def another_async_func(x): print "aaf" raise gen.Return(x + 1) @gen.coroutine def myfunc(x): print "myfunc" y = yield another_async_func(x) print "back" raise gen.Return(y) @gen.coroutine def main(): y = yield myfunc(1) print "Callback called with %d" % y if __name__ == "__main__": ioloop.IOLoop.instance().run_sync(main) 

It is output:

 myfunc aaf back Callback called with 2 

Note that run_sync poorly nested; if you call run_sync in a function called run_sync in the same IOLoop , then ending the internal call stops IOLoop and no further yield after returning the internal call.

+16
source

Here is another possibility, using threads that will work depending on the complexity of the problem and your needs:

 if __name__ == "__main__": import threading, time # The tornado IO loop doesn't need to be started in the main thread # so let start it in another thread: t = threading.Thread(target=IOLoop.instance().start) t.daemon = True t.start() myfunc(1, callback=callback) # now the main loop needs wait; you can do that by polling a value, sleeping, # or waiting on a lock. I've chosen to sleep here, but a lock is probably more # appropriate; and, once computation is done, release the lock. time.sleep(2) 
+1
source

Source: https://habr.com/ru/post/956993/


All Articles