Сочетание трио и колбы
Я пытаюсь создать HTTP API, который может создавать и уничтожать параллельные задачи, которые открывают TCP-соединения с удаленными серверами, передающими потоковые данные ~15 секунд. Я должен выяснить, как обрабатывать данные позже. Сейчас я просто распечатываю это.
В приведенном ниже примере я могу создать несколько соединений TCP, перейдя по http://192.168.1.1:5000/addconnection.
Вопросы:
1) Является ли этот подход разумным? Я думаю, что Flask может создавать новый поток для каждого запроса / addconnection. Я не уверен, какие ограничения производительности я достигну, делая это.
2) Можно ли отслеживать каждое соединение? Я хотел бы реализовать /listconnections и / removeconnections.
3) Есть ли более Pythonic способ сделать это? Я немного читал о сельдерее, но пока не очень хорошо понимаю. Возможно, есть другие уже существующие инструменты для решения подобных проблем.
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)
2 ответа
1) Вы создадите новый цикл обработки событий для каждого запроса /addconnection, который заблокирует время выполнения Flask. Это, вероятно, ограничит вас одним запросом на поток.
2) Да, в простейшем случае вы можете хранить их в глобальном наборе, см. connections
ниже.
3) Я автор Quart-Trio, который я считаю лучшим способом. Quart - это Flask API, заново реализованный с помощью async/await (который решает большую часть из 1)). Quart-Trio - это расширение для использования Trio, а не asyncio для Quart.
Примерно (и я не проверял это) ваш код становится,
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()
Вы можете протестировать свой сервер на pythonanywhere.com. Просто предложение.