Skip to content

Instantly share code, notes, and snippets.

@lotharthesavior
Last active May 25, 2022 04:32
Show Gist options
  • Save lotharthesavior/e4f1c177e422373916f05fcd25d8aaa7 to your computer and use it in GitHub Desktop.
Save lotharthesavior/e4f1c177e422373916f05fcd25d8aaa7 to your computer and use it in GitHub Desktop.
PHP OpenSwoole Atomic forcing one worker to wait for another
<?php
Co\run(function() {
go(function() {
echo "==========================================" . PHP_EOL;
echo file_get_contents('http://localhost:8282/requestA') . PHP_EOL;
echo "==========================================" . PHP_EOL;
});
go(function() {
sleep(1);
echo "==========================================" . PHP_EOL;
echo file_get_contents('http://localhost:8282/requestB') . PHP_EOL;
echo "==========================================" . PHP_EOL;
});
});
<?php
$counter = new Swoole\Atomic;
$lock = new Swoole\Atomic;
$server = new Swoole\Http\Server('0.0.0.0', 8282);
$server->on('request', function(\Swoole\Http\Request $request, \Swoole\Http\Response $response) use ($server, &$lock, &$counter) {
$worker_info = "(worker: " . $server->worker_id . ")";
switch ($request->server['request_uri']) {
case '/requestA':
// interrupt if there is a request A already waiting for a request B
if ($counter->get() === 1) {
// cancel request A
$lock->wakeup();
$counter->set(0);
echo $worker_info . " Interrupted!" . PHP_EOL;
$output = 'interrupted!';
// proceed if there is no request A already waiting
} else {
// start to wait for request B
$output = 'request-a';
$counter->set(1);
$lock->wait(60);
echo $worker_info . " waited..." . PHP_EOL;
}
break;
case '/requestB':
// avoid continuing without waiting A request
if ($counter->get() === 0) {
$output = 'Waiting for Request A.' . PHP_EOL;
break;
}
$output = 'request-b';
echo $worker_info . " waking..." . PHP_EOL;
$lock->wakeup();
$counter->set(0);
echo $worker_info . " woke..." . PHP_EOL;
break;
default:
$output = <<<HTML
<div><a target="_blank" href="/requestA">Request A</a></div>
<div><a target="_blank" href="/requestB">Request B</a></div>
HTML;
break;
}
$response->end($output);
});
$server->start();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment