【问题标题】:How to attend several request in parallel with twisted Klein如何与扭曲的克莱恩同时出席多个请求
【发布时间】:2019-01-27 17:58:57
【问题描述】:

我正在创建一个 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/ 中,但是,“运行”仍然是一个同步过程。我只是发布了我的主要和原始代码,以免与网页更改混淆。

最好的问候

【问题讨论】:

    标签: python api asynchronous twisted


    【解决方案1】:

    本例中与 Klein 相关的所有内容都已经在同时处理请求。但是,您的应用程序代码会阻塞,直到它完全响应请求。

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

    将您的代码从 subprocess 模块切换到 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 获得最终结果) .

    在您理解了 Deferred 之后,您可能想要考虑以 async/await 形式提供的语法糖。 直到你明白 Deferreds 是做什么的,async/await 只是一个黑魔法,只会在你的程序中偶然发生。

    【讨论】:

    • 您好,我已经尝试过使用 Deferred,但代码仍然被阻止。你能告诉我在我的代码中要改变什么吗?当我必须使用 await 关键字时,代码会阻止请求(逻辑上)。
    • 我不打算重写您的代码以使其正常工作。 “已经尝试过使用 Deferred”并没有告诉我太多。剩下的答案呢?您是否尝试过使用 Request.write?您是否尝试过使用 reactor.spawnProcess?
    • 我知道我在代码中丢失了几个关键字,我刚刚问过这个问题,但是,我已经尝试了很多与您提供的链接的组合,但代码仍然阻止执行.
    猜你喜欢
    • 2018-03-22
    • 2017-09-07
    • 1970-01-01
    • 2016-02-11
    • 2016-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多