getLockFilePath(); // 检查执行锁 if ($this->isLocked($lockFile)) { Log::write($this->jobName . '任务正在执行中,跳过'); return $this->getSkippedResult('locked'); } // 检查每日执行标记 if ($this->enableDailyFlag && $this->isExecutedToday()) { Log::write($this->jobName . '今天已经执行过,跳过'); return $this->getSkippedResult('already_executed_today'); } // 创建锁文件 $this->createLock($lockFile); try { Log::write('开始执行' . $this->jobName . '任务'); // 执行具体任务 $result = $this->executeJob(); // 创建每日执行标记 if ($this->enableDailyFlag) { $this->createDailyFlag(); } Log::write($this->jobName . '任务执行完成'); return $result; } catch (\Exception $e) { Log::write($this->jobName . '任务执行失败:' . $e->getMessage()); return $this->getFailedResult($e->getMessage()); } finally { // 删除锁文件 $this->removeLock($lockFile); } } /** * 获取锁文件路径 * @return string */ protected function getLockFilePath() { return runtime_path() . $this->jobName . '.lock'; } /** * 检查是否被锁定 * @param string $lockFile * @return bool */ protected function isLocked($lockFile) { return file_exists($lockFile) && (time() - filemtime($lockFile)) < $this->lockTimeout; } /** * 创建锁文件 * @param string $lockFile */ protected function createLock($lockFile) { file_put_contents($lockFile, time()); } /** * 删除锁文件 * @param string $lockFile */ protected function removeLock($lockFile) { if (file_exists($lockFile)) { unlink($lockFile); } } /** * 检查今天是否已经执行过 * @return bool */ protected function isExecutedToday() { $today = date('Y-m-d'); $flagFile = runtime_path() . $this->jobName . '_' . $today . '.flag'; return file_exists($flagFile); } /** * 创建每日执行标记 */ protected function createDailyFlag() { $today = date('Y-m-d'); $flagFile = runtime_path() . $this->jobName . '_' . $today . '.flag'; file_put_contents($flagFile, time()); } /** * 获取跳过执行的结果 * @param string $reason * @return array */ protected function getSkippedResult($reason) { return [ 'status' => 'skipped', 'reason' => $reason, 'job_name' => $this->jobName, 'timestamp' => time() ]; } /** * 获取执行失败的结果 * @param string $error * @return array */ protected function getFailedResult($error) { return [ 'status' => 'failed', 'error' => $error, 'job_name' => $this->jobName, 'timestamp' => time() ]; } /** * 获取执行成功的结果 * @param array $data * @return array */ protected function getSuccessResult($data = []) { return array_merge([ 'status' => 'success', 'job_name' => $this->jobName, 'timestamp' => time() ], $data); } /** * 清理过期的标记文件(超过7天) */ protected function cleanupOldFlags() { $runtimePath = runtime_path(); $pattern = $runtimePath . $this->jobName . '_*.flag'; $files = glob($pattern); foreach ($files as $file) { if (file_exists($file) && (time() - filemtime($file)) > 7 * 24 * 3600) { // 7天 unlink($file); } } } }