నేటివ్ Polling APIని నిర్వచించే PHP RFC ఆమోదించబడింది మరియు భాష యొక్క మాస్టర్ బ్రాంచ్లోకి విలీనం చేయబడింది, ఇది డెవలపర్లకు ఫైల్ డిస్క్రిప్టర్లను (file descriptors) పోల్ చేయడానికి వేగవంతమైన, OS-స్థాయి మార్గాన్ని అందిస్తుంది. ఇటీవల జోడించిన Fibersతో కలిపి, PHP ఇప్పుడు అసమకాలిక (asynchronous) కోడ్ కోసం ఒక అంతర్నిర్మిత, సమర్థవంతమైన పునాదిని కలిగి ఉంది—ఈ లోటు కారణంగా లైబ్రరీలు చాలా కాలంగా తమ స్వంత పరిష్కారాలను (work-arounds) అతుక్కుంటూ వస్తున్నాయి.
Fibers మరియు event loop, వేరువేరుగా
Fibers అనేవి లో-లెవల్ కంట్రోల్-ఫ్లో ప్రిమిటివ్స్ (low-level control-flow primitives). ఇవి ఒక ఫంక్షన్ తన ఎగ్జిక్యూషన్ను ఒక నిర్దిష్ట పాయింట్ వద్ద నిలిపివేసి (suspend), ఆ తర్వాత సరిగ్గా ఎక్కడ ఆగిపోయిందో అక్కడి నుండే తిరిగి ప్రారంభించేలా (resume) చేస్తాయి. ముఖ్యంగా, ఒక fiber కి సాకెట్లు, టైమర్లు లేదా మరే ఇతర I/O సోర్స్ గురించి ఏమీ తెలియదు; ఇది కేవలం అవసరానికి అనుగుణంగా ఆగుతుంది మరియు మళ్ళీ ప్రారంభమవుతుంది.
ఒక event loop అనేది ఆగిపోయిన 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 కి అవసరమైన వేగం మరియు స్కేలబిలిటీని అందిస్తుంది.
ReactPHP, Amp మరియు ఇతర లైబ్రరీలకు ఈ మార్పు ఎందుకు ముఖ్యం
ReactPHP మరియు Amp v3 తమ స్వంత అబ్స్ట్రాక్షన్ లేయర్లను (abstraction layers) OS పోలింగ్ మెకానిజమ్స్ పైన నిర్మించుకున్నాయి. ఆ లేయర్లలో బహుళ కోడ్ పాత్లు ఉంటాయి, ఇవి ప్రతి ప్లాట్ఫారమ్కు అనుగుణంగా సర్దుబాటు చేయబడతాయి మరియు కెర్నల్ మార్పులతో పాటు వీటిని కూడా అప్డేట్ చేస్తూ ఉండాలి. నేటివ్ Polling APIతో, లైబ్రరీలు ఆ అనవసరమైన పనులను (plumbing) వదిలేసి, కోర్ ద్వారా అందించబడే ఒకే ఒక కాల్పై ఆధారపడవచ్చు.
- మెయింటెనెన్స్ (Maintenance) – ప్లాట్ఫారమ్-స్పెసిఫిక్ బ్రాంచ్లు తక్కువగా ఉండటం వల్ల బగ్స్ తగ్గుతాయి మరియు సెక్యూరిటీ రివ్యూల కోసం తక్కువ విస్తీర్ణం ఉంటుంది.
- పెర్ఫార్మెన్స్ (Performance) – నేటివ్ కాల్ నేరుగా epoll/kqueueతో మాట్లాడుతుంది.
- పోర్టబిలిటీ (Portability) – "vanilla" PHPలో నడిచే కోడ్ ఇప్పుడు ఎటువంటి అదనపు ఎక్స్టెన్షన్లు అవసరం లేకుండానే, అన్ని సపోర్టెడ్ ఆపరేటింగ్ సిస్టమ్స్లో ఒకే విధమైన బేస్లైన్ పెర్ఫార్మెన్స్ను పొందుతుంది.
దీనికి విరుద్ధంగా, Swoole అనేది తన స్వంత event loop మరియు coroutine సిస్టమ్తో వచ్చే ఒక ఫుల్-రన్టైమ్ రీప్లేస్మెంట్ (full-runtime replacement)గా కొనసాగుతుంది. Polling API వల్ల Swoole యొక్క లాభనష్టాలపై (trade-offs) ఎలాంటి ప్రభావం ఉండదు; అల్ట్రా-లో లేటెన్సీ (ultra-low latency) లేదా కస్టమ్ మెమరీ మేనేజ్మెంట్ అవసరమయ్యే డెవలపర్లు దానిని ఇప్పటికీ ఒక ప్రత్యేక ఎంపికగా పరిగణిస్తారు.
ఒక చిన్న బెంచ్మార్క్ దీనిని నిరూపిస్తుంది
ఒక మినిమల్ షెడ్యూలర్, బహుళ fibersలను నిర్వహించడానికి ఒకే Io\Poll\Contextని ఉపయోగిస్తూ, రా సాకెట్ల (raw sockets) ద్వారా కొన్ని URLలను పొందింది. దీని ద్వారా రెండు విషయాలు వెల్లడయ్యాయి:
- వేగం (Speed) – ఎక్కువ కన్కరెంట్ రిక్వెస్ట్లను జోడించడం వల్ల మొత్తం సమయం పెరగదు; రిక్వెస్ట్ బ్యాచ్ అనేది అత్యంత నెమ్మదైన రిక్వెస్ట్ ఎంత త్వరగా పూర్తవుతుందో అంతే త్వరగా పూర్తవుతుంది. మరో మాటలో చెప్పాలంటే, కన్కరెన్సీ ఓవర్హెడ్ (concurrency overhead) దాదాపు సున్నా.
- CPU ఖర్చు (CPU cost) –
stream_select()తో, స్ట్రీమ్ల సంఖ్య పెరిగేకొద్దీ CPU వినియోగం గణనీయంగా పెరుగుతుంది, ఎందుకంటే ప్రతి కాల్లో ఫంక్షన్ ప్రతి డిస్క్రిప్టర్ను తనిఖీ చేయాల్సి ఉంటుంది. కానీ Polling API ఖర్చు మాత్రం మూడు స్ట్రీమ్ల నుండి ముప్పై స్ట్రీమ్ల వరకు స్థిరంగా ఉంటుంది, ఎందుకంటే కెర్నల్ ఒకే సిస్టమ్ కాల్లో అనేక డిస్క్రిప్టర్లను పర్యవేక్షించగలదు.
డెవలపర్లు ఇప్పుడు ఏమి చేయాలి
- Amp v3ని ఉపయోగించండి – మీరు కొత్త APIకి అనుగుణంగా ఉండే ఫైబర్-నేటివ్ (fiber-native) శైలిని ఇష్టపడితే, Amp v3ని ఎంచుకోండి. దీని పబ్లిక్ ఇంటర్ఫేస్ ఇప్పటికే అండర్లైయింగ్ పోలర్కు అనుసంధానించబడి ఉంది, కాబట్టి మీరు మీ కోడ్ను మళ్ళీ రాయకుండానే దీని ప్రయోజనాన్ని పొందవచ్చు.
- ReactPHPతోనే కొనసాగండి – మీకు లూప్ యొక్క లైఫ్సైకిల్ (lifecycle)పై స్పష్టమైన నియంత్రణ కావాలనుకుంటే, ReactPHPతోనే కొనసాగండి.
- ప్రొడక్షన్ వర్క్లోడ్ల కోసం కస్టమ్ షెడ్యూలర్లను నివారించండి. ప్రొడక్షన్ కోసం మీ స్వంత షెడ్యూలర్ను వ్రాయకండి.
