الكرفس + غير متزامن

مرحبا يا هابر! أريد أن أقول كيف حللت مشكلة التنفيذ التنافسي الفعال للمهام غير المتزامنة في الكرفس.

KDPV

المقدمة


الكرفس هو مشروع كبير له تاريخ معقد وعبء ثقيل من التوافق العكسي. تم اتخاذ القرارات المعمارية الرئيسية لفترة طويلة قبل ظهور Asyncio في الثعبان. لذلك ، من المثير للاهتمام أنه يمكنك بطريقة ما تشغيل المهمة غير المتزامنة في الكرفس خارج الصندوق.

تشغيل وضع التجويف
#839. . mode off.

تشغيل مهام غير متزامنة في كرفس الفانيليا


يمكنك بدء مهمة 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


All Articles