Uzantı işçileri
Uzantı İşçileri, FrankenPHP uzantınızın arka plan görevlerini yürütmek, eşzamansız olayları işlemek veya özel protokolleri uygulamak için özel bir PHP iş parçacığı havuzunu yönetmesini sağlar. Kuyruk sistemleri, olay dinleyicileri, zamanlayıcılar vb. için kullanışlıdır.
İşçiyi kaydetme
Statik kayıt
İşçiyi kullanıcı tarafından yapılandırılabilir hale getirmeniz gerekmiyorsa (sabit komut dosyası yolu, sabit iş parçacığı sayısı), işçiyi init() fonksiyonunda basitçe kaydedebilirsiniz.
package myextension
import (
"github.com/dunglas/frankenphp"
"github.com/dunglas/frankenphp/caddy"
)
// İşçi havuzuyla iletişim kurmak için genel tanıtıcı
var worker frankenphp.Workers
func init() {
// Modül yüklendiğinde işçiyi kaydet.
worker = caddy.RegisterWorkers(
"my-internal-worker", // Benzersiz isim
"worker.php", // Komut dosyası yolu (çalışmaya göre veya mutlak)
2, // Sabit iş parçacığı sayısı
// İsteğe bağlı Yaşam Döngüsü Kancaları
frankenphp.WithWorkerOnServerStartup(func() {
// Genel kurulum mantığı...
}),
)
}
Bir Caddy modülünde (kullanıcı tarafından yapılandırılabilir)
Uzantınızı paylaşmayı planlıyorsanız (genel bir kuyruk veya olay dinleyici gibi), onu bir Caddy modülüne sarmalısınız. Bu, kullanıcıların Caddyfile aracılığıyla komut dosyası yolunu ve iş parçacığı sayısını yapılandırmasına olanak tanır. Bu, caddy.Provisioner arayüzünü uygulamayı ve Caddyfile’ı ayrıştırmayı gerektirir (bir örnek görmek için).
Saf bir Go uygulamasında (gömme)
FrankenPHP’yi Caddy olmadan standart bir Go uygulamasına gömüyorsanız, seçenekleri başlatırken frankenphp.WithExtensionWorkers kullanarak uzantı işçilerini kaydedebilirsiniz.
İşçilerle etkileşim kurma
İşçi havuzu aktif hale geldiğinde, ona görevler gönderebilirsiniz. Bu, PHP’ye dışa aktarılan yerel fonksiyonlar içinde veya bir cron zamanlayıcı, bir olay dinleyicisi (MQTT, Kafka) veya herhangi başka bir goroutine gibi herhangi bir Go mantığından yapılabilir.
Başsız mod : SendMessage
Doğrudan işçi komut dosyanıza ham veri geçirmek için SendMessage kullanın. Bu, kuyruklar veya basit komutlar için idealdir.
Örnek: asenkron bir kuyruk uzantısı
// #include <Zend/zend_types.h>
import "C"
import (
"context"
"unsafe"
"github.com/dunglas/frankenphp"
)
//export_php:function my_queue_push(mixed $data): bool
func my_queue_push(data *C.zval) bool {
// 1. İşçinin hazır olduğundan emin olun
if worker == nil {
return false
}
// 2. Arka plan işçisine gönder
_, err := worker.SendMessage(
context.Background(), // Standart Go bağlamı
unsafe.Pointer(data), // İşçiye iletilecek veri
nil, // İsteğe bağlı http.ResponseWriter
)
return err == nil
}
HTTP emülasyonu :SendRequest
Uzantınızın standart bir web ortamı bekleyen ( $_SERVER, $_GET vb. dolduran) bir PHP komut dosyasını çağırması gerekiyorsa SendRequest kullanın.
// #include <Zend/zend_types.h>
import "C"
import (
"net/http"
"net/http/httptest"
"unsafe"
"github.com/dunglas/frankenphp"
)
//export_php:function my_worker_http_request(string $path): string
func my_worker_http_request(path *C.zend_string) unsafe.Pointer {
// 1. İsteği ve kaydediciyi hazırla
url := frankenphp.GoString(unsafe.Pointer(path))
req, _ := http.NewRequest("GET", url, http.NoBody)
rr := httptest.NewRecorder()
// 2. İşçiye gönder
if err := worker.SendRequest(rr, req); err != nil {
return nil
}
// 3. Yakalanan yanıtı döndür
return frankenphp.PHPString(rr.Body.String(), false)
}
İşçi komut dosyası
PHP işçi komut dosyası bir döngüde çalışır ve hem ham mesajları hem de HTTP isteklerini işleyebilir.
<?php
// Hem ham mesajları hem de HTTP isteklerini aynı döngüde işle
$handler = function ($payload = null) {
// Durum 1: Mesaj Modu
if ($payload !== null) {
return "Received payload: " . $payload;
}
// Durum 2: HTTP Modu (standart PHP süper küreselleri doldurulur)
echo "Hello from page: " . $_SERVER['REQUEST_URI'];
};
while (frankenphp_handle_request($handler)) {
gc_collect_cycles();
}
Yaşam döngüsü kancaları
FrankenPHP, yaşam döngüsünün belirli noktalarında Go kodunu yürütmek için kancalar sağlar.
| Kanca türü | Seçenek adı | İmza | Bağlam ve kullanım durumu |
|---|---|---|---|
| Sunucu | WithWorkerOnServerStartup |
func() |
Genel kurulum. Bir Kez çalışır. Örnek: NATS/Redis’e bağlanma. |
| Sunucu | WithWorkerOnServerShutdown |
func() |
Genel temizleme. Bir Kez çalışır. Örnek: Paylaşılan bağlantıları kapatma. |
| İş Parçacığı | WithWorkerOnReady |
func(threadID int) |
İş parçacığı başına kurulum. Bir iş parçacığı başladığında çağrılır. İş Parçacığı Kimliğini alır. |
| İş Parçacığı | WithWorkerOnShutdown |
func(threadID int) |
İş parçacığı başına temizleme. İş Parçacığı Kimliğini alır. |
Örnek
package myextension
import (
"fmt"
"github.com/dunglas/frankenphp"
frankenphpCaddy "github.com/dunglas/frankenphp/caddy"
)
func init() {
workerHandle = frankenphpCaddy.RegisterWorkers(
"my-worker", "worker.php", 2,
// Sunucu Başlatma (Genel)
frankenphp.WithWorkerOnServerStartup(func() {
fmt.Println("Uzantı: Sunucu başlıyor...")
}),
// İş Parçacığı Hazır (İş Parçacığı Başına)
// Not: Fonksiyon, İş Parçacığı Kimliğini temsil eden bir tamsayı kabul eder
frankenphp.WithWorkerOnReady(func(id int) {
fmt.Printf("Uzantı: İşçi iş parçacığı #%d hazır.\n", id)
}),
)
}