结合三重奏和烧瓶

时间:2019-03-08 18:26:55

标签: python-trio

我正在尝试创建一个HTTP API,该API可以创建和销毁并发任务,这些任务打开与流约15秒数据的远程服务器的TCP连接。我将不得不弄清楚以后如何处理数据。现在,我只打印它。

在下面的示例中,我可以通过导航到http://192.168.1.1:5000/addconnection来创建多个TCP连接。

问题:

1)这种方法合理吗?我认为Flask可能会为每个/ addconnection请求创建一个新线程。我不确定这样做会遇到什么性能限制。

2)是否可以跟踪每个连接?我想实现/ listconnections和/ removeconnections。

3)还有更多的Python方式可以做到这一点吗?我已经阅读了一些有关芹菜的知识,但是我还不太了解。也许还有其他用于解决类似问题的工具。

import trio
from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World!"


@app.route("/addconnection")
def addconnection():

    async def receiver(client_stream):
        print("Receiver: started!")
        while True:
            data = await client_stream.receive_some(16800)
            print("Received Data: {}".format(data))

    async def parent():
        async with trio.open_nursery() as nursery:
            client_stream = await trio.open_tcp_stream('192.168.1.1', 1234)
            nursery.start_soon(receiver, client_stream)

    trio.run(parent)

1 个答案:

答案 0 :(得分:2)

1)您将为每个/ addconnection请求创建一个新的事件循环,这将阻止Flask运行时。这可能会将您限制为每个线程一个请求。

2)是,在最简单的情况下,您可以将它们存储在全局集中,请参见下面的connections

3)我是Quart-Trio的作者,我认为这是一种更好的方法。 Quart是使用async / await(解决了大多数问题)重新实现的Flask API。 Quart-Trio是对Triart使用Trio而非asyncio的扩展。

大致(并且我尚未测试过)您的代码成为

import trio
from quart_trio import QuartTrio

connections = set()

app = QuartTrio(__name__)

@app.route("/")
async def hello():
    return "Hello World!"


@app.route("/addconnection")
async def addconnection():

    async def receiver(client_stream):
        print("Receiver: started!")
        while True:
            data = await client_stream.receive_some(16800)
            print("Received Data: {}".format(data))

    async def parent():
        async with trio.open_nursery() as nursery:
            client_stream = await trio.open_tcp_stream('192.168.1.1', 1234)
            connections.add(client_stream)
            nursery.start_soon(receiver, client_stream)
        connections.remove(client_stream)

    app.nursery.start_soon(parent)
    return "Connection Created"

if __name__ == "__main__":
    # Allows this to run and serve via python script.py
    # For production use `hypercorn -k trio script:app`
    app.run()