Classe Worker
OxPHP\Server\Worker est le handle d'exécution unifié pour tout ce qui est lié à un seul thread worker OS d'OxPHP. C'est un wrapper final et sans état par-dessus l'état thread-local du bridge, enregistré par l'extension SAPI elle-même, si bien qu'il est toujours disponible aussi bien en mode traditionnel qu'en mode worker. Chaque appel lit l'état vivant directement depuis le runtime ; l'objet lui-même ne met rien en cache.
Worker::current() renvoie un singleton par thread OS : deux appels sur le même thread renvoient toujours la même instance.
Référence rapide
| Méthode | Description |
|---|---|
Worker::current(): self |
Renvoie le handle singleton pour le thread OS courant. |
Worker::isWorkerMode(): bool |
Renvoie true si le serveur tourne en mode worker (c.-à-d. WORKER_MODE_ENABLED=true). |
id(): int |
Identifiant numérique du worker dans la plage 0..N-1 pour le thread OS courant. |
startTime(): float |
Timestamp Unix (en secondes) du moment où ce thread worker OS a été lancé. |
requestCount(): int |
Nombre de requêtes traitées par ce thread OS (compté à partir de 1). Augmente dans les deux modes. |
memoryUsage(): int |
Utilisation mémoire PHP vivante en octets (zend_memory_usage(0)). |
rss(): int |
Taille de l'ensemble résident (RSS) du processus en octets. Non mis en cache — à appeler au plus une fois par requête. |
maxMemoryBytes(): int |
Plafond mémoire configuré en octets. 0 signifie illimité. |
scheduleExit(): void |
Marque le worker pour un arrêt gracieux après la fin de la requête courante. Sans effet en mode traditionnel. |
isExitScheduled(): bool |
Renvoie true si scheduleExit() a été appelée pour le worker courant. Toujours false en mode traditionnel. |
exitReason(): ?string |
Raison de l'arrêt en attente : 'scheduled', 'max_memory', 'error', ou null quand aucun arrêt n'est en attente. Toujours null en mode traditionnel. |
serve(callable $h): void |
Entre dans la boucle de requêtes. Lève InvalidServeContextException en dehors du mode worker. |
Matrice des modes
| Méthode | Mode traditionnel | Mode worker |
|---|---|---|
current() |
Singleton par thread OS. | Singleton par thread OS. |
isWorkerMode() |
false |
true |
id() |
Index du thread OS dans le pool de workers. | Index du thread OS dans le pool de workers. |
startTime() |
Moment où le thread OS a été lancé (généralement le démarrage du serveur). | Moment où le thread OS a été lancé. |
requestCount() |
Compté à partir de 1, s'incrémente au fil des requêtes qui réutilisent le même thread OS (1, 2, 3, …). |
Compté à partir de 1, s'incrémente à chaque requête traitée par le worker. |
memoryUsage() |
Mémoire PHP vivante au moment de l'appel. | Mémoire PHP vivante au moment de l'appel. |
rss() |
RSS vivant du processus. | RSS vivant du processus. |
maxMemoryBytes() |
0 (aucun plafond de recyclage ne s'applique). |
Valeur de WORKER_MAX_MEMORY_MIB × 1 Mio, ou 0 si non défini. |
scheduleExit() |
Sans effet (le script se termine de toute façon). | Positionne le drapeau d'arrêt ; la boucle de requêtes s'arrête après le retour du handler courant. |
isExitScheduled() |
Toujours false. |
true après que scheduleExit() a été appelée sur ce thread. |
exitReason() |
Toujours null. |
null jusqu'à ce qu'un arrêt soit en attente ; ensuite l'une des valeurs 'scheduled', 'max_memory', 'error'. |
serve(callable) |
Lève OxPHP\Server\Exception\InvalidServeContextException. |
Entre dans la boucle de requêtes. |
Exemples
Contexte de journalisation par worker
Étiquetez chaque ligne de journal avec l'id du worker et le compteur de requêtes par thread, afin de pouvoir corréler le trafic de requêtes avec un worker donné.
<?php
$worker = OxPHP\Server\Worker::current();
$logger->info('handling request', [
'worker_id' => $worker->id(),
'request_number' => $worker->requestCount(),
]);Bootstrap une seule fois par thread OS
requestCount() est compté à partir de 1, si bien que la première requête traitée par un thread quelconque voit la valeur 1. C'est un endroit portable pour exécuter une initialisation paresseuse par thread qui ne doit se produire qu'exactement une fois.
<?php
$worker = OxPHP\Server\Worker::current();
if ($worker->requestCount() === 1) {
bootstrap();
}scheduleExit
Recyclage de worker piloté par l'application. La requête courante se termine normalement ; la boucle vérifie ensuite isExitScheduled() et en sort. Le superviseur relance un worker frais, ré-exécutant la portée externe du fichier worker.
<?php
$worker = OxPHP\Server\Worker::current();
handleRequest();
// Reload bootstrap on every request when developing locally.
if (getenv('OXPHP_DEV') === '1') {
$worker->scheduleExit();
}scheduleExit() est idempotente et sans effet en dehors du mode worker. Cas d'usage :
-
Rechargement à chaud pendant le développement. Sortir après chaque requête pour que le bootstrap de la portée externe soit ré-exécuté.
-
Recyclage basé sur le RSS.
WORKER_MAX_MEMORY_MIBne mesure que l'allocateur Zend. Avec des piles riches en extensions (curl, mysqli), vous pouvez en plus recycler quand le RSS du processus franchit votre propre seuil :if ($worker->rss() > 256 * 1024 * 1024) { $worker->scheduleExit(); } -
Redémarrages progressifs coordonnés. Conditionnez l'appel à un fichier sentinelle ou à un signal pour qu'un orchestrateur externe puisse drainer les workers proprement.
Point d'entrée du worker
Dans un script de bootstrap de worker, appelez serve() pour entrer dans la boucle de requêtes.
<?php
require __DIR__ . '/../vendor/autoload.php';
OxPHP\Server\Worker::current()->serve(function () {
handleRequest();
});Observabilité du RSS
rss() renvoie la taille de l'ensemble résident (RSS) vivant du processus en octets. L'appel est un véritable appel système : peu coûteux, mais pas gratuit. Lisez-le au plus une fois par requête.
<?php
$worker = OxPHP\Server\Worker::current();
$rss = $worker->rss();
$metrics->gauge('php_worker_rss_bytes', $rss, [
'worker_id' => (string) $worker->id(),
]);Migration depuis les fonctions oxphp_*
Les anciennes fonctions libres restent disponibles et passent par le même état interne. Elles ne sont pas dépréciées. Le nouveau code devrait privilégier l'API de classe pour la découvrabilité et la cohérence.
| Fonction héritée | API de classe |
|---|---|
oxphp_is_worker() |
OxPHP\Server\Worker::isWorkerMode() |
oxphp_worker_id() |
OxPHP\Server\Worker::current()->id() |
oxphp_worker(callable) |
OxPHP\Server\Worker::current()->serve(callable) |
Points d'attention
rss()n'est pas mis en cache. Chaque appel effectue un appel système (lecture de/proc/self/statmsous Linux,getrusage(RUSAGE_SELF)sous macOS). Peu coûteux mais pas gratuit, alors appelez-le au plus une fois par requête, typiquement dans un handler de métriques, et non sur chaque ligne de journal.- Le clonage est interdit.
clone $workerlève\Error("Cloning OxPHP\\Server\\Worker is not allowed"). Le handle worker représente l'identité d'un thread OS ; le cloner donnerait l'impression trompeuse d'un second handle pour le même thread. - En dehors d'un hôte OxPHP (par exemple lorsqu'une extension liant le SAPI est chargée dans le PHP CLI),
Worker::current()renvoie toujours une instance, mais chaque accesseur renvoie sa valeur d'état zéro :id()vaut0,startTime()est le moment de démarrage du processus,requestCount()vaut0,rss()est le RSS vivant, etserve()lèveInvalidServeContextException.
Voir aussi
- Mode worker — vue d'ensemble des processus PHP persistants et du motif « bootstrap une seule fois »
- Fonctions PHP — référence des anciennes fonctions libres
oxphp_* - API de requête —
OxPHP\Http\RequestInterface::startTime()pour la mesure du temps par requête