Last active
May 25, 2022 04:32
-
-
Save lotharthesavior/e4f1c177e422373916f05fcd25d8aaa7 to your computer and use it in GitHub Desktop.
PHP OpenSwoole Atomic forcing one worker to wait for another
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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; | |
}); | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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