about summary refs log tree commit diff
path: root/.venv/lib/python3.12/site-packages/gunicorn/workers/ggevent.py
diff options
context:
space:
mode:
authorS. Solomon Darnell2025-03-28 21:52:21 -0500
committerS. Solomon Darnell2025-03-28 21:52:21 -0500
commit4a52a71956a8d46fcb7294ac71734504bb09bcc2 (patch)
treeee3dc5af3b6313e921cd920906356f5d4febc4ed /.venv/lib/python3.12/site-packages/gunicorn/workers/ggevent.py
parentcc961e04ba734dd72309fb548a2f97d67d578813 (diff)
downloadgn-ai-master.tar.gz
two version of R2R are here HEAD master
Diffstat (limited to '.venv/lib/python3.12/site-packages/gunicorn/workers/ggevent.py')
-rw-r--r--.venv/lib/python3.12/site-packages/gunicorn/workers/ggevent.py190
1 files changed, 190 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/gunicorn/workers/ggevent.py b/.venv/lib/python3.12/site-packages/gunicorn/workers/ggevent.py
new file mode 100644
index 00000000..2125a32d
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/gunicorn/workers/ggevent.py
@@ -0,0 +1,190 @@
+# -*- coding: utf-8 -
+#
+# This file is part of gunicorn released under the MIT license.
+# See the NOTICE for more information.
+
+import os
+import sys
+from datetime import datetime
+from functools import partial
+import time
+
+try:
+    import gevent
+except ImportError:
+    raise RuntimeError("gevent worker requires gevent 1.4 or higher")
+else:
+    from packaging.version import parse as parse_version
+    if parse_version(gevent.__version__) < parse_version('1.4'):
+        raise RuntimeError("gevent worker requires gevent 1.4 or higher")
+
+from gevent.pool import Pool
+from gevent.server import StreamServer
+from gevent import hub, monkey, socket, pywsgi
+
+import gunicorn
+from gunicorn.http.wsgi import base_environ
+from gunicorn.sock import ssl_context
+from gunicorn.workers.base_async import AsyncWorker
+
+VERSION = "gevent/%s gunicorn/%s" % (gevent.__version__, gunicorn.__version__)
+
+
+class GeventWorker(AsyncWorker):
+
+    server_class = None
+    wsgi_handler = None
+
+    def patch(self):
+        monkey.patch_all()
+
+        # patch sockets
+        sockets = []
+        for s in self.sockets:
+            sockets.append(socket.socket(s.FAMILY, socket.SOCK_STREAM,
+                                         fileno=s.sock.fileno()))
+        self.sockets = sockets
+
+    def notify(self):
+        super().notify()
+        if self.ppid != os.getppid():
+            self.log.info("Parent changed, shutting down: %s", self)
+            sys.exit(0)
+
+    def timeout_ctx(self):
+        return gevent.Timeout(self.cfg.keepalive, False)
+
+    def run(self):
+        servers = []
+        ssl_args = {}
+
+        if self.cfg.is_ssl:
+            ssl_args = {"ssl_context": ssl_context(self.cfg)}
+
+        for s in self.sockets:
+            s.setblocking(1)
+            pool = Pool(self.worker_connections)
+            if self.server_class is not None:
+                environ = base_environ(self.cfg)
+                environ.update({
+                    "wsgi.multithread": True,
+                    "SERVER_SOFTWARE": VERSION,
+                })
+                server = self.server_class(
+                    s, application=self.wsgi, spawn=pool, log=self.log,
+                    handler_class=self.wsgi_handler, environ=environ,
+                    **ssl_args)
+            else:
+                hfun = partial(self.handle, s)
+                server = StreamServer(s, handle=hfun, spawn=pool, **ssl_args)
+                if self.cfg.workers > 1:
+                    server.max_accept = 1
+
+            server.start()
+            servers.append(server)
+
+        while self.alive:
+            self.notify()
+            gevent.sleep(1.0)
+
+        try:
+            # Stop accepting requests
+            for server in servers:
+                if hasattr(server, 'close'):  # gevent 1.0
+                    server.close()
+                if hasattr(server, 'kill'):  # gevent < 1.0
+                    server.kill()
+
+            # Handle current requests until graceful_timeout
+            ts = time.time()
+            while time.time() - ts <= self.cfg.graceful_timeout:
+                accepting = 0
+                for server in servers:
+                    if server.pool.free_count() != server.pool.size:
+                        accepting += 1
+
+                # if no server is accepting a connection, we can exit
+                if not accepting:
+                    return
+
+                self.notify()
+                gevent.sleep(1.0)
+
+            # Force kill all active the handlers
+            self.log.warning("Worker graceful timeout (pid:%s)", self.pid)
+            for server in servers:
+                server.stop(timeout=1)
+        except Exception:
+            pass
+
+    def handle(self, listener, client, addr):
+        # Connected socket timeout defaults to socket.getdefaulttimeout().
+        # This forces to blocking mode.
+        client.setblocking(1)
+        super().handle(listener, client, addr)
+
+    def handle_request(self, listener_name, req, sock, addr):
+        try:
+            super().handle_request(listener_name, req, sock, addr)
+        except gevent.GreenletExit:
+            pass
+        except SystemExit:
+            pass
+
+    def handle_quit(self, sig, frame):
+        # Move this out of the signal handler so we can use
+        # blocking calls. See #1126
+        gevent.spawn(super().handle_quit, sig, frame)
+
+    def handle_usr1(self, sig, frame):
+        # Make the gevent workers handle the usr1 signal
+        # by deferring to a new greenlet. See #1645
+        gevent.spawn(super().handle_usr1, sig, frame)
+
+    def init_process(self):
+        self.patch()
+        hub.reinit()
+        super().init_process()
+
+
+class GeventResponse(object):
+
+    status = None
+    headers = None
+    sent = None
+
+    def __init__(self, status, headers, clength):
+        self.status = status
+        self.headers = headers
+        self.sent = clength
+
+
+class PyWSGIHandler(pywsgi.WSGIHandler):
+
+    def log_request(self):
+        start = datetime.fromtimestamp(self.time_start)
+        finish = datetime.fromtimestamp(self.time_finish)
+        response_time = finish - start
+        resp_headers = getattr(self, 'response_headers', {})
+        resp = GeventResponse(self.status, resp_headers, self.response_length)
+        if hasattr(self, 'headers'):
+            req_headers = self.headers.items()
+        else:
+            req_headers = []
+        self.server.log.access(resp, req_headers, self.environ, response_time)
+
+    def get_environ(self):
+        env = super().get_environ()
+        env['gunicorn.sock'] = self.socket
+        env['RAW_URI'] = self.path
+        return env
+
+
+class PyWSGIServer(pywsgi.WSGIServer):
+    pass
+
+
+class GeventPyWSGIWorker(GeventWorker):
+    "The Gevent StreamServer based workers."
+    server_class = PyWSGIServer
+    wsgi_handler = PyWSGIHandler