From 4fec98f93920adc0d92cce213a47ff0cddb2fadb Mon Sep 17 00:00:00 2001 From: JaguarJack Date: Tue, 7 Jul 2020 16:58:34 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=20crontab=20=E7=BB=84?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- extend/catcher/library/crontab/Cron.php | 115 ++++++++ .../catcher/library/crontab/Frequencies.php | 245 +++++++++++------- .../catcher/library/crontab/ManageProcess.php | 157 +++++++++++ extend/catcher/library/crontab/Process.php | 199 ++++++++++++++ .../library/crontab/RegisterSignal.php | 122 +++++++++ extend/catcher/library/crontab/Schedule.php | 55 ++++ extend/catcher/library/crontab/Store.php | 90 +++++++ 7 files changed, 883 insertions(+), 100 deletions(-) diff --git a/extend/catcher/library/crontab/Cron.php b/extend/catcher/library/crontab/Cron.php index ef90e0a..2613fd4 100644 --- a/extend/catcher/library/crontab/Cron.php +++ b/extend/catcher/library/crontab/Cron.php @@ -8,3 +8,118 @@ // +---------------------------------------------------------------------- // | Author: JaguarJack [ njphper@gmail.com ] // +---------------------------------------------------------------------- +namespace catcher\library\crontab; + +use Cron\CronExpression; +use think\facade\Console; + +/** + * Class Cron + * @package catcher\library\crontab + * + * // cron 表达式 + * * * * * + * - - - - - +* | | | | | +* | | | | | +* | | | | +----- day of week (0 - 6) (Sunday=0) +* | | | +---------- month (1 - 12) +* | | +--------------- day of month (1 - 31) +* | +-------------------- hour (0 - 23) +* +------------------------- min (0 - 59) + * + * + * + */ +class Cron +{ + use Frequencies; + + /** + * crontab 表达式 + * + * @var string + */ + protected $expression = '* * * * *'; + + /** + * task 任务 + * + * @var string + */ + protected $task; + + /** + * console 命令 + * + * @var string + */ + protected $console; + + /** + * console 参数 + * + * @var array + */ + protected $arguments; + + /** + * 秒级支持 + * + * @var int + */ + protected $second; + + public function __construct($name, $arguments = []) + { + if (is_string($name)) { + $this->console = $name; + } + + if (is_object($name)) { + $this->task = $name; + } + + $this->arguments = $arguments; + } + + /** + * 运行 cron 任务 + * + * @time 2020年07月04日 + * @return void + */ + public function run() + { + if ($this->console) { + Console::call($this->console, $this->arguments); + } + + if ($this->task && method_exists($this->task, 'run')) { + $this->task->run(); + } + } + + /** + * 是否可运行 + * + * @time 2020年07月04日 + * @return bool + */ + protected function can() + { + if ($this->second) { + $now = date('s', time()); + + return in_array($now, [--$now, $now, ++$now]); + } + + if ($this->expression) { + $cron = CronExpression::factory($this->expression); + return $cron->isDue('now'); + } + + return false; + } + +} \ No newline at end of file diff --git a/extend/catcher/library/crontab/Frequencies.php b/extend/catcher/library/crontab/Frequencies.php index 3429b10..242dba6 100644 --- a/extend/catcher/library/crontab/Frequencies.php +++ b/extend/catcher/library/crontab/Frequencies.php @@ -10,12 +10,17 @@ // +---------------------------------------------------------------------- namespace catcher\library\crontab; +use think\helper\Str; + /** + * From Laravel + * * Trait ManagesFrequencies * @package catcher\library\crontab */ -trait frequencies +trait Frequencies { + /** * The Cron expression representing the event's frequency. * @@ -30,51 +35,49 @@ trait frequencies } /** - * Schedule the event to run between start and end time. + * 每十秒 * - * @param string $startTime - * @param string $endTime + * @time 2020年07月04日 * @return $this */ - public function between($startTime, $endTime) + public function everyTenSeconds() { - return $this->when($this->inTimeInterval($startTime, $endTime)); + $this->second = 10; + + return $this; } /** - * Schedule the event to not run between start and end time. + * 每二十秒 * - * @param string $startTime - * @param string $endTime + * @time 2020年07月04日 * @return $this */ - public function unlessBetween($startTime, $endTime) + public function everyTwentySeconds() { - return $this->skip($this->inTimeInterval($startTime, $endTime)); + $this->second = 20; + + return $this; } /** - * Schedule the event to run between start and end time. + * 每三十秒 * - * @param string $startTime - * @param string $endTime - * @return \Closure + * @time 2020年07月04日 + * @return $this */ - private function inTimeInterval($startTime, $endTime) + public function everyThirtySeconds() { - return function () use ($startTime, $endTime) { - return Carbon::now($this->timezone)->between( - Carbon::parse($startTime, $this->timezone), - Carbon::parse($endTime, $this->timezone), - true - ); - }; + $this->second = 30; + + return $this; } /** - * Schedule the event to run every minute. + * 每分钟 * - * @return $this + * @time 2020年07月04日 + * @return Frequencies */ public function everyMinute() { @@ -82,9 +85,10 @@ trait frequencies } /** - * Schedule the event to run every five minutes. + * 5 分钟 * - * @return $this + * @time 2020年07月04日 + * @return Frequencies */ public function everyFiveMinutes() { @@ -92,9 +96,10 @@ trait frequencies } /** - * Schedule the event to run every ten minutes. + * 10 分钟 * - * @return $this + * @time 2020年07月04日 + * @return Frequencies */ public function everyTenMinutes() { @@ -102,9 +107,10 @@ trait frequencies } /** - * Schedule the event to run every fifteen minutes. + * 15 分钟 * - * @return $this + * @time 2020年07月04日 + * @return Frequencies */ public function everyFifteenMinutes() { @@ -112,9 +118,10 @@ trait frequencies } /** - * Schedule the event to run every thirty minutes. + * 三十分钟 * - * @return $this + * @time 2020年07月04日 + * @return Frequencies */ public function everyThirtyMinutes() { @@ -122,9 +129,10 @@ trait frequencies } /** - * Schedule the event to run hourly. + * 每小时 * - * @return $this + * @time 2020年07月04日 + * @return Frequencies */ public function hourly() { @@ -132,7 +140,7 @@ trait frequencies } /** - * Schedule the event to run hourly at a given offset in the hour. + * 小时的时间 * * @param array|int $offset * @return $this @@ -144,10 +152,12 @@ trait frequencies return $this->spliceIntoPosition(1, $offset); } + /** - * Schedule the event to run daily. + * 每天 * - * @return $this + * @time 2020年07月04日 + * @return Frequencies */ public function daily() { @@ -156,7 +166,7 @@ trait frequencies } /** - * Schedule the command at a given time. + * 每天固定时间启动 * * @param string $time * @return $this @@ -167,7 +177,7 @@ trait frequencies } /** - * Schedule the event to run daily at a given time (10:00, 19:30, etc). + * 每天固定时间启动 (10:00, 19:30, etc). * * @param string $time * @return $this @@ -181,7 +191,7 @@ trait frequencies } /** - * Schedule the event to run twice daily. + * 每两天一次 * * @param int $first * @param int $second @@ -196,7 +206,7 @@ trait frequencies } /** - * Schedule the event to run only on weekdays. + * 工作日跑 * * @return $this */ @@ -206,9 +216,10 @@ trait frequencies } /** - * Schedule the event to run only on weekends. + * 周末 * - * @return $this + * @time 2020年07月04日 + * @return Frequencies */ public function weekends() { @@ -216,9 +227,10 @@ trait frequencies } /** - * Schedule the event to run only on Mondays. + * 周一 * - * @return $this + * @time 2020年07月04日 + * @return Frequencies */ public function mondays() { @@ -226,7 +238,7 @@ trait frequencies } /** - * Schedule the event to run only on Tuesdays. + * 周二 * * @return $this */ @@ -236,7 +248,7 @@ trait frequencies } /** - * Schedule the event to run only on Wednesdays. + * 周三 * * @return $this */ @@ -246,7 +258,7 @@ trait frequencies } /** - * Schedule the event to run only on Thursdays. + * 周四 * * @return $this */ @@ -256,7 +268,7 @@ trait frequencies } /** - * Schedule the event to run only on Fridays. + * 周五 * * @return $this */ @@ -266,7 +278,7 @@ trait frequencies } /** - * Schedule the event to run only on Saturdays. + * 周六 * * @return $this */ @@ -276,7 +288,7 @@ trait frequencies } /** - * Schedule the event to run only on Sundays. + * 周日 * * @return $this */ @@ -286,9 +298,10 @@ trait frequencies } /** - * Schedule the event to run weekly. + * 每周 * - * @return $this + * @time 2020年07月04日 + * @return Frequencies */ public function weekly() { @@ -298,7 +311,7 @@ trait frequencies } /** - * Schedule the event to run weekly on a given day and time. + * 每周的某个时间 * * @param int $day * @param string $time @@ -312,23 +325,12 @@ trait frequencies } /** - * Schedule the event to run monthly. + * 每月的某天某个时间 * - * @return $this - */ - public function monthly() - { - return $this->spliceIntoPosition(1, 0) - ->spliceIntoPosition(2, 0) - ->spliceIntoPosition(3, 1); - } - - /** - * Schedule the event to run monthly on a given day and time. - * - * @param int $day - * @param string $time - * @return $this + * @time 2020年07月04日 + * @param int $day + * @param string $time + * @return Frequencies */ public function monthlyOn($day = 1, $time = '0:0') { @@ -338,11 +340,12 @@ trait frequencies } /** - * Schedule the event to run twice monthly. + * 每月两次 * - * @param int $first - * @param int $second - * @return $this + * @time 2020年07月04日 + * @param int $first + * @param int $second + * @return Frequencies */ public function twiceMonthly($first = 1, $second = 16) { @@ -354,9 +357,23 @@ trait frequencies } /** - * Schedule the event to run quarterly. + * 每月 * - * @return $this + * @time 2020年07月04日 + * @return Frequencies + */ + public function monthly() + { + return $this->spliceIntoPosition(1, 0) + ->spliceIntoPosition(2, 0) + ->spliceIntoPosition(3, 1); + } + + /** + * 每个季度 + * + * @time 2020年07月04日 + * @return Frequencies */ public function quarterly() { @@ -367,23 +384,11 @@ trait frequencies } /** - * Schedule the event to run yearly. + * 一周中的几天运行 * - * @return $this - */ - public function yearly() - { - return $this->spliceIntoPosition(1, 0) - ->spliceIntoPosition(2, 0) - ->spliceIntoPosition(3, 1) - ->spliceIntoPosition(4, 1); - } - - /** - * Set the days of the week the command should run on. - * - * @param array|mixed $days - * @return $this + * @time 2020年07月04日 + * @param $days + * @return Frequencies */ public function days($days) { @@ -393,16 +398,17 @@ trait frequencies } /** - * Set the timezone the date should be evaluated on. + * 每年 * - * @param \DateTimeZone|string $timezone - * @return $this + * @time 2020年07月04日 + * @return Frequencies */ - public function timezone($timezone) + public function yearly() { - $this->timezone = $timezone; - - return $this; + return $this->spliceIntoPosition(1, 0) + ->spliceIntoPosition(2, 0) + ->spliceIntoPosition(3, 1) + ->spliceIntoPosition(4, 1); } /** @@ -420,4 +426,43 @@ trait frequencies return $this->cron(implode(' ', $segments)); } + + /** + * call + * + * @time 2020年07月04日 + * @param $name + * @param $arguments + * @return $this + */ + public function __call($name, $arguments) + { + if (Str::contains($name, 'every')) { + $num = (int)Str::substr(str_replace('every', '',$name), 0, 2); + if (Str::contains($name, 'second')) { + return $this->spliceIntoPosition(1, $num < 60 ? $num : 1); + } + + if (Str::contains($name, 'minute')) { + return $this->spliceIntoPosition(2, $num < 60 ? $num : 1); + } + + if (Str::contains($name, 'hour')) { + return $this->spliceIntoPosition(3, $num < 24 ? $num : 1); + } + + if (Str::contains($name, 'day')) { + return $this->spliceIntoPosition(4, $num < 31 ? $num : 1); + } + + if (Str::contains($name, 'month')) { + return $this->spliceIntoPosition(5, $num < 12 ? $num : 1); + } + } + + // other to do + + return $this; + } + } \ No newline at end of file diff --git a/extend/catcher/library/crontab/ManageProcess.php b/extend/catcher/library/crontab/ManageProcess.php index ef90e0a..737067c 100644 --- a/extend/catcher/library/crontab/ManageProcess.php +++ b/extend/catcher/library/crontab/ManageProcess.php @@ -8,3 +8,160 @@ // +---------------------------------------------------------------------- // | Author: JaguarJack [ njphper@gmail.com ] // +---------------------------------------------------------------------- +namespace catcher\library\crontab; + +use Swoole\Process; +use catcher\library\crontab\Process as MProcess; + +class ManageProcess +{ + use RegisterSignal, MProcess, Store; + + /** + * 动态扩展的最大 process 数量 + * + * @var int + */ + protected $maxNum = 10; + + /** + * 常驻 process + * + * @var int + */ + protected $staticNum = 2; + + /** + * 存储 process 信息 + * + * @var array + */ + protected $process = []; + + /** + * 主进程ID + * + * @var + */ + protected $master_pid; + + /** + * pid 文件名称 + * + * @var string + */ + protected $mater = 'catch-master'; + + /** + * process status 存储文件 + * + * @var string + */ + protected $processStatus = 'process-status'; + + // 版本 + const VERSION = '1.0.0'; + + // process 等待状态 + const WAITING = 'waiting'; + // process 繁忙状态 + const BUSYING = 'busying'; + + /** + * 启动进程 + * + * @time 2020年07月07日 + * @return void + */ + public function start() + { + // 守护进程 + // Process::daemon(true, false); + // alarm 信号 + Process::alarm(1000 * 1000); + // 1s 调度一次 + swoole_timer_tick(1000, $this->schedule());//不会继承 + // 注册信号 + $this->registerSignal(); + // 存储 pid + $this->storeMasterPid(getmypid()); + // pid + $this->master_pid = getmypid(); + // 初始化进程 + $this->initProcesses(); + } + + /** + * 调度 + * + * @time 2020年07月07日 + * @return \Closure + */ + protected function schedule() + { + return function () { + $schedule = new Schedule(); + $schedule->command('route:list')->everyFiveMinutes(); + + foreach ($schedule->getCronTask() as $cron) { + if ($cron->can()) { + list($waiting, $process) = $this->hasWaitingProcess(); + if ($waiting) { + // 向 process 投递 cron + } else { + // 创建临时 process 处理,处理完自动销毁 + $this->createProcess($cron); + } + } + } + }; + } + + /** + * Create Task + * + * @time 2019年08月06日 + * @param Cron $cron + * @return void + */ + protected function createProcess(Cron $cron) + { + $process = new Process(function (Process $process) use($cron) { + $cron->run(); + $process->exit(); + }); + + $process->name(sprintf('worker: ')); + + $process->start(); + } + + /** + * 创建静态 worker 进程 + * + * @time 2020年07月05日 + * @return Process + */ + protected function createStaticProcess() + { + return new Process($this->createProcessCallback()); + } + + /** + * 初始化 workers + * + * @time 2020年07月03日 + * @return void + */ + protected function initProcesses() + { + for ($i = 0; $i < $this->staticNum; $i++) { + + $process = $this->createStaticProcess(); + // $worker->name("[$i+1]catch-worker"); + $process->start(); + + $this->process[$process->pid] = $this->processInfo($process); + } + } +} \ No newline at end of file diff --git a/extend/catcher/library/crontab/Process.php b/extend/catcher/library/crontab/Process.php index ef90e0a..9612674 100644 --- a/extend/catcher/library/crontab/Process.php +++ b/extend/catcher/library/crontab/Process.php @@ -8,3 +8,202 @@ // +---------------------------------------------------------------------- // | Author: JaguarJack [ njphper@gmail.com ] // +---------------------------------------------------------------------- +namespace catcher\library\crontab; + +use catcher\CatchAdmin; +use think\console\Table; + +trait Process +{ + protected function createProcessCallback() + { + return function (\Swoole\Process $process) { + $quit = false; + // 必须使用 pcntl signal 注册捕获 + // Swoole\Process::signal ignalfd 和 EventLoop 是异步 IO,不能用于阻塞的程序中,会导致注册的监听回调函数得不到调度 + // 同步阻塞的程序可以使用 pcntl 扩展提供的 pcntl_signal + // 安全退出进程 + pcntl_signal(SIGTERM, function() use (&$quit){ + $quit = true; + }); + + while (true) { + //$data = $worker->pop(); + $this->beforeTask($process->pid); + $this->afterTask($process->pid); + + var_dump($this->process); + var_dump(isset($this->process[$process->pid]), $process->pid); + // 处理任务前 + // 处理任务中 + // 处理任务后 + //var_dump(unserialize($data)); + // echo "来自主进程的消息:". $worker->pop().',来自管道'.$worker->pipe.',当前的进程id为'.$worker->pid.PHP_EOL; + // $worker->push('hello 主进程'); //不要当做管道使用 + + // 睡眠一秒 让出 CPU 调度 + + // var_dump(123); + + pcntl_signal_dispatch(); + sleep(5); + + // 如果收到安全退出的信号,需要在最后任务处理完成之后退出 + if ($quit) { + var_dump(1000); + $process->exit(0); + } + } + }; + } + + /** + * 进程信息 + * + * @time 2020年07月05日 + * @param $process + * @return array + */ + protected function processInfo($process) + { + return [ + 'name' => $process, + 'pid' => $process->pid, + 'status' => self::WAITING, + 'start_at' => time(), + 'deal_num' => 0, + 'error' => 0, + ]; + } + + /** + * 是否有等待的 Process + * + * @time 2020年07月07日 + * @return array + */ + protected function hasWaitingProcess() + { + $waiting = [false, null]; + + foreach ($this->process as $process) { + if ($process['status'] == self::WAITING) { + $waiting = [true, $process]; + break; + } + } + + return $waiting; + } + + /** + * 处理任务前 + * + * @time 2020年07月07日 + * @param $pid + * @return void + */ + protected function beforeTask($pid) + { + if (isset($this->process[$pid])) { + $this->process[$pid]['status'] = self::BUSYING; + } + } + + /** + * 处理任务后 + * + * @time 2020年07月07日 + * @param $pid + * @return void + */ + protected function afterTask($pid) + { + if (isset($this->process[$pid])) { + $this->process[$pid]['status'] = self::WAITING; + $this->process[$pid]['deal_num'] += 1; + var_dump($this->process); + } + } + + /** + * 退出服务 + * + * @time 2020年07月07日 + * @return void + */ + public function stop() + { + \Swoole\Process::kill($this->getMasterPid(), SIGTERM); + } + + /** + * 状态输出 + * + * @time 2020年07月07日 + * @return void + */ + public function status() + { + \Swoole\Process::kill($this->getMasterPid(), SIGUSR1); + } + + /** + * 子进程重启 + * + * @time 2020年07月07日 + * @return void + */ + public function reload() + { + \Swoole\Process::kill($this->getMasterPid(), SIGUSR2); + } + + /** + * 输出 process 信息 + * + * @time 2020年07月05日 + * @return string + */ + public function getWorkerStatus() + { + $scheduleV = self::VERSION; + $adminV = CatchAdmin::VERSION; + $phpV = PHP_VERSION; + + $info = <<setHeader([ + 'Pid', 'StartAt', 'Status', 'DealTaskNumber', 'Errors' + ], 3); + + $processes = []; + + foreach ($this->process as $process) { + $processes[] = [ + 'pid' => $process['pid'], + 'start_at' => date('Y-m-d H:i', $process['start_at']), + 'status' => $process['status'], + 'deal_num' => $process['deal_num'], + 'error' => $process['error'], + ]; + } + + $table->setRows($processes, 3); + + $table->render(); + + return $info . PHP_EOL . $table->render(); + } +} \ No newline at end of file diff --git a/extend/catcher/library/crontab/RegisterSignal.php b/extend/catcher/library/crontab/RegisterSignal.php index ef90e0a..819321c 100644 --- a/extend/catcher/library/crontab/RegisterSignal.php +++ b/extend/catcher/library/crontab/RegisterSignal.php @@ -8,3 +8,125 @@ // +---------------------------------------------------------------------- // | Author: JaguarJack [ njphper@gmail.com ] // +---------------------------------------------------------------------- +namespace catcher\library\crontab; + +use Swoole\Process; + +trait RegisterSignal +{ + /** + * Register 信号 + * + * @time 2019年08月06日 + */ + protected function registerSignal() + { + // Process::signal(SIGALRM, $this->restartProcess()); + + Process::signal(SIGCHLD, $this->waitingForWorkerExit()); + + Process::signal(SIGTERM, $this->smoothExit()); + + Process::signal(SIGUSR2, $this->smoothReloadWorkers()); + + Process::signal(SIGUSR1, $this->workerStatus()); + + Process::signal(SIGPIPE, $this->catchPipeError()); + } + + /** + * 重新拉起子进程 + * + * @time 2019年08月06日 + * @return \Closure + */ + protected function restartProcess() + { + return function () { + // var_dump('alarm here'); + /**$count = count($this->process); + if ($count < $this->staticNum) { + $process = $this->createStaticProcess(); + $this->workerInfo($process); + }*/ + }; + } + + /** + * 等待子进程退出 防止僵尸 + * + * @time 2019年08月06日 + * @return \Closure + */ + protected function waitingForWorkerExit() + { + return function () { + while ($res = Process::wait(false)) { + if (isset($this->process[$res['pid']])) { + unset($this->process[$res['pid']]); + } + } + }; + } + + /** + * 注册 SIGTERM + * + * @time 2019年08月06日 + * @return \Closure + */ + protected function smoothExit() + { + return function () { + // 发送停止信号给子进程 等待结束后自动退出 + foreach ($this->process as $process) { + Process::kill($process['pid'], SIGTERM); + } + + Process::kill($this->master_pid, SIGKILL); + }; + } + + /** + * 输出 worker 的状态 + * + * @time 2020年07月06日 + * @return \Closure + */ + protected function workerStatus() + { + return function () { + $this->storeStatus(); + }; + } + + /** + * 平滑重启子进程 + * + * @time 2020年07月06日 + * @return \Closure + */ + protected function smoothReloadWorkers() + { + return function () { + foreach ($this->process as $process) { + var_dump($process['pid']); + Process::kill((int)$process['pid'], SIGTERM); + } + }; + } + + + /** + * 管道破裂信号 + * + * @time 2020年07月06日 + * @return \Closure + */ + public function catchPipeError() + { + return function () { + // todo + }; + } +} \ No newline at end of file diff --git a/extend/catcher/library/crontab/Schedule.php b/extend/catcher/library/crontab/Schedule.php index ef90e0a..4c11795 100644 --- a/extend/catcher/library/crontab/Schedule.php +++ b/extend/catcher/library/crontab/Schedule.php @@ -8,3 +8,58 @@ // +---------------------------------------------------------------------- // | Author: JaguarJack [ njphper@gmail.com ] // +---------------------------------------------------------------------- +namespace catcher\library\crontab; + +use catcher\exceptions\FailedException; + +class Schedule +{ + + protected $crons = []; + + /** + * 新增 command 任务 + * + * @time 2020年07月04日 + * @param $command + * @param array $arguments + * @return Cron + */ + public function command($command, $arguments = []): Cron + { + $this->crons[] = $cron = new Cron($command); + + return $cron; + } + + /** + * 新增 task 任务 + * + * @time 2020年07月04日 + * @param $task + * @param array $argument + * @return Cron + */ + public function task($task, $argument = []): Cron + { + if (is_string($task)) { + if (!class_exists($task)) { + throw new FailedException("[$task] not found"); + } + + $task = new $task(...$argument); + } + + $this->crons[] = $cron = new Cron($task); + + return $cron; + } + + + public function getCronTask() + { + return $this->crons; + } +} + + diff --git a/extend/catcher/library/crontab/Store.php b/extend/catcher/library/crontab/Store.php index ef90e0a..3faedf3 100644 --- a/extend/catcher/library/crontab/Store.php +++ b/extend/catcher/library/crontab/Store.php @@ -8,3 +8,93 @@ // +---------------------------------------------------------------------- // | Author: JaguarJack [ njphper@gmail.com ] // +---------------------------------------------------------------------- +namespace catcher\library\crontab; + +trait Store +{ + /** + * 存储 pid + * + * @time 2020年07月05日 + * @param $pid + * @return false|int + */ + public function storeMasterPid($pid) + { + $path = $this->getMasterPidPath(); + + return file_put_contents($path, $pid); + } + + /** + * 存储信息 + * + * @time 2020年07月07日 + * @return false|int + */ + public function storeStatus() + { + return file_put_contents($this->getWorkerStatusPath(), $this->getWorkerStatus()); + } + + /** + * 输出 + * + * @time 2020年07月07日 + * @return false|string + */ + public function output() + { + // 等待信号输出 + sleep(1); + + return file_exists($this->getWorkerStatusPath()) ? file_get_contents($this->getWorkerStatusPath()) : ''; + } + + /** + * 获取 pid + * + * @time 2020年07月05日 + * @return int + */ + public function getMasterPid() + { + $pid = file_get_contents($this->getMasterPidPath()); + + return intval($pid); + } + + /** + * 获取配置地址 + * + * @time 2020年07月05日 + * @return string + */ + protected function getMasterPidPath() + { + $path = runtime_path('schedule' . DIRECTORY_SEPARATOR); + + if (!is_dir($path)) { + mkdir($path, 0777, true); + } + + return $path . 'master.pid'; + } + + /** + * 获取 worker 状态存储地址 + * + * @time 2020年07月07日 + * @return string + */ + protected function getWorkerStatusPath() + { + $path = runtime_path('schedule' . DIRECTORY_SEPARATOR); + + if (!is_dir($path)) { + mkdir($path, 0777, true); + } + + return $path . 'worker-status.txt'; + } +} \ No newline at end of file