Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to limit or set size for the default ThreadPoolExecutor which be used to run blocking background task in FastAPI? #2961

Closed
Nohysiwe opened this issue Mar 18, 2021 · 9 comments
Labels
question Question or problem question-migrate

Comments

@Nohysiwe
Copy link

Nohysiwe commented Mar 18, 2021

I noticed that blocking background task was running in the default ThreadPoolExecutor for the current thread's asyncio.Eventloop, so how to limit or set size of the default ThreadPoolExecutor. :)

@Nohysiwe Nohysiwe added the question Question or problem label Mar 18, 2021
@Nohysiwe Nohysiwe changed the title How to limit or set size for the default ThreadPoolExecutor which be used to run blocking backgroud task in FastAPI? How to limit or set size for the default ThreadPoolExecutor which be used to run blocking background task in FastAPI? Mar 18, 2021
@insomnes
Copy link

@Nohysiwe
You can try to set default ThreadPoolExecutor in your main file

from concurrent.futures import ThreadPoolExecutor
import asyncio

loop = asyncio.get_running_loop()
loop.set_default_executor(ThreadPoolExecutor(max_workers=4))

@Nohysiwe
Copy link
Author

@insomnes
Thank you.

@Nohysiwe
Copy link
Author

Nohysiwe commented Mar 19, 2021

@insomnes
I think that using loop = asyncio.get_event_loop() is better than loop = asyncio.get_running_loop() in here.

@Nohysiwe Nohysiwe reopened this Mar 19, 2021
@Nohysiwe
Copy link
Author

And I find that I can use ProcessPoolExecutor same as ThreadPoolExecutor . But it's not a good idea when the app run with multi worker.

@Nohysiwe
Copy link
Author

@insomnes
I find that it's ineffective to set default ThreadPoolExecutor in main file. Because the loop used by uvicorn is from asyncio.new_event_loop(). It run after import my main file in the code of uvicorn.

# in uvicorn/loops/asyncio.py/asyncio_setup()
def asyncio_setup():
    if (
        sys.version_info.major >= 3
        and sys.version_info.minor >= 8
        and platform.system() == "Windows"
    ):
        selector = selectors.SelectSelector()
        loop = asyncio.SelectorEventLoop(selector)
        asyncio.set_event_loop(loop)
    else:
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)

@Nohysiwe Nohysiwe reopened this Mar 19, 2021
@Kludex
Copy link
Sponsor Collaborator

Kludex commented Mar 19, 2021

I'm not sure why are you doing this, but...

You can add the @insomnes logic inside of this: https://fastapi.tiangolo.com/advanced/events/?h=startup#startup-event

@Nohysiwe
Copy link
Author

Nohysiwe commented Mar 19, 2021

@Kludex
Thank you for your help :)

@tiangolo
Copy link
Owner

Thanks for the help here @insomnes and @Kludex ! 👏 🙇

Thanks for reporting back and closing the issue @Nohysiwe 👍

Sorry for the long delay! 🙈 I wanted to personally address each issue/PR and they piled up through time, but now I'm checking each one in order.

@Kludex
Copy link
Sponsor Collaborator

Kludex commented Nov 27, 2022

The answer for this question is a bit different at the moment, see encode/starlette#1724 (comment) for the answer.

@tiangolo tiangolo reopened this Feb 27, 2023
Repository owner locked and limited conversation to collaborators Feb 27, 2023
@tiangolo tiangolo converted this issue into discussion #6728 Feb 27, 2023

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
question Question or problem question-migrate
Projects
None yet
Development

No branches or pull requests

4 participants