Path: blob/1.0-develop/app/Services/Schedules/ProcessScheduleService.php
10284 views
<?php12namespace Pterodactyl\Services\Schedules;34use Exception;5use Pterodactyl\Models\Schedule;6use Illuminate\Contracts\Bus\Dispatcher;7use Pterodactyl\Jobs\Schedule\RunTaskJob;8use Illuminate\Database\ConnectionInterface;9use Pterodactyl\Exceptions\DisplayException;10use Pterodactyl\Repositories\Wings\DaemonServerRepository;11use Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException;1213class ProcessScheduleService14{15/**16* ProcessScheduleService constructor.17*/18public function __construct(private ConnectionInterface $connection, private Dispatcher $dispatcher, private DaemonServerRepository $serverRepository)19{20}2122/**23* Process a schedule and push the first task onto the queue worker.24*25* @throws \Throwable26*/27public function handle(Schedule $schedule, bool $now = false): void28{29$task = $schedule->tasks()->orderBy('sequence_id')->first();30if (is_null($task)) {31throw new DisplayException('Cannot process schedule for task execution: no tasks are registered.');32}3334$this->connection->transaction(function () use ($schedule, $task) {35$schedule->forceFill([36'is_processing' => true,37'next_run_at' => $schedule->getNextRunDate(),38])->saveOrFail();3940$task->update(['is_queued' => true]);41});4243$job = new RunTaskJob($task, $now);44if ($schedule->only_when_online) {45// Check that the server is currently in a starting or running state before executing46// this schedule if this option has been set.47try {48$details = $this->serverRepository->setServer($schedule->server)->getDetails();49$state = $details['state'] ?? 'offline';50// If the server is stopping or offline just do nothing with this task.51if (in_array($state, ['offline', 'stopping'])) {52$job->failed();5354return;55}56} catch (\Exception $exception) {57if (!$exception instanceof DaemonConnectionException) {58// If we encountered some exception during this process that wasn't just an59// issue connecting to Wings run the failed sequence for a job. Otherwise we60// can just quietly mark the task as completed without actually running anything.61$job->failed($exception);62}63$job->failed();6465return;66}67}6869if (!$now) {70$this->dispatcher->dispatch($job->delay($task->time_offset));71} else {72// When using dispatchNow the RunTaskJob::failed() function is not called automatically73// so we need to manually trigger it and then continue with the exception throw.74//75// @see https://github.com/pterodactyl/panel/issues/255076try {77$this->dispatcher->dispatchNow($job);78} catch (\Exception $exception) {79$job->failed($exception);8081throw $exception;82}83}84}85}868788