Async PHP பற்றிய உண்மை: Fibers, epoll, மற்றும் PHP 8.6
நான் பல ஆண்டுகளாக Laravel உடன் பணியாற்றினேன். நான் sync PHP-யைப் பயன்படுத்தினேன். ஒரு கோரிக்கை (request) வரும், செயல்முறை (process) இயங்கும், பின்னர் பதில் (response) செல்லும். எனக்கு async குறியீடு (code) தேவைப்பட்டதே இல்லை.
பிறகு புதிய PHP 8.6 Polling API பற்றி படித்தேன். அது நான் அனைத்தையும் பார்க்கும் விதத்தையே மாற்றியது.
async எவ்வாறு பின்னணியில் (under the hood) செயல்படுகிறது என்பதைப் பற்றி நான் கற்றுக்கொண்டவை இதோ.
The IO Problem
நீங்கள் ஒரு API-யை அழைக்கும்போது, உங்கள் PHP செயல்முறை (process) காத்திருக்கும்.
உதாரணம்:
$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 total: 900ms. Async total: 400ms (மிக மெதுவான அழைப்பின் நேரம்).
தரவுக்காகக் காத்திருக்கும் அதே நேரத்தில், உங்கள் செயல்முறை மற்ற வேலைகளைச் செய்ய async அனுமதிக்கிறது.
Select vs. epoll
async செய்ய, எந்த socket-இல் தரவு தயாராக உள்ளது என்பதை நீங்கள் அறிய வேண்டும்.
select() PHP பதிப்பு 4 முதல் stream_select()-ஐப் பயன்படுத்தி வருகிறது. இது sockets-களின் பட்டியலைக் கண்காணிக்க kernel-இடம் கேட்பதன் மூலம் செயல்படுகிறது. சிக்கல்: தரவு வரும் ஒவ்வொரு முறையும், நீங்கள் முழுப் பட்டியலையும் மீண்டும் ஸ்கேன் செய்ய வேண்டும். இது ஒரு rescan tax போன்றது. மேலும் இது சுமார் 1024 இணைப்புகளுக்கு மட்டுமே வரம்பு கொண்டது.
epoll (Linux) / kqueue (macOS) இவை kernel அம்சங்கள். ஒரு பட்டியலை ஸ்கேன் செய்வதற்குப் பதிலாக, kernel ஒரு ready-list-ஐ வைத்திருக்கும். எந்த குறிப்பிட்ட sockets தயாராக உள்ளன என்பதை மட்டுமே அது உங்களுக்குத் தெரிவிக்கும். இது கூடுதல் வேலை இன்றி ஆயிரக்கணக்கான இணைப்புகளுக்குத் தடையின்றிச் செயல்படும் (scales).
epoll என்பது PHP அம்சம் அல்ல. இது ஒரு Linux அம்சம். Go, Rust மற்றும் Node.js ஆகிய அனைத்தும் இதைப் பயன்படுத்துகின்றன.
Fibers: The Pause Button
PHP 8.1 Fibers-ஐ அறிமுகப்படுத்தியது. Fibers தானாகவே விழித்துக்கொள்ளும் என்று நான் நினைத்தேன். ஆனால் அவை அவ்வாறு செய்வதில்லை.
ஒரு Fiber என்பது நிறுத்தப்பட்ட (paused) வீடியோவைப் போன்றது. யாராவது $fiber->resume() என்று அழைக்கும் வரை அது நிறுத்தப்பட்ட நிலையிலேயே இருக்கும்.
ஒரு Event Loop என்பது எப்போது resume() என்று அழைக்க வேண்டும் என்பதைத் தீர்மானிக்கும் ஒரு PHP குறியீடு மட்டுமே.
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 இந்த இடைவெளியை நிரப்புகிறது. இது ஒரு native Polling API-யை அதன் core-க்குள் கொண்டுவருகிறது. இப்போது, PHP கூடுதல் extensions இன்றி நேரடியாக epoll அல்லது kqueue-ஐப் பயன்படுத்த முடியும்.
The Takeaway
நீங்கள் Laravel-ஐ PHP-FPM உடன் பயன்படுத்தினால், இன்று நீங்கள் எதையும் மாற்ற வேண்டிய அவசியமில்லை.
ஆனால் இதைத் தெரிந்து கொள்ளுங்கள்: Async என்பது மந்திரம் அல்ல. இது காத்திருக்கும் நேரத்தை நிர்வகிப்பதற்கான ஒரு புத்திசாலித்தனமான வழி மட்டுமே.
வெறும் குறியீடுகளைப் பயன்படுத்துவதை மட்டும் நிறுத்திக் கொள்ளுங்கள். ஒரு எளிய ஸ்கிரிப்டை இயக்கிப் பாருங்கள். அதை உடைத்துப் பாருங்கள். அதுதான் நீங்கள் உண்மையாகக் கற்றுக்கொள்ளும் வழி.
