Die meisten Programmiersprachen enthalten Konstrukte für nebenläufiges Programmieren. In PHP schickt sich das Projekt Swoole an, Concurrency nach dem Vorbild von Google Go einzuführen. Andrei Avram erklärt, wie das geht!
Swoole ist ein CLI Server und wurde als PHP-Extension in C geschrieben. Der Server verarbeitet HTTP, TCP und Socket-Server und bietet einige wirklich interessante Funktionen. Die Features, die ich getestet habe – und von denen ich ziemlich begeistert bin -, beschäftigen sich mit Concurrency.
Die Entwickler von Swoole haben ein Concurrency-Modell implementiert, das sehr an das von Go erinnert. Das Modell verwendet Co-Routinen und Kanäle für die prozessübergreifende Kommunikation. Es verfügt über eine Memory Map, atomare Objekte, Locks, Puffer, Timer und vieles andere mehr.
Ausprobiert habe ich Swoole in der Version 2.2, die ich über das PECL-Repository installiert habe. Erst kürzlich ist indes Version 4.0.0 erschienen. Meine Begeisterung darüber wurde allerdings ein wenig dadurch gedämpft, dass mit Swoole 4.0.0 ein ziemlich gravierender Bug ausgeliefert wurde. Aber das Swoole-Team war schnell dabei, den Fehler zu beheben (eine neue Version war zum Zeitpunkt des Schreibens dieses Beitrags allerdings noch nicht verfügbar – den Bugfix kann man dennoch durch das Kompilieren vom Master Branch erhalten).
Schauen wir uns ein kleines Beispiel an, wie Concurrency mittels Routinen auf einem Kanal funktioniert.
Wir beginnen mit der traditionellen Art, über eine Reihe von Daten zu iterieren und eine Validierungsfunktion aufzurufen. Wenn die Funktion slowValidationFunction eine Sekunde benötigt, dauert es für 60 Elemente eine Minute, um den gesamten Prozess zu validieren.
$items = ["item1", "item2", "item3" ...];
$size = count($items);
$chan = new chan($size);
$result = [];
foreach ($items as $item) {
$valid = slowValidationFunction($item);
$result[$item] = $valid;
}
print_r($result);
Beim parallelen Aufruf der slowValidationFunction dauert alles insgesamt eine Sekunde. Die Begrenzung für diese Methode liegt in den Hardware-Ressourcen (RAM und in einigen Fällen die CPU).
$items = ["item1", "item2", "item3" ...];
$size = count($items);
$chan = new chan($size);
foreach ($items as $item) {
go(function () use($item, $chan) {
$valid = slowValidationFunction($item);
$chan->push([$item => $valid]);
});
}
$result = [];
for ($i = $size; $i > 0; $i--) {
$result = array_merge($result, $chan->pop());
}
Wer Go kennt, dürfte die Codebeispiele auf Anhieb verstehen. Die Idee dabei ist die folgende:
Mit Co-Routinen können allerdings subtile Probleme entstehen, die manchmal schwer manuell zu debuggen sind. Deshalb arbeiten die Entwickler derzeit an einem Debugging-Tool für Co-Routinen. Xdebug ist an dieser Stelle wenig hilfreich.
Swoole lässt sich einfach via PECL installieren:
pecl install swoole-2.2.0
Wer Swoole einmal selbst ausprobieren möchte, findet auf GitHub eine vollständige Umgebung und eine etwas umfangreichere Anwendung als die hier gezeigte. Die Dokumentation gibt’s auf der Swoole-Website sowie auf php.net.
Soweit unsere kurze Vorstellung von Swoole. Ich hoffe, Concurrency wird ein großes Thema für PHP. Aus meiner Sicht hat Swoole das Potenzial, PHP auf eine neue Ebene zu heben!
Dieser Beitrag ist im englischen Original erschienen auf Andrei Avrams Blog: Concurrency in PHP with Swoole