Membedah arsitektur internal Swoole: proses Master dan Manager yang mengelola sekumpulan worker dan task processes, event loop berbasis reactor, penjadwalan coroutine, serta memory model per-worker yang menjaga keamanan state antar proses.

Setelah di episode 1 kita memahami mengapa Swoole ada — lahir dari keterbatasan PHP-FPM dan kemenangan benchmark di 2026 — pada episode kali ini kita membedah bagaimana Swoole bekerja di balik layar. Ini adalah fondasi paling penting dalam series: tanpa memahami arsitekturnya, semua episode praktik berikutnya hanya akan menjadi "meniru kode tanpa mengerti".
Mengapa episode ini penting? Karena konfigurasi Swoole (worker_num, dispatch_mode, task_worker_num, dst.) hanyalah nama-nama pada konsep arsitektur yang sama. Ketika kalian paham peran Master, worker, dan event loop, kalian akan membaca setiap config seperti membaca peta, bukan teka-teki.
Swoole adalah multi-process server yang polanya mirip Nginx: satu proses kontrol yang tidak pernah memproses request, dan sekumpulan proses pekerja yang melayaninya:
Peran tiap komponen:
| Komponen | Tugas |
|---|---|
| Master | Proses utama yang paling awal lahir; mengelola signal, fork Manager. Tidak pernah memproses request. |
| Manager | "Orkestrator": me-launch, memantau, dan me-restart worker/task worker yang mati. |
| Worker | Mengeksekusi kode bisnis kalian (on('Request'), on('Message'), dst). |
| Task Worker | Menangani pekerjaan berat yang dikirim lewat task() — dibahas di episode 11. |
| Event Loop (Reactor) | Inti concurrency: mendengarkan socket, membaca data, dan menyalurkan event ke worker. |
Pilihan ini bukan kebetulan. PHP tidak dirancang untuk multi-threading — interpreter, ekstensi, dan library lama pada umumnya tidak thread-safe. Dengan model multi-process, setiap worker adalah interpreter PHP yang berdiri sendiri. Jika satu worker crash karena bug atau exit(), worker lain tidak terpengaruh; Manager tinggal me-restart yang mati.
Analoginya: PHP-FPM juga multi-process, tetapi setiap proses hanya melayani satu request lalu mati. Di Swoole, setiap worker melayani ribuan request secara berurutan dan tetap hidup — di sinilah letak efisiensinya. Proses mati hanya saat direcycle (diatur max_request, episode 20).
Jantung Swoole adalah event loop berbasis epoll (Linux) atau kqueue (macOS). Alur penanganan koneksi kira-kira begini:
Semua langkah ini tidak memblokir. Ketika sebuah coroutine menunggu I/O (misal query database), event loop berpindah mengerjakan coroutine lain yang siap, lalu kembali saat data database tiba. Inilah yang membuat satu worker mampu melayani ribuan koneksi aktif secara bersamaan.
Coroutine adalah titik paling khas Swoole. Kalian menulis kode yang terlihat berurutan dan sinkron:
$resp = $httpClient->get('/api/users');
$data = json_decode($resp->getBody(), true);Sekilas seperti kode PHP biasa — dan justru itulah tujuannya. Di belakang layar, Swoole menyimpan context setiap coroutine (tumpukan stack-nya), lalu menunda eksekusi saat menunggu I/O dan melanjutkannya saat data siap. Tidak ada callback, tidak ada promise chaining.
Perbedaan mental modelnya:
| Model | Cara kerja | Contoh |
|---|---|---|
| Blocking (FPM) | Satu operasi selesai baru operasi berikutnya | file_get_contents |
| Callback (async klasik) | Kode berantakan bersarang | client->on('data', fn => ...) |
| Coroutine (Swoole) | Tulis sinkron, jalankan non-blocking | $client->get() di dalam coroutine |
Penjadwalan coroutine dikendalikan oleh coroutine scheduler di dalam setiap worker. Poin pentingnya:
Coroutine::suspend().Konsekuensi praktisnya: kode CPU-heavy (loop panjang, kompresi) sebaiknya tidak berjalan di worker biasa agar tidak memblokir worker — itulah gunanya task worker (episode 11).
Karena multi-process, memory antar worker tidak dibagi. Konsekuensinya:
| Hal | Behavior |
|---|---|
| Variabel PHP | Terisolasi per worker; tidak bisa diakses worker lain |
| State persist antar request | Bisa disimpan di properti object yang hidup sepanjang worker |
| State shared antar worker | Wajib lewat Swoole\Table (shared memory), Redis, atau Atomic |
| Concurrency dalam satu worker | Aman — request diproses satu per satu |
Ini adalah sumber kebingungan paling umum developer Swoole pemula: menambah counter $count++ di worker ternyata tidak terlihat di worker lain. Untuk counter global, gunakan Swoole\Atomic — kita bahas di episode 12.
Warning
Jangan pernah menyimpan state bisnis penting hanya di variabel PHP biasa bila aplikasi kalian memakai lebih dari satu worker. Karena request bisa masuk ke worker mana pun (bergantung dispatch_mode), state harus hidup di layer yang dibagi: Table, Atomic, Redis, atau database. Ini kesalahan arsitektur nomor satu di aplikasi Swoole produksi.
Pengembangan Swoole berbasis event callback. Server kalian mendaftarkan handler untuk event tertentu:
| Event | Dipicu saat | Episode |
|---|---|---|
on('Start') | Server mulai berjalan | 4 |
on('WorkerStart') | Sebuah worker di-launch | 4 |
on('Request') | Request HTTP diterima | 4-5 |
on('Open') / on('Message') / on('Close') | Koneksi WebSocket | 6 |
on('Task') / on('Finish') | Task diterima / selesai | 11 |
on('PipeMessage') | Pesan antar worker via sendMessage() | 10 |
Model ini konsisten di semua tipe server Swoole — kalian hanya mengganti Swoole\Server dengan Swoole\Http\Server atau Swoole\WebSocket\Server, dan event callback-nya menyesuaikan.
Pada episode 2 ini, kalian telah memahami arsitektur inti Swoole.
Inti yang harus dibawa pulang:
worker_num, task_worker_num, dan dispatch_mode adalah parameter dari arsitektur ini.Di episode 3 selanjutnya, kita masuk ke tangan: instalasi & konfigurasi Swoole — dari pecl install, build options saat kompilasi, hingga setelan php.ini yang wajib kalian ketahui. Sampai jumpa di episode 3!