مرحبا يا هابر! أريد أن أقول كيف حللت مشكلة التنفيذ التنافسي الفعال للمهام غير المتزامنة في الكرفس.![KDPV](https://habrastorage.org/webt/dr/iq/wn/driqwnzsb4fprqwzfsmqyvkvu54.jpeg)
المقدمة
الكرفس هو مشروع كبير له تاريخ معقد وعبء ثقيل من التوافق العكسي. تم اتخاذ القرارات المعمارية الرئيسية لفترة طويلة قبل ظهور Asyncio في الثعبان. لذلك ، من المثير للاهتمام أنه يمكنك بطريقة ما تشغيل المهمة غير المتزامنة في الكرفس خارج الصندوق.تشغيل مهام غير متزامنة في كرفس الفانيليا
يمكنك بدء مهمة asyncio من الصندوق:import asyncio
from .celeryapp import celeryapp
async def async_task():
await asyncio.sleep(42)
@celeryapp.task
def regular_task():
coro = async_task()
asyncio.run(coro)
مزايا واضحة:- إنها تعمل!
- ببساطة
- لا تبعيات خارجية إضافية
ما هو الخطأ في الواقع؟- يتم إنشاء حلقة الأحداث داخل كل عامل.
- لا يوجد تبديل السياق بين تنفيذ coroutines
- في وقت ما ، لا ينفذ العامل أكثر من كوروتين واحد
- لا تتم مشاركة الموارد المشتركة بين المهام
- لوحة مرجعية
أي ، يستخدم asyncio في هذه الحالة لـ asyncio ، ولكن لا توجد مزايادعونا نحاول أصعب؟
حاربت من أجل الأداء:import asyncio
import threading
from .celeryapp import celeryapp
celeryapp.loop = asyncio.get_event_loop()
celeryapp.loop_runner = threading.Thread(
target=celeryapp.loop.run_forever,
daemon=True,
)
celeryapp.loop_runner.start()
async def async_task():
await asyncio.sleep(42)
@celeryapp.task
def regular_task():
coro = async_task()
asyncio.run_coroutine_threadsafe(
coro=coro,
loop=celeryapp.loop,
)
البنغو! الإيجابيات:- لا يزال يعمل
- أكثر أو أقل فعالية
- حتى الموارد تتناوب بين coruteines داخل العامل.
- لا توجد حتى الآن تبعيات خارجية إضافية
البنغو؟ لم تكن المشاكل طويلة في المستقبل:- الكرفس لا يعرف أي شيء عن تشغيل الكوروتين
- تفقد السيطرة على تنفيذ المهام
- تفقد السيطرة على الاستثناءات
- لوحة مرجعية
للذهاب مع مثل هذا الحل الهندسي الرائع في همز ، لم ترتفع يدي بطريقة أو بأخرىصياغة المشكلة
- يجب أن تعمل
- يجب أن تكون Coroutines قادرة على المنافسة
- يجب مشاركة الموارد بين العديد من الملفات القابلة للتنفيذ
- لا يوجد مرجل
- واجهة برمجة تطبيقات بسيطة يمكن التنبؤ بها
أي توقعاتي:import asyncio
from .celeryapp import celeryapp
@celeryapp.task
async def async_task():
await asyncio.sleep(42)
ملخص
قمت بتطبيق أفكاري في مكتبة الكرفس-حوض غير متزامن . يتم استخدام هذه المكتبة من قبل فريقنا في المشروع الحالي ، وقد بدأنا بالفعل في الإنتاج.الميزات لفترة وجيزة
إلى جانب التنفيذ المباشر لمهام عدم التزامن ، يحل celery-pool-asyncio أيضًا المشاكل:- ذرف المهمة غير المتزامنة
- دعم Corutin في إشارات الكرفس
من أجل الحصول على الكرفس-بركة-غير متزامن للعمل ، استخدمت ترقيع القرد . لكل تصحيح مستخدم في وقت التشغيل ، من الممكن تعطيله.يمكنك قراءة المزيد عن كل هذا في الوثائق.الخطط
بطريقة جيدة ، تحتاج إلى دمج البركة في الكرفس. من ناحية أخرى ، فإن مطوري الكرفس هم نماذج أولية للكرفس 5.0 ، والتي ستكون غير متزامنة. هل اللعبة تستحق الشمعة؟أمثلة
لإثبات قدرات مكتبات celery-pool-asyncio و celery-decorator-taskcls ( مقالة ) ، تم تنفيذ مشروع اختبار .آخر
حاولت أن أقول نفس الشيء على mitap