0

I am running FastAPI app with gunicorn with the following config:

bind = 0.0.0.0:8080
worker_class = "uvicorn.workers.UvicornWorker"
workers = 3
loglevel = ServerConfig.LOG_LEVEL.lower()
max_requests = 1500
max_requests_jitter = 300
timeout = 120

Inside this app, I am doing some task (not very long running) every 0.5 seconds (through a Job Scheduler) and doing some processing on the data.

In that Job scheduler, I am calling "perform" method (See code below):

class BaseQueueConsumer:
    def __init__(self, threads: int):
        self._threads = threads
        self._executor = ThreadPoolExecutor(max_workers=1)

    def perform(self, param1, param2, param3) -> None:
        futures = []
        for _ in range(self._threads):
            futures.append(
                self._executor.submit(
                    BaseQueueConsumer.consume, param1, param2, param3
                )
            )

        for future in futures:
            future.done()

    @staticmethod
    def consume(param1, param2, param3) -> None:
        # Doing some work here

The problem is, whenever this app is under a high load, I am getting the following error:

cannot schedule new futures after shutdown

My guess is that the gunicorn process restarts every 1500 requests (max_requests) and the tasks that are already submitted are causing this issue. What I am not able to understand is that whatever thread gunicorn process starts due to threadpoolexecutor should also end when the process is terminated but that is not the case.

Can someone help me explain this behaviour and a possible solution for gracefully ending the gunicorn process without these threadpoolexecutor tasks causing errors?

I am using python 3.8 and gunicorn 0.15.0

Ankit Arora
  • 110
  • 3
  • 16
  • Does this answer your question? [FastAPI runs api-calls in serial instead of parallel fashion](https://stackoverflow.com/questions/71516140/fastapi-runs-api-calls-in-serial-instead-of-parallel-fashion) – Chris Feb 14 '23 at 17:08
  • Hi @Chris I tried following the above link but it wasn't really helpful. I am specifically looking for a thread pool executor inside a gunicorn process and what happens if the process ends – Ankit Arora Feb 14 '23 at 17:40

0 Answers0