_stop = true; } /** * @return $this */ public function increment(): static { $this->execute_number += 1; return $this; } /** * @return array|Closure */ public function getHandler(): array|Closure { return $this->handler; } /** * @return string */ #[Pure] public function getName(): string { return md5($this->name); } /** * @return mixed */ public function getParams(): mixed { return $this->params; } /** * @return int */ public function getTickTime(): int { return $this->tickTime; } /** * @return bool */ public function isLoop(): bool { return $this->isLoop; } /** * @return int */ public function getMaxExecuteNumber(): int { return $this->max_execute_number; } /** * @return int */ public function getExecuteNumber(): int { return $this->execute_number; } /** * @param array|Closure $handler */ public function setHandler(array|Closure $handler): void { if ($handler instanceof Closure) { Closure::bind($handler, $this, $this); } $this->handler = $handler; } /** * @param string $name */ public function setName(string $name): void { $this->name = $name; } /** * @param mixed $params */ public function setParams(...$params): void { $this->params = $params; } /** * @param int $tickTime */ public function setTickTime(int $tickTime): void { $this->tickTime = $tickTime; } /** * @param bool $isLoop */ public function setIsLoop(bool $isLoop): void { $this->isLoop = $isLoop; } /** * @param int $max_execute_number */ public function setMaxExecuteNumber(int $max_execute_number): void { $this->max_execute_number = $max_execute_number; } /** * @param int $execute_number */ public function setExecuteNumber(int $execute_number): void { $this->execute_number = $execute_number; } /** * @return int */ public function getTimerId(): int { return $this->timerId; } /** * @param int $timerId */ public function setTimerId(int $timerId): void { $this->timerId = $timerId; } /** * * @throws Exception */ public function clearTimer() { $this->warning('crontab timer clear.'); if (Timer::exists($this->timerId)) { Timer::clear($this->timerId); } } /** * @throws Exception */ private function recover() { $redis = Snowflake::app()->getRedis(); $redis->set('crontab:' . ($name = $this->getName()), swoole_serialize($this)); $tickTime = time() + $this->getTickTime(); $redis->zAdd(Producer::CRONTAB_KEY, $tickTime, $name); } /** * @param Closure|array $closure */ public function setMaxExecute(Closure|array $closure) { $this->_max_execute_handler = $closure; } /** * @throws Exception */ public function execute(): void { try { $redis = Snowflake::app()->getRedis(); $name_md5 = $this->getName(); $redis->hSet(self::WAIT_END, $name_md5, serialize($this)); array_push($this->params, $this->name); $params = call_user_func($this->handler, ...$this->params); $redis->hDel(self::WAIT_END, $name_md5); if ($params === null) { return; } $name = date('Y_m_d_H_i_s.' . $this->name . '.log'); write(storage($name, '/log/crontab'), serialize($params)); } catch (\Throwable $throwable) { logger()->addError($throwable, 'throwable'); } finally { $this->after(); } } /** * @throws Exception */ private function after(): void { if ($this->_stop === true) { return; } if ($this->isLoop()) { $this->recover(); return; } if ($this->max_execute_number == -1) { return; } if ($this->getExecuteNumber() < $this->getMaxExecuteNumber()) { $this->recover(); } else { call_user_func($this->_max_execute_handler, ...$this->params); } } }