Signatur
Beschreibung
EvEmbed ermöglicht es, einen separaten EvLoop in einen übergeordneten Loop zu integrieren. Das ist besonders nützlich, wenn bestimmte Backends (z. B. kqueue auf macOS) nur für bestimmte Dateideskriptoren (etwa Sockets) zuverlässig funktionieren, während der Haupt-Loop ein anderes Backend (z. B. select oder epoll) nutzt. Durch das Einbetten kann man die Stärken beider Backends kombinieren.
Der eingebettete Loop muss ein einbettbares Backend verwenden – typischerweise wird vor der Erstellung geprüft, ob das gewünschte Backend die Einbettung unterstützt (Ev::embeddableBackends()). Sobald der Watcher aktiv ist, ruft der Haupt-Loop regelmäßig den eingebetteten Loop ab und verarbeitet dessen ausstehende Ereignisse.
Wichtig: Nicht jedes Backend ist einbettbar. Vor der Verwendung sollte man mit Ev::embeddableBackends() prüfen, welche Backends auf dem aktuellen System eingebettet werden dürfen. Unter Linux ist epoll in der Regel einbettbar, unter macOS und BSD ist es häufig kqueue.
Die Klasse erbt alle Methoden von EvWatcher, insbesondere start(), stop() und keepalive().
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $other Pflicht | EvLoop | Der einzubettende EvLoop. Dieser Loop muss ein einbettbares Backend nutzen (geprüft via Ev::embeddableBackends()). |
|
| $callback | callable | null | Optionaler Callback, der aufgerufen wird, wenn der eingebettete Loop Ereignisse verarbeitet hat. Erhält die üblichen Watcher-Argumente $watcher und $revents. |
| $data | mixed | null | Beliebige benutzerdefinierte Daten, die dem Watcher zugeordnet werden (zugänglich über $watcher->data). |
| $priority | int | 0 | Priorität des Watchers. Höhere Werte bedeuten höhere Priorität. Erlaubte Werte: Ev::MINPRI bis Ev::MAXPRI. |
Beispiele
kqueue-Loop in den Standard-Loop einbetten
<?php
// Prüfen, ob kqueue eingebettet werden kann
$embeddable = Ev::embeddableBackends();
if ($embeddable & Ev::BACKEND_KQUEUE) {
// Eigenen Loop mit kqueue-Backend anlegen
$kqLoop = new EvLoop(Ev::BACKEND_KQUEUE);
// kqueue-Loop in den Standard-Loop einbetten
$embed = new EvEmbed($kqLoop, function ($watcher, $revents) {
echo "Eingebetteter Loop hat Ereignisse verarbeitet.\n";
});
// Beispielhafter I/O-Watcher im eingebetteten Loop
$io = $kqLoop->io(
STDIN,
Ev::READ,
function ($watcher, $revents) use ($kqLoop) {
echo "Eingabe empfangen.\n";
$watcher->stop();
$kqLoop->stop();
Ev::stop();
}
);
// Standard-Loop starten (verarbeitet automatisch den eingebetteten Loop)
Ev::run();
} else {
echo "kqueue ist auf diesem System nicht einbettbar.\n";
}
Eingebetteten Loop manuell sweepen
<?php
// Prüfen, ob epoll eingebettet werden kann (typisch unter Linux)
$embeddable = Ev::embeddableBackends();
if ($embeddable & Ev::BACKEND_EPOLL) {
$innerLoop = new EvLoop(Ev::BACKEND_EPOLL);
$embed = new EvEmbed($innerLoop);
// Timer im Haupt-Loop, der den eingebetteten Loop periodisch abfragt
$timer = new EvTimer(0, 0.1, function () use ($embed) {
// Manuell den eingebetteten Loop sweepen
$embed->sweep();
});
// I/O-Watcher im inneren Loop
$io = $innerLoop->io(STDIN, Ev::READ, function ($w, $revents) use ($innerLoop) {
echo "Daten verfügbar.\n";
$w->stop();
Ev::stop();
});
Ev::run();
} else {
echo "epoll ist auf diesem System nicht einbettbar.\n";
}
// Wichtig · Fallstricke
Einbettbarkeit prüfen: Nicht alle Backends können eingebettet werden. Ein Loop, der mit einem nicht einbettbaren Backend erstellt wurde, kann nicht als other übergeben werden – dies führt zu einem Fehler. Verwende immer Ev::embeddableBackends() zur Vorprüfung.
Methode sweep(): EvEmbed stellt die Methode sweep() bereit, die den eingebetteten Loop einmalig manuell abfragt, ohne den Haupt-Loop zu blockieren. Das ist nützlich, wenn eine manuelle Kontrolle über den Iterationsrhythmus gewünscht wird.
Plattformabhängigkeit: Dieses Feature ist eng an die verfügbaren System-Backends gebunden und verhält sich unter Linux, macOS und BSD unterschiedlich. Portable Anwendungen sollten einen Fallback-Pfad implementieren, falls kein einbettbares Backend verfügbar ist.