getRedis(); $range = $redis->zRangeByScore(ACrontab::CRONTAB_KEY, '0', (string)$startTime); $redis->zRemRangeByScore(ACrontab::CRONTAB_KEY, '0', (string)$startTime); foreach ($range as $value) { $crontab = $redis->get('crontab:' . md5($value)); if (empty($crontab) || !($crontab = unserialize($crontab))) { continue; } Coroutine::create(function (Crontab $value, int $startTime) { $this->dispatch($value); }, $crontab, $startTime); } $redis->release(); }); } /** * @param Crontab $value * @param int $startTime * @throws \Exception */ private function dispatch(Crontab $value) { try { $value->increment()->execute(); if ($value->getExecuteNumber() < $value->getMaxExecuteNumber()) { $this->addTask($value); } else if ($value->isLoop()) { $this->addTask($value); } } catch (\Throwable $exception) { $this->application->error($exception->getMessage()); } finally { fire(Event::SYSTEM_RESOURCE_RELEASES); } } /** * @param string $name */ public function clear(string $name) { if (!isset($this->names[$name])) { return; } $timers = $this->timers[$name]; $search = array_search($name, $this->scores[$timers]); if ($search !== false) { unset($this->scores[$timers][$search]); } unset($this->timers[$name], $this->names[$name]); } /** * @param Crontab $content * @param $ticker */ private function addTask(Crontab $crontab) { $redis = Snowflake::app()->getRedis(); $name = md5($crontab->getName()); $redis->set('crontab:' . $name, serialize($crontab)); $tickTime = time() + $crontab->getTickTime(); $redis->zAdd(ACrontab::CRONTAB_KEY, $tickTime, $crontab->getName()); } }