如何与扭曲的克莱因并行处理多个请求



我正在创建一个API来执行命令行命令。服务器实际上只有两种方法,"运行"和"停止"。所以,"run"的主要功能是在服务器端运行一个命令行程序,并返回一个带有系统输出的列表。另一方面,"停止"功能只是杀死正在运行的进程。这是代码:

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)
好吧,这样做

的问题是,如果我需要停止当前执行,"停止"请求将不会参加,直到"运行"请求完成,因此以这种方式工作是没有意义的。我一直在阅读有关异步/等待解决方案的几页,但我无法让它工作!我认为最突出的解决方案是在这个网页 https://crossbario.com/blog/Going-Asynchronous-from-Flask-to-Twisted-Klein/,但是,"运行"仍然是一个同步过程。我只是发布了我的主要和原始代码,以免与网页更改混淆。

此致敬意

在这个例子中,与 Klein 相关的一切都已经并发处理请求。 但是,应用程序代码会阻止,直到它完全响应请求。

您必须将应用程序代码编写为非阻塞而不是阻塞。

将您的代码从子流程模块切换到 Twisted 的进程支持。

使用 Klein 能够返回延迟而不是结果的功能(如果您希望在进程运行时获得增量结果,请查看请求接口 - 特别是 write 方法 - 以便您可以在延迟触发之前编写这些结果并给出最终结果)。

在延迟对您有意义之后,您可能需要考虑以异步/等待形式提供的语法糖。 你了解 Deferreds 在做什么之前,async/await 只是黑魔法,只会在你的程序中偶然起作用。

最新更新