【发布时间】:2019-03-16 21:39:44
【问题描述】:
采用标准 Tornado 演示并将 IOLoop 推入后台线程允许在单个脚本中查询服务器。这在 Tornado 服务器是交互式对象时很有用(参见 Dask 或类似内容)。
import asyncio
import requests
import tornado.ioloop
import tornado.web
from concurrent.futures import ThreadPoolExecutor
class MainHandler(tornado.web.RequestHandler):
def get(self):
self.write("Hello, world")
def make_app():
return tornado.web.Application([
(r"/", MainHandler),
])
pool = ThreadPoolExecutor(max_workers=2)
loop = tornado.ioloop.IOLoop()
app = make_app()
app.listen(8888)
fut = pool.submit(loop.start)
print(requests.get("https://localhost:8888"))
以上在标准 python 脚本中工作得很好(尽管它缺少安全关闭)。 Jupyter notebook 是这些交互式 Tornado 服务器环境的最佳环境。然而,当涉及到 Jupyter 时,这个想法就被打破了,因为已经有一个活跃的运行循环:
>>> import asyncio
>>> asyncio.get_event_loop()
<_UnixSelectorEventLoop running=True closed=False debug=False>
在 Jupyter 笔记本中运行上述脚本时会出现这种情况,服务器和请求客户端都试图在同一个线程中打开一个连接并且代码挂起。构建一个新的 Asyncio 循环和/或 Tornado IOLoop 似乎没有帮助,我怀疑我在 Jupyter 本身中遗漏了一些东西。
问题:是否可以在 Jupyter 笔记本的后台运行实时 Tornado 服务器,以便标准 python requests 或类似的可以从主线程连接到它?如果可能的话,我宁愿在呈现给用户的代码中避免使用 Asyncio,因为它对于新手用户来说相对复杂。
【问题讨论】:
标签: python tornado jupyter python-asyncio dask