ஒரு இயல்பான (native) Polling API-ஐ வரையறுக்கும் PHP RFC அங்கீகரிக்கப்பட்டு மொழியின் master branch-இல் இணைக்கப்பட்டுள்ளது, இது டெவலப்பர்களுக்கு file descriptors-களைப் புலறிய (poll) ஒரு வேகமான, OS-நிலை வழியை வழங்குகிறது. சமீபத்தில் சேர்க்கப்பட்ட Fibers உடன் இணைந்து, PHP இப்போது asynchronous குறியீடுகளுக்கான ஒரு உள்ளமைக்கப்பட்ட, திறமையான அடித்தளத்தைக் கொண்டுள்ளது—இது நீண்டகாலமாக நூலகங்கள் (libraries) தமக்கான மாற்று வழிகளைத் தாங்களாகவே உருவாக்க வேண்டிய கட்டாயத்திற்குத் தள்ளிய ஒரு இடைவெளியாகும்.
Fibers மற்றும் event loop, தனித்தனியாக
Fibers என்பவை ஒரு low-level control-flow primitive ஆகும். அவை ஒரு function-ஐத் தேர்ந்தெடுக்கப்பட்ட ஒரு புள்ளியில் அதன் செயல்பாட்டை நிறுத்தி வைக்கவும் (suspend), பின்னர் அது விட்ட இடத்திலிருந்தே மீண்டும் தொடங்கவும் (resume) அனுமதிக்கின்றன. முக்கியமாக, ஒரு fiber-க்கு sockets, timers அல்லது வேறு எந்த I/O மூலத்தைப் பற்றியும் தெரியாது; அது தேவைப்படும்போது மட்டும் இடைநிறுத்தம் செய்யப்பட்டு மீண்டும் தொடங்கும்.
ஒரு event loop என்பது ஒரு இடைநிறுத்தப்பட்ட fiber எப்போது மீண்டும் தொடங்கப்பட வேண்டும் என்பதைத் தீர்மானிக்கும் scheduler ஆகும். ஒரு வழக்கமான async stack-இல், loop என்பது ஒரு தொகுப்பு file descriptors-களைக் கண்காணிக்கும், அவை வாசிக்கக்கூடியதாக (readable) அல்லது எழுதக்கூடியதாக (writable) மாறும் வரை காத்திருக்கும், பின்னர் பொருத்தமான fiber-ஐத் தூண்டும்.
PHP-இல் ஏற்கனவே Fibers இருந்தன, ஆனால் எந்த descriptors தயாராக உள்ளன என்று இயங்குதளத்திடம் (operating system) கேட்பதற்கான ஒரு native mechanism அதில் இல்லை. இதன் விளைவாக stream_select() அல்லது வெளிப்புற extensions-களைச் சார்ந்திருக்க வேண்டியிருந்தது, மேலும் ஒவ்வொரு async library-யும் Linux-ன் epoll, BSD-ன் kqueue, Windows-ன் IOCP போன்றவற்றுக்கான தமக்கான back-ends-களை எழுத வேண்டியிருந்தது.
புதிய Polling API அந்த விடுபட்ட பகுதியை நிரப்புகிறது. இது OS-ன் polling வசதிகளைச் (Linux-இல் epoll, BSD/macOS-இல் kqueue போன்றவை) சுற்றி ஒரு மெல்லிய wrapper-ஐ வழங்குகிறது. இந்த API Fibers-ஐ மாற்றீடு செய்யவில்லை; இது event loop-க்குத் தேவையான வேகம் மற்றும் scalability-ஐ வழங்குகிறது.
ReactPHP, Amp மற்றும் நண்பர்களுக்கு இந்த மாற்றம் ஏன் முக்கியமானது
ReactPHP மற்றும் Amp v3 ஆகியவை OS polling mechanisms-களின் மேல் தமக்கான abstraction layers-களைக் கட்டமைத்துள்ளன. அந்த layers பல code paths-களைக் கொண்டுள்ளன, ஒவ்வொன்றும் ஒரு குறிப்பிட்ட தளத்திற்கு (platform) ஏற்றவாறு மாற்றியமைக்கப்பட்டவை, மேலும் அவை kernel மாற்றங்களுடன் ஒத்துப்போக வேண்டும். ஒரு native Polling API மூலம், இந்த நூலகங்கள் அந்தப் பெரும்பாலான சிக்கலான கட்டமைப்புகளைத் தவிர்த்துவிட்டு, core-ஆல் வழங்கப்படும் ஒரு ஒற்றை call-ஐ மட்டும் நம்பியிருக்க முடியும்.
- Maintenance – குறைவான platform-specific branches என்பது குறைவான bugs மற்றும் பாதுகாப்பு ஆய்வுகளுக்கான (security reviews) சிறிய பரப்பளவைக் குறிக்கிறது.
- Performance – இந்த native call நேரடியாக epoll/kqueue உடன் தொடர்பு கொள்கிறது.
- Portability – "vanilla" PHP-இல் இயங்கும் குறியீடு இப்போது கூடுதல் extensions தேவையின்றி, ஆதரிக்கப்படும் அனைத்து இயங்குதளங்களிலும் ஒரே மாதிரியான அடிப்படை செயல்திறனைப் பெறுகிறது.
இதற்கு நேர்மாறாக, Swoole என்பது அதன் சொந்த event loop மற்றும் coroutine system-ஐக் கொண்ட ஒரு முழுமையான runtime replacement ஆகத் தொடர்கிறது. Polling API ஆனது Swoole-ன் வர்த்தகத் தீர்வுகளை (trade-offs) பாதிக்காது; மிகக் குறைந்த latency அல்லது தனிப்பயனாக்கப்பட்ட memory management தேவைப்படும் டெவலப்பர்கள் அதைத் தொடர்ந்து ஒரு தனி விருப்பமாகவே கருதுவார்கள்.
ஒரு விரைவான benchmark உண்மையைச் சொல்கிறது
ஒரு சிறிய scheduler, பல fibers-களை நிர்வகிக்க ஒரு ஒற்றை Io\Poll\Context-ஐப் பயன்படுத்தி, raw sockets மூலம் பல URLs-களைப் பெற்றது. இரண்டு அவதானிப்புகள் வெளிப்பட்டன:
- Speed – அதிகப்படியான concurrent requests-களைச் சேர்ப்பது மொத்த கால அளவை அதிகரிக்காது; அந்த request batch, மிக மெதுவான ஒற்றை request எவ்வளவு விரைவாக முடியுமோ அவ்வளவு விரைவாக முடிந்துவிடும். வேறு வார்த்தைகளில் கூறுவதானால், concurrency overhead என்பது நடைமுறையில் பூஜ்ஜியம் ஆகும்.
- CPU cost –
stream_select()பயன்படுத்தும்போது, streams-களின் எண்ணிக்கை அதிகரிக்கும் போது CPU பயன்பாடு குறிப்பிடத்தக்க அளவில் உயர்கிறது, ஏனெனில் ஒவ்வொரு முறையும் function அனைத்து descriptors மீதும் சுழற்சி (iterate) செய்ய வேண்டும். ஆனால், ஒரே ஒரு system call மூலம் பல descriptors-களைக் கண்காணிக்கும் kernel-ன் திறன் காரணமாக, Polling API-ன் செலவு மூன்று streams முதல் முப்பது streams வரை நிலையாகவே உள்ளது.
டெவலப்பர்கள் இப்போது என்ன செய்ய வேண்டும்
- Amp v3-ஐப் பயன்படுத்தவும் – நீங்கள் புதிய API-உடன் நேரடியாக ஒத்துப்போகும் fiber-native பாணியை விரும்பினால் இதைத் தேர்ந்தெடுக்கவும். அதன் public interface ஏற்கனவே அடிப்படையிலுள்ள poller-உடன் இணைக்கப்பட்டுள்ளது, எனவே உங்கள் குறியீட்டை மீண்டும் எழுதாமலேயே நீங்கள் இதன் பலனைப் பெறலாம்.
- ReactPHP-உடன் தொடரவும் – loop-ன் lifecycle மீது உங்களுக்குத் தெளிவான கட்டுப்பாடு (explicit control) வேண்டுமென்றால் இதைத் தேர்ந்தெடுக்கவும்.
- Production workloads-களுக்குத் தனிப்பயனாக்கப்பட்ட schedulers-களைத் தவிர்க்கவும். Production பயன்பாட்டிற்காகத் தமக்கான scheduler-ஐ எழுத வேண்டாம்.
