Configure different timeouts in gunicorn for different endpoints?
Asked Answered
P

2

27

Gunicorn allows configuring a timeout for requests, as demonstrated in their documentation below. This seems to be a global configuration for the entire application.

Is it possible to configure different timeouts for different endpoints? Perhaps overriding the default timeout on url endpoints that are known to take a long time?

http://docs.gunicorn.org/en/stable/settings.html#timeout

timeout

-t INT, --timeout INT

30

Workers silent for more than this many seconds are killed and restarted.

Generally set to thirty seconds. Only set this noticeably higher if you’re sure of the repercussions for sync workers. For the non sync workers it just means that the worker process is still communicating and is not tied to the length of time required to handle a single request.

Pampas answered 20/7, 2017 at 16:20 Comment(1)
This issue is quite old and I don't know if things has changed from then but anyway this is the closest thing I could find: github.com/benoitc/gunicorn/issues/724Ster
B
2

There is no easy way to do what you want to do. Probably the best option is to package each endpoint into a separate application, and then launch them with their own separate gunicorn processes / workers with the appropriate timeouts. Then put something like nginx to proxy the endpoints to different gunicorn processes.

Biogenesis answered 22/12, 2020 at 18:31 Comment(0)
J
0

I dont know this is a good solution or not. But I did something like this:

  1. install gevent :
pip install gevent
  1. create a custom worker for gunicorn:
# gunicorn_config.py

import gevent
from gunicorn.workers.ggevent import GeventWorker

ADMIN_TIMEOUT = 30  # second
API_TIMEOUT = 5


class CustomWorker(GeventWorker):
    def handle_request(self, listener_name, req, sock, addr):
        try:
            if req.path.startswith('/admin'):
                timeout = ADMIN_TIMEOUT
            else:
                timeout = API_TIMEOUT
           
            with gevent.Timeout(timeout):
                super().handle_request(listener_name, req, sock, addr)
        except gevent.GreenletExit:
            pass
        except SystemExit:
            pass
        except gevent.timeout.Timeout:
            print(f'timeout for {req.path}')
            raise StopIteration()

  1. run gunicorn:
gunicorn --bind 0.0.0.0:8000 MyProject.wsgi -k 'gunicorn_config.CustomWorker'
Jackshaft answered 9/2 at 23:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.