public function run()
{
if ($this->is_running) {
return;
}
Logger::debug("[MQ Pump] begin");
$this->is_running = true;
while (count($this->next_action) || count($this->next_idle)) {
//没有活动事件,执行idle事件
if (count($this->next_action) === 0) {
$queue_id = array_pop($this->next_idle);
if (!isset($this->idle_queues[$queue_id])) {
// 队列可能被关闭
continue;
}
$idle = array_pop($this->idle_queues[$queue_id]);
Verify::isTrue($idle !== null, 'never been here!!');
if ($idle[2] !== null) {
try {
call_user_func_array($idle[0], $idle[1]);
} catch (\Exception $e) {
$idle[2]($e);
}
} else {
call_user_func_array($idle[0], $idle[1]);
}
continue;
}
$queue_id = array_pop($this->next_action);
if (!isset($this->action_queues[$queue_id])) {
// 队列可能被关闭
continue;
}
$actions =& $this->action_queues[$queue_id];
$left = count($actions);
$action = array_pop($actions);
if ($action !== null) {
$this->callAction($queue_id, $action);
} elseif ($left !== 0) {
//null插入队列,表示执行队列结束, 可以安全关闭队列了
$onend = $this->end_handles[$queue_id];
unset($this->action_queues[$queue_id]);
unset($this->idle_queues[$queue_id]);
unset($this->end_handles[$queue_id]);
Logger::debug("[MQ {$queue_id}] closed");
if ($onend !== null) {
$onend();
}
}
}
//不是在单个队列为空时将其关闭,因为对于存在子流程的时候,其消息队列可能为空,但
//其他流程执行可能导致子流程产生活动消息,所以不能在队列为空时就关闭队列
foreach ($this->end_handles as $onend) {
if ($onend !== null) {
$onend();
}
}
$this->next_action = array();
$this->next_idle = array();
$this->action_queues = array();
$this->idle_queues = array();
$this->end_handles = array();
$this->is_running = false;
Logger::debug("[MQ Pump] end");
}