about summary refs log tree commit diff
path: root/.venv/lib/python3.12/site-packages/gunicorn/workers/gtornado.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/gtornado.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/gtornado.py')
-rw-r--r--.venv/lib/python3.12/site-packages/gunicorn/workers/gtornado.py167
1 files changed, 167 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/gunicorn/workers/gtornado.py b/.venv/lib/python3.12/site-packages/gunicorn/workers/gtornado.py
new file mode 100644
index 00000000..28506119
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/gunicorn/workers/gtornado.py
@@ -0,0 +1,167 @@
+# -*- coding: utf-8 -
+#
+# This file is part of gunicorn released under the MIT license.
+# See the NOTICE for more information.
+
+import os
+import sys
+
+try:
+    import tornado
+except ImportError:
+    raise RuntimeError("You need tornado installed to use this worker.")
+import tornado.web
+import tornado.httpserver
+from tornado.ioloop import IOLoop, PeriodicCallback
+from tornado.wsgi import WSGIContainer
+from gunicorn.workers.base import Worker
+from gunicorn import __version__ as gversion
+from gunicorn.sock import ssl_context
+
+
+# Tornado 5.0 updated its IOLoop, and the `io_loop` arguments to many
+# Tornado functions have been removed in Tornado 5.0. Also, they no
+# longer store PeriodCallbacks in ioloop._callbacks. Instead we store
+# them on our side, and use stop() on them when stopping the worker.
+# See https://www.tornadoweb.org/en/stable/releases/v5.0.0.html#backwards-compatibility-notes
+# for more details.
+TORNADO5 = tornado.version_info >= (5, 0, 0)
+
+
+class TornadoWorker(Worker):
+
+    @classmethod
+    def setup(cls):
+        web = sys.modules.pop("tornado.web")
+        old_clear = web.RequestHandler.clear
+
+        def clear(self):
+            old_clear(self)
+            if "Gunicorn" not in self._headers["Server"]:
+                self._headers["Server"] += " (Gunicorn/%s)" % gversion
+        web.RequestHandler.clear = clear
+        sys.modules["tornado.web"] = web
+
+    def handle_exit(self, sig, frame):
+        if self.alive:
+            super().handle_exit(sig, frame)
+
+    def handle_request(self):
+        self.nr += 1
+        if self.alive and self.nr >= self.max_requests:
+            self.log.info("Autorestarting worker after current request.")
+            self.alive = False
+
+    def watchdog(self):
+        if self.alive:
+            self.notify()
+
+        if self.ppid != os.getppid():
+            self.log.info("Parent changed, shutting down: %s", self)
+            self.alive = False
+
+    def heartbeat(self):
+        if not self.alive:
+            if self.server_alive:
+                if hasattr(self, 'server'):
+                    try:
+                        self.server.stop()
+                    except Exception:
+                        pass
+                self.server_alive = False
+            else:
+                if TORNADO5:
+                    for callback in self.callbacks:
+                        callback.stop()
+                    self.ioloop.stop()
+                else:
+                    if not self.ioloop._callbacks:
+                        self.ioloop.stop()
+
+    def init_process(self):
+        # IOLoop cannot survive a fork or be shared across processes
+        # in any way. When multiple processes are being used, each process
+        # should create its own IOLoop. We should clear current IOLoop
+        # if exists before os.fork.
+        IOLoop.clear_current()
+        super().init_process()
+
+    def run(self):
+        self.ioloop = IOLoop.instance()
+        self.alive = True
+        self.server_alive = False
+
+        if TORNADO5:
+            self.callbacks = []
+            self.callbacks.append(PeriodicCallback(self.watchdog, 1000))
+            self.callbacks.append(PeriodicCallback(self.heartbeat, 1000))
+            for callback in self.callbacks:
+                callback.start()
+        else:
+            PeriodicCallback(self.watchdog, 1000, io_loop=self.ioloop).start()
+            PeriodicCallback(self.heartbeat, 1000, io_loop=self.ioloop).start()
+
+        # Assume the app is a WSGI callable if its not an
+        # instance of tornado.web.Application or is an
+        # instance of tornado.wsgi.WSGIApplication
+        app = self.wsgi
+
+        if tornado.version_info[0] < 6:
+            if not isinstance(app, tornado.web.Application) or \
+                    isinstance(app, tornado.wsgi.WSGIApplication):
+                app = WSGIContainer(app)
+        elif not isinstance(app, WSGIContainer) and \
+                not isinstance(app, tornado.web.Application):
+            app = WSGIContainer(app)
+
+        # Monkey-patching HTTPConnection.finish to count the
+        # number of requests being handled by Tornado. This
+        # will help gunicorn shutdown the worker if max_requests
+        # is exceeded.
+        httpserver = sys.modules["tornado.httpserver"]
+        if hasattr(httpserver, 'HTTPConnection'):
+            old_connection_finish = httpserver.HTTPConnection.finish
+
+            def finish(other):
+                self.handle_request()
+                old_connection_finish(other)
+            httpserver.HTTPConnection.finish = finish
+            sys.modules["tornado.httpserver"] = httpserver
+
+            server_class = tornado.httpserver.HTTPServer
+        else:
+
+            class _HTTPServer(tornado.httpserver.HTTPServer):
+
+                def on_close(instance, server_conn):
+                    self.handle_request()
+                    super(_HTTPServer, instance).on_close(server_conn)
+
+            server_class = _HTTPServer
+
+        if self.cfg.is_ssl:
+            if TORNADO5:
+                server = server_class(app, ssl_options=ssl_context(self.cfg))
+            else:
+                server = server_class(app, io_loop=self.ioloop,
+                                      ssl_options=ssl_context(self.cfg))
+        else:
+            if TORNADO5:
+                server = server_class(app)
+            else:
+                server = server_class(app, io_loop=self.ioloop)
+
+        self.server = server
+        self.server_alive = True
+
+        for s in self.sockets:
+            s.setblocking(0)
+            if hasattr(server, "add_socket"):  # tornado > 2.0
+                server.add_socket(s)
+            elif hasattr(server, "_sockets"):  # tornado 2.0
+                server._sockets[s.fileno()] = s
+
+        server.no_keep_alive = self.cfg.keepalive <= 0
+        server.start(num_processes=1)
+
+        self.ioloop.start()