नेटिव्ह Polling API परिभाषित करणारा PHP RFC मंजूर करण्यात आला असून तो भाषेच्या मास्टर ब्रँचमध्ये (master branch) विलीन करण्यात आला आहे, ज्यामुळे डेव्हलपर्सना फाईल डिस्क्रिप्टर्स (file descriptors) पोल करण्यासाठी एक वेगवान, OS-स्तरीय मार्ग उपलब्ध झाला आहे. अलीकडेच जोडलेल्या Fibers सोबत, PHP कडे आता असिंक्रोनस (asynchronous) कोडसाठी एक अंगभूत, कार्यक्षम पाया आहे—ही अशी एक त्रुटी होती ज्यामुळे दीर्घकाळ लायब्ररींना स्वतःचे तात्पुरते उपाय (work-arounds) तयार करण्यास भाग पडले होते.

Fibers आणि event loop, वेगळे

Fibers हे लो-लेव्हल कंट्रोल-फ्लो प्रिमिटिव्ह (low-level control-flow primitive) आहेत. ते एखाद्या फंक्शनला निवडलेल्या ठिकाणी त्याचे एक्झिक्यूशन (execution) थांबवण्यास आणि नंतर जिथे थांबले होते तिथूनच पुन्हा सुरू करण्यास परवानगी देतात. महत्त्वाचे म्हणजे, एका fiber ला सॉकेट्स (sockets), टाइमर्स (timers) किंवा इतर कोणत्याही I/O सोर्सबद्दल काहीही माहिती नसते; ते फक्त मागणीनुसार थांबते आणि पुन्हा सुरू होते.

Event loop हा एक शेड्युलर (scheduler) आहे जो थांबलेला fiber कधी पुन्हा सुरू करायचा हे ठरवतो. एका सामान्य async स्टॅकमध्ये, लूप फाईल डिस्क्रिप्टर्सच्या संचावर लक्ष ठेवतो, ते वाचण्यायोग्य (readable) किंवा लिहिण्यायोग्य (writable) होण्याची वाट पाहतो आणि त्यानंतर संबंधित fiber ला कार्यान्वित करतो.

PHP मध्ये पूर्वी Fibers होते, परंतु ऑपरेटिंग सिस्टमला कोणते डिस्क्रिप्टर्स तयार आहेत हे विचारण्यासाठी नेटिव्ह यंत्रणेचा अभाव होता. परिणामी stream_select() किंवा बाह्य एक्स्टेंशन्सवर अवलंबून राहावे लागत असे, आणि प्रत्येक async लायब्ररीला Linux चे epoll, BSD चे kqueue, Windows चे IOCP इत्यादींसाठी स्वतःचे बॅक-एंड्स लिहावे लागत होते.

नवीन Polling API ही उणीव भरून काढते. हे OS च्या पोलिंग सुविधांभोवती (Linux वर epoll, BSD/macOS वर kqueue, इत्यादी) एक थिन रॅपर (thin wrapper) प्रदान करते. ही API Fibers ची जागा घेत नाही; ती फक्त event loop ला आवश्यक असलेला वेग आणि स्केलेबिलिटी (scalability) प्रदान करते.

ReactPHP, Amp आणि इतर मित्रत्वाच्या लायब्ररींसाठी हा बदल का महत्त्वाचा आहे

ReactPHP आणि Amp v3 ने OS पोलिंग मेकॅनिझमवर स्वतःचे ॲब्स्ट्रॅक्शन लेयर्स (abstraction layers) तयार केले आहेत. त्या लेयर्समध्ये अनेक कोड पाथ्स (code paths) असतात, जे प्रत्येक विशिष्ट प्लॅटफॉर्मसाठी ट्यून केलेले असतात आणि त्यांना कर्नल बदलांशी सुसंगत ठेवणे आवश्यक असते. नेटिव्ह Polling API मुळे, या लायब्ररी त्यातील बहुतेक प्लंबिंग (plumbing) काढून टाकू शकतात आणि केवळ एका सिंगल, कोअर-प्रदान केलेल्या कॉलवर अवलंबून राहू शकतात.

  • Maintenance – कमी प्लॅटफॉर्म-विशिष्ट ब्रँचेस म्हणजे कमी बग्स आणि सुरक्षा पुनरावलोकनासाठी (security reviews) कमी क्षेत्र.
  • Performance – नेटिव्ह कॉल थेट epoll/kqueue शी संवाद साधतो.
  • Portability – "vanilla" PHP वर चालणारा कोड आता कोणत्याही पर्यायी एक्स्टेंशन्सशिवाय सर्व समर्थित ऑपरेटिंग सिस्टमवर समान बेसलाइन परफॉर्मन्स मिळवतो.

याउलट, Swoole हे एक पूर्ण-रनटाइम रिप्लेसमेंट आहे जे स्वतःचा event loop आणि coroutine सिस्टम प्रदान करते. Polling API मुळे Swoole च्या ट्रेड-ऑफ्सवर (trade-offs) कोणताही परिणाम होत नाही; ज्या डेव्हलपर्सना अल्ट्रा-लो लेटन्सी (ultra-low latency) किंवा कस्टम मेमरी मॅनेजमेंटची गरज आहे, ते अजूनही याला एक वेगळा पर्याय मानतील.

एक जलद बेंचमार्क सर्व काही सांगतो

एका मिनिमल शेड्युलरने अनेक फाइबर्स व्यवस्थापित करण्यासाठी सिंगल Io\Poll\Context वापरून रॉ सॉकेट्सद्वारे (raw sockets) काही URL फेच केल्या. दोन निरीक्षणे समोर आली:

  1. Speed – अधिक कॉनकरंट रिक्वेस्ट (concurrent requests) जोडल्याने एकूण लागणारा वेळ वाढत नाही; रिक्वेस्टचा बॅच सर्वात संथ सिंगल रिक्वेस्ट इतक्याच वेगाने पूर्ण होतो. दुसऱ्या शब्दांत, कॉनकरन्सी ओव्हरहेड (concurrency overhead) प्रभावीपणे शून्य आहे.
  2. CPU coststream_select() मध्ये स्ट्रीम्सची संख्या जसजशी वाढते तसतसा CPU वापर लक्षणीयरीत्या वाढतो, कारण फंक्शनला प्रत्येक कॉलवर प्रत्येक डिस्क्रिप्टरवर इटरेशन (iterate) करावे लागते. कर्नलच्या एका सिंगल सिस्टम कॉलमध्ये अनेक डिस्क्रिप्टर्सवर लक्ष ठेवण्याच्या क्षमतेमुळे, Polling API चा खर्च तीन स्ट्रीम्सपासून तीस स्ट्रीम्सपर्यंत स्थिर राहतो.

डेव्हलपर्सनी आता काय करावे

  • Amp v3 वापरा जर तुम्हाला नवीन API शी थेट सुसंगत असलेला fiber-native स्टाईल आवडत असेल. त्याचा पब्लिक इंटरफेस आधीच मूळ poller ला मॅप केलेला आहे, त्यामुळे तुम्हाला तुमचा कोड पुन्हा न लिहिता याचा फायदा मिळेल.
  • ReactPHP सोबतच राहा जर तुम्हाला लूपच्या लाइफसायकलवर (lifecycle) स्पष्ट नियंत्रण हवे असेल.
  • कस्टम शेड्युलर्स टाळा प्रोडक्शन वर्कलोडसाठी (production workloads). प्रोडक्शनसाठी स्वतःचा शेड्युलर लिहू नका.