Tornado 异步读取多个文件
Asynchronous reading of multiple files in Tornado
我正在尝试为通过 WebSocket 向一系列客户端广播信息的服务器构建一个微型状态监视器。为此,我正在阅读使用 tornado.process.Subprocess
的几个命令的输出以及 /proc/
目录下的各种文件。我想知道如何异步读取不同命令的输出,更新 WebSocket 通道将广播给客户端的值字典。
我尝试使用 gen.coroutine
和 yield
数组,其中包含每个 Subprocess
调用 returns 的所有 DummyFuture
对象,不幸的是无济于事。这是我的代码的简化版本:
def get_data(*args, **kwargs):
response_dict = {}
fd_uname = process.Subprocess("uname -r", shell=True, stdout=process.Subprocess.STREAM).stdout
f_uname = fd_uname.read_until_close() # A DummyFuture is generated
fd_uptime = process.Subprocess("uptime | tail -n 1 | awk '{print }'", shell=True, stdout=subprocess.PIPE).stdout
f_uptime.read_until_close()
# In the end, the results will be stored as entries of response_dict
data_dict = {}
def process_data():
result = get_data() # The goal is to run this function asynchronously
data_dict = result
open_ws = set()
class WebSocketIndexHandler(websocket.WebSocketHandler):
def open(self):
open_ws.add(self)
self.callback = PeriodicCallback(self.send_data, 1000)
self.callback.start()
start_callback()
def send_data(self):
self.write_message(data_dict)
def on_close(self):
self.callback.stop()
open_ws.remove(self)
ProcessCallback(get_data, 1000)
我想到了使用read_until_close
的callback
参数作为解决方案,将另一个回调参数分配给get_data
),当所有其他期货成功解析时将被调用,但我发现该解决方案相当麻烦。
提前致谢!
要从另一个协程调用协程,您需要 Python 3.5+ 中的 "async def" 和 "await",或者 "gen.coroutine" 和 "yield"。这是现代语法:
async def get_data(*args, **kwargs):
response_dict = {}
fd_uname = process.Subprocess("uname -r", shell=True, stdout=process.Subprocess.STREAM).stdout
uname_result = await fd_uname.read_until_close()
fd_uptime = process.Subprocess("uptime | tail -n 1 | awk '{print }'", shell=True, stdout=subprocess.PIPE).stdout
uptime_result = await f_uptime.read_until_close()
# In the end, the results will be stored as entries of response_dict
return response_dict
async def process_data():
result = await get_data() # The goal is to run this function asynchronously
# Now do something with the result....
Make sure you import subprocess from tornado, of course, not from the standard library.
有关详细信息,请参阅我的 Refactoring Tornado Coroutines or the Tornado coroutine guide。
我正在尝试为通过 WebSocket 向一系列客户端广播信息的服务器构建一个微型状态监视器。为此,我正在阅读使用 tornado.process.Subprocess
的几个命令的输出以及 /proc/
目录下的各种文件。我想知道如何异步读取不同命令的输出,更新 WebSocket 通道将广播给客户端的值字典。
我尝试使用 gen.coroutine
和 yield
数组,其中包含每个 Subprocess
调用 returns 的所有 DummyFuture
对象,不幸的是无济于事。这是我的代码的简化版本:
def get_data(*args, **kwargs):
response_dict = {}
fd_uname = process.Subprocess("uname -r", shell=True, stdout=process.Subprocess.STREAM).stdout
f_uname = fd_uname.read_until_close() # A DummyFuture is generated
fd_uptime = process.Subprocess("uptime | tail -n 1 | awk '{print }'", shell=True, stdout=subprocess.PIPE).stdout
f_uptime.read_until_close()
# In the end, the results will be stored as entries of response_dict
data_dict = {}
def process_data():
result = get_data() # The goal is to run this function asynchronously
data_dict = result
open_ws = set()
class WebSocketIndexHandler(websocket.WebSocketHandler):
def open(self):
open_ws.add(self)
self.callback = PeriodicCallback(self.send_data, 1000)
self.callback.start()
start_callback()
def send_data(self):
self.write_message(data_dict)
def on_close(self):
self.callback.stop()
open_ws.remove(self)
ProcessCallback(get_data, 1000)
我想到了使用read_until_close
的callback
参数作为解决方案,将另一个回调参数分配给get_data
),当所有其他期货成功解析时将被调用,但我发现该解决方案相当麻烦。
提前致谢!
要从另一个协程调用协程,您需要 Python 3.5+ 中的 "async def" 和 "await",或者 "gen.coroutine" 和 "yield"。这是现代语法:
async def get_data(*args, **kwargs):
response_dict = {}
fd_uname = process.Subprocess("uname -r", shell=True, stdout=process.Subprocess.STREAM).stdout
uname_result = await fd_uname.read_until_close()
fd_uptime = process.Subprocess("uptime | tail -n 1 | awk '{print }'", shell=True, stdout=subprocess.PIPE).stdout
uptime_result = await f_uptime.read_until_close()
# In the end, the results will be stored as entries of response_dict
return response_dict
async def process_data():
result = await get_data() # The goal is to run this function asynchronously
# Now do something with the result....
Make sure you import subprocess from tornado, of course, not from the standard library.
有关详细信息,请参阅我的 Refactoring Tornado Coroutines or the Tornado coroutine guide。