2020-11-03 21:02:24 +08:00
|
|
|
<?php
|
|
|
|
|
|
2022-03-15 18:05:33 +08:00
|
|
|
declare(strict_types=1);
|
2020-11-03 21:02:24 +08:00
|
|
|
|
|
|
|
|
namespace ZM\Utils;
|
|
|
|
|
|
2022-03-15 18:05:33 +08:00
|
|
|
use Exception;
|
2021-06-16 00:17:30 +08:00
|
|
|
use Swoole\Coroutine;
|
2022-05-14 23:51:17 +08:00
|
|
|
use Swoole\Timer;
|
2020-11-03 21:02:24 +08:00
|
|
|
use ZM\Store\LightCacheInside;
|
|
|
|
|
use ZM\Store\Lock\SpinLock;
|
|
|
|
|
use ZM\Store\ZMAtomic;
|
2022-03-15 18:05:33 +08:00
|
|
|
use ZM\Utils\Manager\WorkerManager;
|
2020-11-03 21:02:24 +08:00
|
|
|
|
|
|
|
|
class CoMessage
|
|
|
|
|
{
|
|
|
|
|
/**
|
2021-01-29 23:34:34 +08:00
|
|
|
* @return mixed
|
2020-11-03 21:02:24 +08:00
|
|
|
*/
|
2022-04-02 19:20:47 +08:00
|
|
|
public static function yieldByWS(array $hang, array $compare, int $timeout = 600)
|
2022-03-15 18:05:33 +08:00
|
|
|
{
|
2021-06-16 00:17:30 +08:00
|
|
|
$cid = Coroutine::getuid();
|
2022-05-14 23:51:17 +08:00
|
|
|
$api_id = ZMAtomic::get('wait_msg_id')->add();
|
2022-03-15 18:05:33 +08:00
|
|
|
$hang['compare'] = $compare;
|
|
|
|
|
$hang['coroutine'] = $cid;
|
|
|
|
|
$hang['worker_id'] = server()->worker_id;
|
|
|
|
|
$hang['result'] = null;
|
|
|
|
|
SpinLock::lock('wait_api');
|
|
|
|
|
$wait = LightCacheInside::get('wait_api', 'wait_api');
|
2020-11-03 21:02:24 +08:00
|
|
|
$wait[$api_id] = $hang;
|
2022-03-15 18:05:33 +08:00
|
|
|
LightCacheInside::set('wait_api', 'wait_api', $wait);
|
|
|
|
|
SpinLock::unlock('wait_api');
|
2020-11-03 21:02:24 +08:00
|
|
|
$id = swoole_timer_after($timeout * 1000, function () use ($api_id) {
|
2022-03-15 18:05:33 +08:00
|
|
|
$r = LightCacheInside::get('wait_api', 'wait_api')[$api_id] ?? null;
|
2020-11-03 21:02:24 +08:00
|
|
|
if (is_array($r)) {
|
2022-03-15 18:05:33 +08:00
|
|
|
Coroutine::resume($r['coroutine']);
|
2020-11-03 21:02:24 +08:00
|
|
|
}
|
|
|
|
|
});
|
2021-06-16 00:17:30 +08:00
|
|
|
Coroutine::suspend();
|
2022-03-15 18:05:33 +08:00
|
|
|
SpinLock::lock('wait_api');
|
|
|
|
|
$sess = LightCacheInside::get('wait_api', 'wait_api');
|
|
|
|
|
$result = $sess[$api_id]['result'] ?? null;
|
2020-11-03 21:02:24 +08:00
|
|
|
unset($sess[$api_id]);
|
2022-03-15 18:05:33 +08:00
|
|
|
LightCacheInside::set('wait_api', 'wait_api', $sess);
|
|
|
|
|
SpinLock::unlock('wait_api');
|
2022-05-14 23:51:17 +08:00
|
|
|
Timer::clear($id);
|
2022-03-15 18:05:33 +08:00
|
|
|
if ($result === null) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2020-11-03 21:02:24 +08:00
|
|
|
return $result;
|
|
|
|
|
}
|
2021-01-29 22:27:10 +08:00
|
|
|
|
2022-03-15 18:05:33 +08:00
|
|
|
/**
|
|
|
|
|
* @throws Exception
|
|
|
|
|
*/
|
|
|
|
|
public static function resumeByWS(): bool
|
|
|
|
|
{
|
2021-01-29 22:27:10 +08:00
|
|
|
$dat = ctx()->getData();
|
|
|
|
|
$last = null;
|
2022-03-15 18:05:33 +08:00
|
|
|
SpinLock::lock('wait_api');
|
|
|
|
|
$all = LightCacheInside::get('wait_api', 'wait_api') ?? [];
|
2021-01-29 22:27:10 +08:00
|
|
|
foreach ($all as $k => $v) {
|
2022-03-15 18:05:33 +08:00
|
|
|
if (!isset($v['compare'])) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
foreach ($v['compare'] as $vs) {
|
|
|
|
|
if (!isset($v[$vs], $dat[$vs])) {
|
|
|
|
|
continue 2;
|
|
|
|
|
}
|
2021-01-29 23:34:34 +08:00
|
|
|
if ($v[$vs] != $dat[$vs]) {
|
2021-01-29 22:27:10 +08:00
|
|
|
continue 2;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
$last = $k;
|
|
|
|
|
}
|
2021-02-09 17:09:09 +08:00
|
|
|
if ($last !== null) {
|
2022-03-15 18:05:33 +08:00
|
|
|
$all[$last]['result'] = $dat;
|
|
|
|
|
LightCacheInside::set('wait_api', 'wait_api', $all);
|
|
|
|
|
SpinLock::unlock('wait_api');
|
|
|
|
|
if ($all[$last]['worker_id'] != server()->worker_id) {
|
|
|
|
|
WorkerManager::sendActionToWorker($all[$last]['worker_id'], 'resume_ws_message', $all[$last]);
|
2021-01-29 22:27:10 +08:00
|
|
|
} else {
|
2022-03-15 18:05:33 +08:00
|
|
|
Coroutine::resume($all[$last]['coroutine']);
|
2021-01-29 22:27:10 +08:00
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2022-03-15 18:05:33 +08:00
|
|
|
SpinLock::unlock('wait_api');
|
|
|
|
|
return false;
|
2021-01-29 22:27:10 +08:00
|
|
|
}
|
2020-11-03 21:02:24 +08:00
|
|
|
}
|