From d10a7c2d39ea209bf660fe22fbd864c10a407eae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mr=C2=B7x?= Date: Fri, 19 Mar 2021 18:52:30 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=B9=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- System/Crontab.php | 54 +++++++++++++++++++++++++++++-- System/Process/CrontabProcess.php | 15 +++------ 2 files changed, 56 insertions(+), 13 deletions(-) diff --git a/System/Crontab.php b/System/Crontab.php index dfe015ed..8c79c240 100644 --- a/System/Crontab.php +++ b/System/Crontab.php @@ -16,14 +16,33 @@ class Crontab extends Component { + public array|Closure $handler; + + + public mixed $params; + + + public int $tickTime = 1; + + + public bool $isLoop = false; + + + public int $max_execute_number = -1; + + + public int $execute_number = 0; + + /** * @param array|Closure $handler * @param mixed $params * @param int $tickTime * @param bool $isLoop + * @param int $max_execute_number * @throws Exception */ - public function dispatch(array|Closure $handler, mixed $params = null, $tickTime = 1, $isLoop = false) + public function dispatch(array|Closure $handler, mixed $params = null, $tickTime = 1, bool $isLoop = false, $max_execute_number = -1) { $redis = Snowflake::app()->getRedis(); @@ -33,9 +52,40 @@ class Crontab extends Component $executeTime = time() + $tickTime; - $crontab = ['isLoop' => $isLoop, 'handler' => $handler, 'tick' => $tickTime, 'params' => $params]; + $crontab = new Crontab(); + $crontab->max_execute_number = $max_execute_number; + $crontab->handler = $handler; + $crontab->params = $params; + $crontab->tickTime = $tickTime; + $crontab->isLoop = $isLoop; $redis->zAdd('system:crontab', (string)$executeTime, serialize($crontab)); } + + /** + * @throws Exception + */ + public function execute(): void + { + $redis = Snowflake::app()->getRedis(); + try { + $this->execute_number += 1; + call_user_func($this->handler, $list['params'] ?? null); + if ($this->isLoop === false) { + return; + } + if ($this->max_execute_number === -1) { + $redis->zAdd('system:crontab', time() + $this->tickTime, serialize($this)); + } else if ($this->execute_number < $this->max_execute_number) { + $redis->zAdd('system:crontab', time() + $this->tickTime, serialize($this)); + } + } catch (\Throwable $throwable) { + $this->addError($throwable->getMessage()); + } finally { + $redis->release(); + } + } + + } diff --git a/System/Process/CrontabProcess.php b/System/Process/CrontabProcess.php index 26ff209d..d4e17de7 100644 --- a/System/Process/CrontabProcess.php +++ b/System/Process/CrontabProcess.php @@ -5,6 +5,7 @@ namespace Snowflake\Process; use ReflectionException; +use Snowflake\Crontab; use Snowflake\Exception\ComponentException; use Snowflake\Exception\ConfigException; use Snowflake\Exception\NotFindClassException; @@ -44,18 +45,10 @@ class CrontabProcess extends Process */ public function execute() { - $redis = Snowflake::app()->getRedis(); while (true) { + /** @var Crontab $list */ $list = $this->channel->pop(-1); - if (isset($list['isLoop']) && isset($list['tick']) && $list['isLoop'] == 1) { - $redis->zAdd('system:crontab', time() + $list['tick'], serialize($list)); - } - try { - call_user_func($list['handler'], $list['params'] ?? null); - } catch (\Throwable $throwable) { - $this->application->addError($throwable->getMessage()); - } - $redis->release(); + $list->execute(); } } @@ -79,7 +72,7 @@ class CrontabProcess extends Process $barrier = Barrier::make(); foreach ($lists as $list) { $list = unserialize($list); - if (!isset($list['handler']) || !is_callable($list['handler'], true)) { + if (!($list instanceof Crontab)) { continue; } $this->channel->push($list);