Вот код воспроизведения:
Код: Выделить всё
import time
from fastapi import FastAPI
from concurrent.futures import ThreadPoolExecutor
import asyncio
import os
import random
app = FastAPI()
executor = ThreadPoolExecutor(max_workers=1)
loop = asyncio.get_event_loop()
class SomeClass():
def task(self):
random_time = random.randint(2000, 3000) / 1000
time.sleep(random_time)
return f"process id: {os.getpid()}"
@app.get("/test")
async def test():
instance = SomeClass()
result = await loop.run_in_executor(executor, instance.task)
print(result)
return result
Код: Выделить всё
uvicorn --workers 2 main:app
Код: Выделить всё
for i in {1..20}; do curl http://127.0.0.1:8000/test &; done
- ~10 запросов обрабатываются 1-м работником
- ~10 запросов обрабатываются вторым работником.
- общее время ок. 25 секунд
- 14 запросов обрабатываются 1-м работником
- 6 запросов обрабатываются 2-м работником
- общее время ок. 35 сек.
Код: Выделить всё
process id: 56017
process id: 56016
process id: 56017
process id: 56016
process id: 56017
process id: 56016
process id: 56017
process id: 56016
process id: 56017
process id: 56016
process id: 56017
process id: 56017
process id: 56017
process id: 56017
process id: 56017
process id: 56017
process id: 56017
process id: 56017
process id: 56017
Большое спасибо!
РЕДАКТИРОВАТЬ: Я прочитал ваше замечание о том, что time.sleep блокирует цикл событий, но у меня та же проблема, когда я запускаю функцию блокировки в потоке asyncio. Итак, я отредактировал свой код и выходные данные, чтобы отразить это.
Подробнее здесь: https://stackoverflow.com/questions/777 ... rn-workers