Koroutinen-Warteschlange WaitGroup

WaitGroup ist ein Werkzeug zur Synchronisation von Koroutinen, das ähnlich wie Barrier funktioniert und es ermöglicht, in asynchronen Aufgaben zu warten, bis alle Koroutinen ihre Ausführung abgeschlossen haben, bevor die nachfolgende Logik fortgesetzt wird.

Der Unterschied zu Barrier besteht darin, dass der Entwickler die Zählung selbst erhöhen und verringern kann.

Hinweis
Der zugrunde liegende Typ wird automatisch erkannt und unterstützt nur Swoole/Swow/Fiber-Treiber.

Tipp
Dieses Feature erfordert workerman>=5.1.0.

<?php
use Workerman\Connection\TcpConnection;
use Workerman\Coroutine\Barrier;
use Workerman\Coroutine;
use Workerman\Events\Swoole;
use Workerman\Protocols\Http\Request;
use Workerman\Worker;
require_once __DIR__ . '/vendor/autoload.php';

// Http-Server
$worker = new Worker('http://0.0.0.0:8001');
$worker->eventLoop = Swoole::class; // Oder Swow::class oder Fiber::class
$worker->onMessage = function (TcpConnection $connection, Request $request) {
    $wg = new WaitGroup();
    for ($i=1; $i<5; $i++) {
        $wg->add();
        Coroutine::create(function () use ($wg, $i) {
            try {
            // Etwas tun
            } finally {
                $wg->done();
            }
        });
    }
    // Warten, bis alle Koroutinen fertig sind, Timeout nach 10 Sekunden
    $result = $wg->wait(10.0);
    if (!$result) {
        $connection->send('WaitGroup Timeout');
        return;
    }
    $connection->send('Alle Aufgaben erledigt');
};

Worker::runAll();

Schnittstellenerklärung

interface WaitGroupInterface
{

    /**
     * Zählung erhöhen
     *
     * @param int $delta
     * @return bool
     */
    public function add(int $delta = 1): bool;

    /**
     * Zählung abschließen
     *
     * @return bool
     */
    public function done(): bool;

    /**
     * Zählung zurückgeben
     *
     * @return int
     */
    public function count(): int;

    /**
     * Koroutine warten
     *
     * @param int|float $timeout Sekunden
     * @return bool Timeout:false Erfolg:true
     */
    public function wait(int|float $timeout = -1): bool;
}