channel = new Channel(5000); Coroutine::create([$this, 'execute']); Timer::tick(1000, [$this, 'systemLoop']); } /** * @throws \Exception */ public function execute() { while (true) { /** @var Crontab $list */ $list = $this->channel->pop(-1); $list->execute(); } } /** * @throws ReflectionException * @throws ComponentException * @throws ConfigException * @throws NotFindClassException * @throws Exception * @throws \Exception */ public function systemLoop() { $score = time(); $redis = Snowflake::app()->getRedis(); $lists = $redis->zRangeByScore('system:crontab', '0', (string)$score); $redis->zRemRangeByScore('system:crontab', '0', (string)$score); $barrier = Barrier::make(); foreach ($lists as $list) { $list = unserialize($list); if (!($list instanceof Crontab)) { continue; } $this->channel->push($list); } Barrier::wait($barrier); $redis->release(); } }