Skip to content

Commit e9af6a1

Browse files
committed
fix: Include the post fork function
1 parent 5747b92 commit e9af6a1

1 file changed

Lines changed: 24 additions & 0 deletions

File tree

src/backend/base/langflow/server.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ def __init__(self, app_factory: Callable[[], Any], options=None) -> None:
7070
self.options["worker_class"] = "langflow.server.LangflowUvicornWorker"
7171
self.options["logger_class"] = Logger
7272
self.options["pre_fork"] = self.pre_fork
73+
self.options["post_fork"] = _langflow_post_fork
7374
self._app_factory = app_factory
7475
self.application = None
7576
super().__init__()
@@ -166,3 +167,26 @@ def load(self):
166167

167168
preload_master()
168169
return self.application
170+
171+
172+
def _langflow_post_fork(server, worker) -> None: # noqa: ARG001
173+
"""Reset fork-unsafe resources in each worker after gunicorn forks.
174+
175+
Gunicorn calls this hook synchronously in the worker process immediately
176+
after fork, before any request is served. No event loop exists yet here —
177+
this function MUST remain fully synchronous.
178+
179+
Currently resets ``TelemetryService.client`` (an ``httpx.AsyncClient``
180+
constructed during master preload) so ``TelemetryService.start()`` can
181+
reconstruct it inside the worker's event loop. ``httpx.AsyncClient`` has
182+
no synchronous ``.close()``, so replacing the reference is the correct
183+
pattern.
184+
"""
185+
try:
186+
from langflow.services.deps import get_telemetry_service
187+
188+
get_telemetry_service().client = None
189+
except Exception: # noqa: BLE001, S110
190+
# Service not yet initialized (e.g. preload_app=False path). The
191+
# hook must not crash gunicorn.
192+
pass

0 commit comments

Comments
 (0)