From b3f624a5126b5ed2ce1fd6f85a63dac0bd6ce1cb Mon Sep 17 00:00:00 2001 From: Zareian Date: Sun, 4 Oct 2026 14:41:48 +0330 Subject: [PATCH] gunicorn: warm the assistant's Qdrant/OpenAI clients when a worker starts The first assistant round after a restart waited ~6 s before reaching the model on the live server (later rounds ~1 s); locally a cold 10-ask burst took 7.5 s vs 6.1 s with this hook (simulated model, 5.2 s). Workers are recycled by max_requests, so the delay recurred. A failed warm-up is logged and does not stop the worker. Co-Authored-By: Claude Opus 5.5 --- gunicorn.conf.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/gunicorn.conf.py b/gunicorn.conf.py index d52c837..2d78164 100644 --- a/gunicorn.conf.py +++ b/gunicorn.conf.py @@ -34,3 +34,27 @@ keepalive = 5 # نشود؛ jitter نمی‌گذارد هر سه با هم ری‌استارت شوند. max_requests = 2000 max_requests_jitter = 200 + + +def post_worker_init(worker): + """ + کتابخانه‌های Qdrant و OpenAI را همان لحظه‌ی بالا آمدنِ worker بار می‌کند، نه سرِ اولین + سوالِ دستیار. در لودتستِ ۲۰۲۶-۱۰-۰۴ اولین دورِ پرسش بعد از ری‌استارت روی سرور ~۶ ثانیه + پیش از رسیدن به مدل معطل ماند و دورهای بعد ~۱ ثانیه؛ روی لپ‌تاپ همین تفاوت ۱٫۷ ثانیه بود + (import ِ qdrant_client به‌تنهایی ~۰٫۷ ثانیه). با max_requests هر worker گاه‌به‌گاه از نو + بالا می‌آید، پس بدونِ این هر چند هزار درخواست یک دانش‌آموز همین تأخیر را می‌دید. + + ساختنِ کلاینت تماسِ شبکه‌ای ندارد. شکستِ این گرم‌کردن نباید worker را بخواباند (کلِ اپ + به‌خاطرِ یک بهینه‌سازی پایین نمی‌آید)؛ ثبت می‌شود و اولین سوال همان مسیرِ عادی را می‌رود. + """ + from rag.services.config import rag_is_configured + + if not rag_is_configured(): + return + try: + from rag.services import clients + + clients.get_openai_client() + clients.get_qdrant_client() + except Exception: + worker.log.exception('گرم کردنِ کلاینت‌های دستیار شکست خورد؛ اولین سوال آن‌ها را می‌سازد.')