Async PHP Hakkındaki Gerçekler: Fibers, epoll ve PHP 8.6

Yıllarca Laravel ile çalıştım. Senkron (sync) PHP kullandım. Bir istek gelir, işlem çalışır ve yanıt gider. Asenkron koda hiç ihtiyacım olmamıştı.

Sonra yeni PHP 8.6 Polling API hakkında okudum. Bu, her şeye bakış açımı değiştirdi.

Asenkron yapının arka planda nasıl çalıştığına dair öğrendiklerim şunlar:

I/O Problemi

Bir API çağırdığınızda, PHP işleminiz bekler. Örnek: $response = Http::get('https://api.example.com');

Eğer bu çağrı 300ms sürerse, CPU'nuz 300ms boyunca hiçbir şey yapmaz. Uyku modunda kalır. Bu, engelleyici (blocking) I/O'dur.

Üç API çağrınız varsa:

  • API A: 300ms
  • API B: 400ms
  • API C: 200ms

Sıralı toplam: 900ms. Asenkron toplam: 400ms (en yavaş çağrının süresi).

Asenkron yapı, veri beklenirken işleminizin başka işler yapmasına olanak tanır.

Select vs. epoll

Asenkron işlem yapmak için hangi soketin veriye hazır olduğunu bilmeniz gerekir.

  1. select() PHP, versiyon 4'ten beri stream_select() kullanıyor. Çekirdekten (kernel) bir soket listesini izlemesini isteyerek çalışır. Sorun: Her veri geldiğinde tüm listeyi tekrar taramanız gerekir. Bu bir "yeniden tarama maliyeti"dir (rescan tax). Ayrıca yaklaşık 1024 bağlantı sınırı vardır.

  2. epoll (Linux) / kqueue (macOS) Bunlar çekirdek özellikleridir. Bir listeyi taramak yerine, çekirdek bir "hazır listesi" (ready-list) tutar. Size yalnızca hangi belirli soketlerin hazır olduğunu söyler. Bu, ekstra iş yükü olmadan binlerce bağlantıya ölçeklenebilir.

epoll bir PHP özelliği değildir. Bir Linux özelliğidir. Go, Rust ve Node.js'in hepsi bunu kullanır.

Fibers: Duraklatma Düğmesi

PHP 8.1 ile Fibers tanıtıldı. Fibers'ın kendi kendine uyanacağını düşünmüştüm. Uyanmıyorlar.

Bir Fiber, duraklatılmış bir video gibidir. Birisi $fiber->resume() çağırana kadar duraklatılmış halde kalır.

Bir Event Loop, yalnızca ne zaman resume() çağrılacağına karar veren bir PHP kod parçasıdır.

Asenkron I/O üç parça gerektirir:

  • Duraklat: Fibers (PHP 8.1 çekirdeği)
  • Karar Ver: Event Loop (Düz PHP kodu)
  • Bil: Kernel Polling (epoll/kqueue)

PHP 8.6'dan önce, PHP "Duraklat" ve "Karar Ver" kısımlarına sahipti ancak "Bil" kısmı eski select() yöntemine veya yavaş C eklentilerine (extensions) dayanıyordu.

PHP 8.6 bu boşluğu kapatıyor. Çekirdeğe yerleşik (native) bir Polling API getiriyor. Artık PHP, ekstra eklentilere ihtiyaç duymadan doğrudan epoll veya kqueue kullanabilir.

Özetle

Eğer Laravel'i PHP-FPM ile kullanıyorsanız, bugün herhangi bir şeyi değiştirmenize gerek yok.

Ancak şunu anlayın: Asenkron yapı sihir değildir. Sadece bekleme süresini yönetmenin akıllıca bir yoludur.

Sadece kod tüketmeyi bırakın. Basit bir betik (script) çalıştırın. Onu bozun. Gerçekten böyle öğrenirsiniz.

Kaynak: https://dev.to/alamriku/sync-php-developer-hisebe-async-php-bujhte-giye-yaa-shikhlaam-fibers-epoll-aar-php-86-462j