如何与扭曲的Klein同时参加几个请求

时间:2019-01-27 17:58:57

标签: python api asynchronous twisted

我正在创建一个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)

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

最诚挚的问候

1 个答案:

答案 0 :(得分:0)

在此示例中,与Klein有关的所有事情已在同时处理请求。但是,您的应用程序代码将阻塞,直到它完全响应请求为止。

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

将代码从子流程模块切换到Twisted's process support

使用Klein's feature of being able to return a Deferred instead of a result(如果您希望在进程运行时获得递增结果,请同时查看the request interface-特别是write方法-这样,您可以在write those results之前延期开火,最终结果)。

在Deferreds对您有意义之后,您可能需要考虑以async / await形式提供的语法糖。 直到,您才知道Deferreds在做什么,async / await只是一种黑魔法,只会在您的程序中偶然起作用。