هذا ما تعلمته كمطور PHP متزامن (Sync) حول PHP غير المتزامن (Async)
عملت مع Laravel لسنوات. كنت أستخدم PHP المتزامن (sync). يأتي طلب، يتم تنفيذ عملية، ثم يخرج الرد. لم أكن بحاجة أبداً إلى الـ async.
ثم قرأت عن واجهة برمجة تطبيقات الاستطلاع (Polling API) الجديدة في PHP 8.6. لقد غير ذلك نظرتي لكيفية تعامل PHP مع المهام.
إليك تفصيل لكيفية عمل الـ async.
المشكلة في عمليات الإدخال والإخراج المعطلة (Blocking I/O)
عندما تستدعي API، ينتظر الكود الخاص بك.
مثال: $response = Http::get('https://api.example.com');
إذا استغرق هذا الـ API مدة 300 مللي ثانية، فإن عملية PHP الخاصة بك لا تفعل شيئاً طوال تلك الـ 300 مللي ثانية. تظل في حالة سكون (sleep state)، وتستهلك الذاكرة وتشغل مساحة من العمال (worker slot). وإذا كانت جميع العمال في حالة سكون، سيتوقف خادمك عن قبول طلبات جديدة.
حل الـ Async
يسمح لك الـ Async بالقيام بأعمال أخرى خلال تلك الـ 300 مللي ثانية. فبدلاً من الانتظار، تقوم بتشغيل مهام أخرى.
ولكن كيف تعرف متى تصل البيانات؟ هنا يأتي دور النواة (kernel).
تطور عملية الاستطلاع (Polling)
select()يتوفر في PHP دالةstream_select()منذ الإصدار PHP 4. وهي تسأل النواة: "هل هناك أي بيانات جاهزة على هذه المقابس (sockets)؟" المشكلة تكمن في ضريبة إعادة الفحص (rescan tax). فإذا كان لديك 10,000 اتصال، يجب عليك إرسال القائمة بأكملها إلى النواة في كل مرة. هذا الأمر بطيء ويصل إلى الحدود القصوى.epoll/kqueueهذه ميزة في النواة وليست ميزة في لغة البرمجة. يستخدم Linux نظامepollبينما يستخدم macOS نظامkqueue. بدلاً من فحص قائمة كاملة، تحتفظ النواة بقائمة جاهزة (ready-list). وهي تخبرك فقط بالمقابس المحددة التي تحتوي على بيانات. هذا يسمح بالتوسع لآلاف الاتصالات دون تكلفة إضافية.Fibers(في PHP 8.1) تتيح لك الـFibersإيقاف وظيفة (function) مؤقتاً في أي مكان في مكدس الاستدعاءات (call stack). الـFiberلا يستيقظ من تلقاء نفسه؛ فهو يشبه فيديو YouTube متوقف مؤقتاً. يجب على شخص ما استدعاء$fiber->resume()لتشغيله مرة أخرى.
الحلقة المفقودة: PHP 8.6
يتطلب الـ Async I/O ثلاثة أجزاء:
• الإيقاف (Pause): الـ Fibers (موجودة الآن في نواة PHP)
• القرار (Decide): حلقة الأحداث (Event Loop) (كود PHP عادي)
• المعرفة (Know): استطلاع النواة (Kernel Polling) (وهي الفجوة)
حتى الآن، كان PHP يفتقر إلى طريقة أصلية (native) لـ "معرفة" أي مقبس جاهز دون استخدام أدوات قديمة أو إضافات مكتوبة بلغة C.
يغلق PHP 8.6 هذه الفجوة، حيث يوفر واجهة برمجة تطبيقات استطلاع (Polling API) أصلية في النواة. وسيقوم تلقائياً باستخدام epoll على Linux و kqueue على Mac.
الصورة الكبيرة
الـ Async ليس سحراً. حلقة الأحداث (event loop) هي مجرد كود PHP يقرر متى يستدعي resume() على Fiber.
توفر الـ Fibers القدرة على الإيقاف المؤقت.
ويوفر epoll الذكاء لمعرفة متى يتم استئناف العمل.
إذا كنت تستخدم PHP المتزامن فقط، فلن تحتاج إلى تغيير تطبيقات Laravel الخاصة بك اليوم. ولكن فهم هذا النموذج يجعل إتقان مكتبات الـ async مثل ReactPHP أو Amp أسهل بكثير.
ابنِ، ولا تكتفِ بالاستهلاك فقط. قم بتشغيل الكود بنفسك لترى كيف يعمل.
