FastAPI / دليل حلول تحريري
بطء طلب async أوفشله: تشخيص التنفيذ ودورة الحياة
افصل حجب الحلقة وانتظار المجمع وعمر العميل الخاطئ وغياب البدء دون خدمة حقيقية أونوم عشوائي.
قاعدة معرفة للقراءة فقط · بلا تعليقات عامة
تعرّف على الأعراض
تبطؤ الطلبات أويرمي العميل خطأ حلقة أومورد مغلق أويغيب بدء الاختبار. لا يثبت async غياب الحجب ولا نقل ASGI دخول الحياة؛ وتحتاج الأعراض أدلة مختلفة.
افهم الأسباب المحتملة
- قد يكون استدعاء حاجبا أوانتظار مجمع أوموردا عاما من حلقة أخرى أوحياة غائبة أوتنظيفا مبكرا. وقد يشبه بطء الاعتماد والقفل مشكلة الحلقة؛ فلا تلُم الإطار افتراضا.
تحديد مرحلة التنفيذ الفاشلة
سجل الإصدار والتصريح ومالك المورد ودليل المراحل الآمن. افصل الأخذ والانتظار والحساب والتسلسل والتدفق والمهمة واحفظ الأول دون أسرار. لا يثبت 200 قبل فشل لاحق الاكتمال. ابدأ بفرضية وإعادة اصطناعية لا تغيير الجميع والعمال.
فحص سلسلة الاستدعاء الحاجب الفعلية
توزع FastAPI العادي المدعوم ولا تعترض كل مساعد داخل async. اختر API مناسبة أونقلا صريحا. يفحص المثال فصل الخيط دون I/O حقيقي. افحص تشبع المجمع والخلفية قبل زيادة المهام.
import threading
from fastapi import FastAPI
from fastapi.testclient import TestClient
from starlette.concurrency import run_in_threadpool
def helper(value, loop_thread):
return {"value": value * 2, "same_thread": threading.get_ident() == loop_thread}
app = FastAPI()
@app.get("/calculate")
async def calculate():
return await run_in_threadpool(helper, 3, threading.get_ident())
with TestClient(app) as client:
print(client.get("/calculate").json())
{'value': 6, 'same_thread': False}
يعيد المساعد النقي ستة على خيط آخر، دون قاعدة أو شبكة أو قياس إنتاجية.
توضيح البدء وعمر العميل
أنشئ مورد التطبيق بالحياة وأغلقه فيها وأدخل سياق العميل، وأدر الحياة صراحة مع نقل async عند الحاجة. يثبت المثال الوجود والإغلاق اصطناعيا. لا تعِد عميلا عبر حلقات غير متوافقة أوتفترض أمان العام بين العمال.
from contextlib import asynccontextmanager
from fastapi import FastAPI
from fastapi.testclient import TestClient
state = {"closed": False}
@asynccontextmanager
async def lifespan(app):
app.state.resource = {"ready": True}
try:
yield
finally:
state["closed"] = True
app = FastAPI(lifespan=lifespan)
@app.get("/resource")
def resource(): return app.state.resource
with TestClient(app) as client:
print(client.get("/resource").json())
print(state["closed"])
{'ready': True}
True
يدخل السياق البدء ثم التنظيف والمورد قاموس وهمي بلا خارج.
مراجعة نطاق تنظيف الرد والمهمة
قد تغلق تبعية الدالة قبل الإرسال وتحفظ الطلب عبر المعالجة وفق الإصدار؛ فطابق احتياج التدفق. مرر للخلفية ثابتا وموارد خاصة لا جلسة منتهية، ولا تؤخر تثبيتا بعد النجاح. احفظ الأصلي وحد التنظيف من تعليق دائم.
إصلاح حد مملوك والتحقق منه
غير العقد الضيق بالدليل واختبر النجاح والفشل والإلغاء والتدفق والتنظيف بإشارة لا نوم. السكربتات داخلية بحالة ومساعد نقي بلا خادم أوشبكة أوقاعدة. يحتاج الأداء والنشر تحقق إذن آخر.
تحقق من نجاح الإصلاح
تحقق من النتيجة والملكية وأخذ واحد حسب النطاق والتنظيف، ومن عدم استخدام المحرر واكتمال التثبيت قبل النجاح، واحفظ الإصدار وحدود الاختبار.
امنع تكرار المشكلة
- راجع التنفيذ والعمر معا واستخدم مصانع وعزلا وحدود مجمع وطابور وموعد. أعد فحص التحديث وتجنب عميلا عاما بحلقة مجهولة وخلفية تستعير جلسة طلب.