@extends('layouts.admin') @section('style') @parent @include('admin.system._style') @endsection @section('content') @php $statusLook = [ \romanzipp\QueueMonitor\Enums\MonitorStatus::RUNNING => ['Running', 'is-live'], \romanzipp\QueueMonitor\Enums\MonitorStatus::SUCCEEDED => ['Done', 'is-good'], \romanzipp\QueueMonitor\Enums\MonitorStatus::FAILED => ['Failed', 'is-bad'], \romanzipp\QueueMonitor\Enums\MonitorStatus::STALE => ['Stale', 'is-warn'], \romanzipp\QueueMonitor\Enums\MonitorStatus::QUEUED => ['Waiting', 'is-quiet'], ]; $tabLabels = ['failed' => 'Failed', 'running' => 'Running', 'waiting' => 'Waiting', 'done' => 'Done', 'stale' => 'Stale']; $tabStatuses = \App\Http\Controllers\Admin\SystemController::STATUS_TABS; $age = fn ($seconds) => \Carbon\CarbonInterval::seconds(max(1, (int) $seconds))->cascade()->forHumans(['short' => true, 'parts' => 2]); $took = function ($s) { if ($s < 1) return round($s * 1000) . ' ms'; if ($s < 60) return number_format($s, 1) . ' s'; return \Carbon\CarbonInterval::seconds((int) $s)->cascade()->forHumans(['short' => true, 'parts' => 2]); }; $tabUrl = fn ($key) => route('admin.system.queue', array_merge( ['channel' => $channel], array_filter(['queue' => $filters['queue'] ?? null, 'job' => $filters['job'] ?? null]), $key ? ['status' => $key] : [] ), false); $active = $filters['status'] ?? null; $stuck = $backlog ? $backlog->where('due', '>', 0)->where('waited', '>=', $stuckAfter)->sortByDesc('waited')->first() : null; $waiting = $backlog ? $backlog->sum('due') : 0; $running = $backlog ? $backlog->sum('running') : 0; @endphp

Queue monitor

Background jobs for every channel: blasts, template syncs and integrations.
@csrf
@if(session('system_status'))
{{ session('system_status') }}
@endif @if(session('system_error')) @endif
@if($backlog !== null) @if($stuck)

{{ number_format($stuck->due) }} {{ \Illuminate\Support\Str::plural('job', $stuck->due) }} on “{{ $stuck->queue }}” {{ $stuck->due === 1 ? 'has' : 'have' }} waited {{ \Carbon\CarbonInterval::seconds($stuck->waited)->cascade()->forHumans(['parts' => 1]) }}.

Nothing is picking them up. Check that the queue worker is running.
@elseif($waiting + $running > 0)

Jobs are moving.

{{ number_format($waiting) }} waiting and {{ number_format($running) }} running right now.
@else

Nothing waiting.

Every job that was due has been picked up.
@endif @if($backlog->isNotEmpty())
QueueWaitingRunningScheduledOldest waiting
@foreach($backlog as $lane)
{{ $lane->queue }} {{ number_format($lane->due) }} {{ number_format($lane->running) }} {{ number_format($lane->scheduled) }} {{ $lane->due ? $age($lane->waited) : 'None' }}
@endforeach
@endif @endif
Last 14 days {{ number_format($stats->ran ?? 0) }} jobs finished {{ number_format($stats->failed ?? 0) }} failed @if($stats && $stats->avg_seconds !== null) {{ $took((float) $stats->avg_seconds) }} average run time @endif
@if($jobs->isEmpty())
@if($active || ($filters['queue'] ?? null) || ($filters['job'] ?? null))
No jobs match these filters
@else
No jobs recorded yet
Jobs show up here as soon as one is queued or starts running.
@endif
@else
JobQueueStatusStartedTook
@foreach($jobs as $job) @php [$statusLabel, $statusClass] = $statusLook[(int) $job->status] ?? ['Unknown', 'is-quiet']; $failed = (int) $job->status === \romanzipp\QueueMonitor\Enums\MonitorStatus::FAILED; $when = $job->started_at ?? $job->queued_at; $namespace = \Illuminate\Support\Str::beforeLast($job->name, '\\'); $meta = collect([ $namespace !== $job->name ? $namespace : null, $job->attempt > 1 ? "attempt {$job->attempt}" : null, ])->filter()->implode(', '); @endphp
{{ $job->getBasename() }}
{{ $meta }}
{{ $job->queue }} {{ $statusLabel }} {{-- Waiting rows say "Queued …" in the value itself, so no mobile label to repeat it. --}} started_at) data-label="Started" @endif @if($when) title="{{ $when->toDayDateTimeString() }}" @endif> {{ $when ? ($job->started_at ? '' : 'Queued ') . $when->diffForHumans() : '' }} @if($job->started_at && $job->finished_at) {{ $took($job->getElapsedInterval()->totalSeconds) }} @else @endif @if($job->canBeRetried())
@csrf
@elseif($failed && $job->retried) Retried @else @endif @if($failed && $job->exception_message)
@if($job->exception_class)
{{ class_basename($job->exception_class) }}
@endif

{{ $job->exception_message }}

@if($job->exception)
Stack trace
{{ $job->exception }}
@endif
@endif
@endforeach @endif
@include('admin.system._pager', ['p' => $jobs])
@endsection