Async PHP کی حقیقت: Fibers، epoll، اور PHP 8.6

میں سالوں تک Laravel کے ساتھ کام کرتا رہا۔ میں sync PHP استعمال کرتا تھا۔ ایک ریکویسٹ آتی ہے، پروسیس چلتا ہے، اور ریسپانس چلا جاتا ہے۔ مجھے کبھی async کوڈ کی ضرورت محسوس نہیں ہوئی۔

پھر میں نے نئی PHP 8.6 Polling API کے بارے میں پڑھا۔ اس نے چیزوں کو دیکھنے کا میرا نظریہ ہی بدل دیا۔

یہاں وہ سب کچھ ہے جو میں نے سیکھا کہ async اندرونی طور پر (under the hood) کیسے کام کرتا ہے۔

IO کا مسئلہ

جب آپ کسی API کو کال کرتے ہیں، تو آپ کا PHP پروسیس انتظار کرتا ہے۔ مثال: $response = Http::get('https://api.example.com');

اگر اس کال میں 300ms لگتے ہیں، تو آپ کا CPU 300ms تک کچھ نہیں کرتا۔ یہ sleep state میں رہتا ہے۔ اسے blocking I/O کہتے ہیں۔

اگر آپ کی تین API کالز ہوں:

  • API A: 300ms
  • API B: 400ms
  • API C: 200ms

ترتیب وار (Sequential) کل وقت: 900ms۔ Async کل وقت: 400ms (سب سے سست کال کا وقت)۔

Async آپ کے پروسیس کو ڈیٹا کا انتظار کرنے کے دوران دوسرے کام کرنے کی اجازت دیتا ہے۔

Select بمقابلہ epoll

Async کرنے کے لیے، آپ کو یہ جاننے کی ضرورت ہے کہ کس socket میں ڈیٹا تیار ہے۔

  1. select() PHP ورژن 4 سے stream_select() استعمال کر رہا ہے۔ یہ kernel سے sockets کی ایک فہرست پر نظر رکھنے کا کہہ کر کام کرتا ہے۔ مسئلہ: ہر بار جب ڈیٹا آتا ہے، آپ کو پوری فہرست کو دوبارہ اسکین کرنا پڑتا ہے۔ اسے "rescan tax" کہا جاتا ہے۔ اس میں تقریباً 1024 کنکشنز کی حد (limit) بھی ہوتی ہے۔

  2. epoll (Linux) / kqueue (macOS) یہ kernel کے فیچرز ہیں۔ فہرست کو اسکین کرنے کے بجائے، kernel ایک "ready-list" رکھتا ہے۔ یہ آپ کو صرف وہی مخصوص sockets بتاتا ہے جو تیار ہیں۔ یہ اضافی کام کے بغیر ہزاروں کنکشنز تک پھیل سکتا ہے۔

epoll کوئی PHP فیچر نہیں ہے۔ یہ ایک Linux فیچر ہے۔ Go، Rust، اور Node.js سب اسے استعمال کرتے ہیں۔

Fibers: پاز (Pause) بٹن

PHP 8.1 میں Fibers متعارف کروائے گئے۔ میں نے سوچا تھا کہ Fibers خود بخود جاگ جائیں گے۔ ایسا نہیں ہوتا۔

ایک Fiber ایک رکے ہوئے (paused) ویڈیو کی طرح ہے۔ یہ تب تک رکا رہتا ہے جب تک کوئی $fiber->resume() کو کال نہ کر دے۔

ایک Event Loop محض PHP کوڈ کا ایک حصہ ہے جو فیصلہ کرتا ہے کہ resume() کب کال کرنا ہے۔

Async I/O کے لیے تین حصوں کی ضرورت ہوتی ہے:

  • Pause: Fibers (PHP 8.1 core)
  • Decide: The Event Loop (Plain PHP code)
  • Know: Kernel Polling (epoll/kqueue)

PHP 8.6 سے پہلے، PHP کے پاس "Pause" اور "Decide" والے حصے موجود تھے، لیکن "Know" والا حصہ پرانے select() یا سست C extensions پر انحصار کرتا تھا۔

PHP 8.6 اس خلا کو ختم کرتا ہے۔ یہ core میں ایک native Polling API لاتا ہے۔ اب، PHP اضافی extensions کے بغیر براہ راست epoll یا kqueue استعمال کر سکتا ہے۔

حاصلِ کلام

اگر آپ PHP-FPM کے ساتھ Laravel استعمال کرتے ہیں، تو آج آپ کو کچھ بھی تبدیل کرنے کی ضرورت نہیں ہے۔

لیکن یہ سمجھ لیں: Async کوئی جادو نہیں ہے۔ یہ صرف انتظار کے وقت کو سنبھالنے کا ایک ہوشیار طریقہ ہے۔

صرف کوڈ کو استعمال کرنا (consume کرنا) بند کریں۔ ایک سادہ اسکرپٹ چلائیں۔ اسے توڑیں۔ اسی طرح آپ حقیقی طور پر سیکھتے ہیں۔

ماخذ (Source): https://dev.to/alamriku/sync-php-developer-hisebe-async-php-bujhte-giye-yaa-shikhlaam-fibers-epoll-aar-php-86-462j