diff --git a/gunicorn_config.py b/gunicorn_config.py index 62223af54..c4844df4b 100644 --- a/gunicorn_config.py +++ b/gunicorn_config.py @@ -2,6 +2,8 @@ import os import sys import traceback import gunicorn +import eventlet +import socket from gds_metrics.gunicorn import child_exit # noqa @@ -30,3 +32,22 @@ def on_exit(server): def worker_int(worker): worker.log.info("worker: received SIGINT {}".format(worker.pid)) + + +def fix_ssl_monkeypatching(): + """ + eventlet works by monkey-patching core IO libraries (such as ssl) to be non-blocking. However, there's currently + a bug: In the normal socket library it may throw a timeout error as a `socket.timeout` exception. However + eventlet.green.ssl's patch raises an ssl.SSLError('timed out',) instead. redispy handles socket.timeout but not + ssl.SSLError, so we solve this by monkey patching the monkey patching code to raise the correct exception type + :scream: + + https://github.com/eventlet/eventlet/issues/692 + """ + # this has probably already been called somewhere in gunicorn internals, however, to be sure, we invoke it again. + # eventlet.monkey_patch can be called multiple times without issue + eventlet.monkey_patch() + eventlet.green.ssl.timeout_exc = socket.timeout + + +fix_ssl_monkeypatching()