Async PHP ಬಗ್ಗೆ ಸತ್ಯ: Fibers, epoll, ಮತ್ತು PHP 8.6
ನಾನು ವರ್ಷಗಳ ಕಾಲ Laravel ನೊಂದಿಗೆ ಕೆಲಸ ಮಾಡಿದ್ದೇನೆ. ನಾನು sync PHP ಬಳಸುತ್ತಿದ್ದೆ. ಒಂದು ರಿಕ್ವೆಸ್ಟ್ ಬರುತ್ತದೆ, ಪ್ರಕ್ರಿಯೆ (process) ನಡೆಯುತ್ತದೆ ಮತ್ತು ರೆಸ್ಪಾನ್ಸ್ ಹೋಗುತ್ತದೆ. ನನಗೆ ಎಂದಿಗೂ async ಕೋಡ್ನ ಅಗತ್ಯವಿರಲಿಲ್ಲ.
ನಂತರ ನಾನು ಹೊಸ PHP 8.6 Polling API ಬಗ್ಗೆ ಓದಿದೆ. ಅದು ನಾನು ಎಲ್ಲವನ್ನೂ ನೋಡುವ ರೀತಿಯನ್ನೇ ಬದಲಿಸಿತು.
async ಒಳಗಿನಿಂದ ಹೇಗೆ ಕೆಲಸ ಮಾಡುತ್ತದೆ ಎಂಬುದರ ಬಗ್ಗೆ ನಾನು ಕಲಿತ ವಿಷಯಗಳು ಇಲ್ಲಿವೆ.
IO ಸಮಸ್ಯೆ
ನೀವು ಒಂದು API ಅನ್ನು ಕರೆ ಮಾಡಿದಾಗ, ನಿಮ್ಮ PHP ಪ್ರಕ್ರಿಯೆಯು (process) ಕಾಯುತ್ತದೆ.
ಉದಾಹರಣೆ:
$response = Http::get('https://api.example.com');
ಆ ಕರೆಗೆ 300ms ತಗುಲಿದರೆ, ನಿಮ್ಮ CPU 300ms ಕಾಲ ಏನನ್ನೂ ಮಾಡದೆ ಇರುತ್ತದೆ. ಅದು ಸ್ಲೀಪ್ (sleep) ಸ್ಥಿತಿಯಲ್ಲಿರುತ್ತದೆ. ಇದನ್ನೇ blocking I/O ಎನ್ನುತ್ತಾರೆ.
ನಿಮ್ಮ ಬಳಿ ಮೂರು API ಕರೆಗಳಿದ್ದರೆ:
- API A: 300ms
- API B: 400ms
- API C: 200ms
Sequential ಒಟ್ಟು ಸಮಯ: 900ms. Async ಒಟ್ಟು ಸಮಯ: 400ms (ಅತಿ ನಿಧಾನವಾದ ಕರೆಯ ಸಮಯ).
ಡೇಟಾಕ್ಕಾಗಿ ಕಾಯುವಾಗ, ನಿಮ್ಮ ಪ್ರಕ್ರಿಯೆಯು (process) ಇತರ ಕೆಲಸಗಳನ್ನು ಮಾಡಲು async ಅನುಮತಿಸುತ್ತದೆ.
Select vs. epoll
async ಮಾಡಲು, ಯಾವ ಸಾಕೆಟ್ನಲ್ಲಿ (socket) ಡೇಟಾ ಸಿದ್ಧವಾಗಿದೆ ಎಂದು ನಿಮಗೆ ತಿಳಿಯಬೇಕಾಗುತ್ತದೆ.
select() PHP ವರ್ಷನ್ 4 ರಿಂದ
stream_select()ಅನ್ನು ಬಳಸುತ್ತಿದೆ. ಇದು ಸಾಕೆಟ್ಗಳ ಪಟ್ಟಿಯನ್ನು ಗಮನಿಸಲು ಕರ್ನಲ್ (kernel) ಅನ್ನು ಕೇಳುವ ಮೂಲಕ ಕೆಲಸ ಮಾಡುತ್ತದೆ. ಸಮಸ್ಯೆ: ಪ್ರತಿ ಬಾರಿ ಡೇಟಾ ಬಂದಾಗಲೂ, ನೀವು ಇಡೀ ಪಟ್ಟಿಯನ್ನು ಮತ್ತೆ ಸ್ಕ್ಯಾನ್ ಮಾಡಬೇಕಾಗುತ್ತದೆ. ಇದನ್ನು 'rescan tax' ಎನ್ನಬಹುದು. ಇದು ಸುಮಾರು 1024 ಕನೆಕ್ಷನ್ಗಳ ಮಿತಿಯನ್ನು ಸಹ ಹೊಂದಿದೆ.epoll (Linux) / kqueue (macOS) ಇವು ಕರ್ನಲ್ ಫೀಚರ್ಗಳು. ಪಟ್ಟಿಯನ್ನು ಸ್ಕ್ಯಾನ್ ಮಾಡುವ ಬದಲು, ಕರ್ನಲ್ ಒಂದು 'ready-list' ಅನ್ನು ಇಟ್ಟುಕೊಳ್ಳುತ್ತದೆ. ಯಾವ ನಿರ್ದಿಷ್ಟ ಸಾಕೆಟ್ಗಳು ಸಿದ್ಧವಾಗಿವೆ ಎಂದು ಇದು ನಿಮಗೆ ಮಾತ್ರ ತಿಳಿಸುತ್ತದೆ. ಇದು ಯಾವುದೇ ಹೆಚ್ಚಿನ ಕೆಲಸವಿಲ್ಲದೆ ಸಾವಿರಾರು ಕನೆಕ್ಷನ್ಗಳಿಗೆ ವಿಸ್ತರಿಸುತ್ತದೆ (scales).
epoll ಎಂಬುದು PHP ಫೀಚರ್ ಅಲ್ಲ. ಇದು ಒಂದು Linux ಫೀಚರ್. Go, Rust, ಮತ್ತು Node.js ಎಲ್ಲವೂ ಇದನ್ನು ಬಳಸುತ್ತವೆ.
Fibers: ಪಾಸ್ ಬಟನ್ (The Pause Button)
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 ಅನ್ನು ಬಳಸಬಹುದು.
ಮುಖ್ಯ ಅಂಶ (The Takeaway)
ನೀವು PHP-FPM ನೊಂದಿಗೆ Laravel ಬಳಸುತ್ತಿದ್ದರೆ, ಇಂದು ನೀವು ಏನನ್ನೂ ಬದಲಾಯಿಸುವ ಅಗತ್ಯವಿಲ್ಲ.
ಆದರೆ ಇದನ್ನು ಅರ್ಥಮಾಡಿಕೊಳ್ಳಿ: Async ಎಂಬುದು ಮ್ಯಾಜಿಕ್ ಅಲ್ಲ. ಇದು ಕೇವಲ ಕಾಯುವ ಸಮಯವನ್ನು ನಿರ್ವಹಿಸುವ ಒಂದು ಸ್ಮಾರ್ಟ್ ವಿಧಾನವಾಗಿದೆ.
ಕೇವಲ ಕೋಡ್ ಅನ್ನು ಬಳಸುವುದನ್ನು ನಿಲ್ಲಿಸಿ. ಒಂದು ಸರಳ ಸ್ಕ್ರಿಪ್ಟ್ ಅನ್ನು ರನ್ ಮಾಡಿ. ಅದನ್ನು ಬ್ರೇಕ್ ಮಾಡಿ. ಹಾಗೆ ಮಾಡಿದಾಗ ಮಾತ್ರ ನೀವು ನಿಜವಾಗಿ ಕಲಿಯುತ್ತೀರಿ.
