python - 如何与扭曲的克莱恩同时出席多个请求
问题描述
我正在创建一个 API 来执行命令行命令。服务器实际上只有两种方法,“运行”和“停止”。所以,“运行”的主要功能是在服务器端运行一个命令行程序,并返回一个带有系统输出的列表。另一方面,“停止”功能只是杀死正在运行的进程。这是代码:
import sys
import json
import subprocess
from klein import Klein
class ItemStore(object):
app = Klein()
current_process = None
def __init__(self):
self._items = {}
def create_process(self, exe):
"""
Run command and return the system output inside a JSON string
"""
print("COMMAND: ", exe)
process = subprocess.Popen(exe, shell=True, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
self.current_process = process
# Poll process for new output until finished
output_lines = []
counter = 0
while True:
counter = counter + 1
nextline = process.stdout.readline()
if process.poll() is not None:
break
aux = nextline.decode("utf-8")
output_lines.append(aux)
sys.stdout.flush()
counter = counter + 1
print("RETURN CODE: ", process.returncode)
return json.dumps(output_lines)
@app.route('/run/<command>', methods=['POST'])
def run(self, request, command):
"""
Execute command line process
"""
exe = command
print("COMMAND: ", exe)
output_lines = self.create_process(exe)
request.setHeader("Content-Type", "application/json")
request.setResponseCode(200)
return output_lines
@app.route('/stop', methods=['POST'])
def stop(self, request):
"""
Kill current execution
"""
self.current_process.kill()
request.setResponseCode(200)
return None
if __name__ == '__main__':
store = ItemStore()
store.app.run('0.0.0.0', 15508)
好吧,这样的问题是,如果我需要停止当前的执行,“停止”请求将在“运行”请求完成之前不会出现,因此以这种方式工作是没有意义的。我已经阅读了几页关于 async/await 解决方案的内容,但我无法让它工作!我认为最突出的解决方案是在这个网页https://crossbario.com/blog/Going-Asynchronous-from-Flask-to-Twisted-Klein/,但是,“运行”仍然是一个同步过程。我刚刚发布了我的主要和原始代码,以免与网页更改混淆。
此致
解决方案
本例中与 Klein 相关的所有内容都已经在同时处理请求。但是,您的应用程序代码会阻塞,直到它完全响应请求。
您必须将应用程序代码编写为非阻塞而不是阻塞。
将您的代码从 subprocess 模块切换到Twisted 的 process support。
使用Klein 能够返回 Deferred 而不是结果的特性(如果您想要在进程运行时增加结果,还请查看请求接口- 特别是write
方法 - 这样您就可以在 Deferred 触发之前编写这些结果最终结果)。
在 Deferred 对您有意义之后,您可能想要考虑以 async/await 形式提供的语法糖。 在您了解 Deferreds 在做什么之前,async/await 只是一种黑魔法,只会在您的程序中偶然发生。
推荐阅读
- python - Python 将字典转换为数据框并将其导出到 csv 文件
- html - 反应不从网络源渲染我的图像
- spring - jhipster中的“这个实体是关系的所有者是什么意思”是什么意思
- prolog - 将目标作为参数传递?加上可变数量的参数?
- classification - 分类错误率决策可以小于0吗?什么时候它会正好是 0?
- .net - HTTP 错误 500.30 - ANCM 进程内启动失败 - 我在 IIS 服务器上本地部署 .NET Core 3.1 项目
- bash - 当包含在函数中时,bash extglob 模式匹配会中断
- python - Subprocess.run 和未知数量的文件,如何?
- javascript - onbeforeunload 在 Chrome 上的工作方式与在 Firefox 上的工作方式不同。我正在寻找任何潜在的替代品
- elasticsearch - 使用 ngram 分析器获取脏结果以进行高亮搜索