@page "/queue/{queue?}/{pagination:int?}/{status?}" @inject QueueService QueueSvc @using Iceshrimp.Backend.Core.Database.Tables @using Iceshrimp.Backend.Core.Extensions @using Iceshrimp.Backend.Core.Services @model QueueModel @{ ViewData["title"] = $"Queue dashboard - {Model.InstanceName}"; } @section head { } @section scripts { @if (Model.Queue == null) { } }

Queue Dashboard

@foreach (var queue in QueueSvc.QueueNames) { }
@if (Model.Queue == null) {

Please pick a queue.

Queue status — Connecting...

@foreach (var status in Enum.GetValues()) { var name = Enum.GetName(status); } @foreach (var queue in Model.QueueStatuses ?? throw new Exception("Model.QueueStatuses must not be null here")) { var isScheduled = QueueModel.ScheduledQueues.Contains(queue.Name); var scheduled = isScheduled ? queue.JobCounts[Job.JobStatus.Delayed].ToString() : "-"; var delayed = !isScheduled ? queue.JobCounts[Job.JobStatus.Delayed].ToString() : "-"; @foreach (var status in Enum.GetValues()) { var name = Enum.GetName(status)!.ToLowerInvariant(); if (status == Job.JobStatus.Delayed) { if (!isScheduled) { } else { } } else if (status == Job.JobStatus.Queued && isScheduled) { } else { } } }
Name@name
@queue.Name @delayed @delayed (@scheduled) @queue.JobCounts[status] @queue.JobCounts[status]

Recent jobs

@foreach (var job in Model.Jobs) { await RenderJob(job, true); }
ID Queue Status Actions
var last = Model.Jobs.FirstOrDefault(); var lastUpdated = last != null ? new DateTimeOffset(last.LastUpdatedAt).ToUnixTimeMilliseconds() : 0; } else { var delayedStr = QueueModel.ScheduledQueues.Contains(Model.Queue) ? "scheduled" : "delayed"; if (Model.Filter == null) {

Listing @Model.TotalCount @Model.Queue jobs, out of which @Model.RunningCount are running, @Model.QueuedCount are queued and @Model.DelayedCount are @delayedStr.

} else { var filterStr = Model.Filter.Value == Job.JobStatus.Delayed && QueueModel.ScheduledQueues.Contains(Model.Queue) ? "scheduled" : Model.Filter.Value.ToString().ToLowerInvariant();

Listing @Model.TotalCount @filterStr @Model.Queue jobs. @if (Model.Filter is Job.JobStatus.Failed) { Batch retry: all failed / all on this page }

} @foreach (var job in Model.Jobs) { await RenderJob(job); }
ID Status Actions
@if (Model.PrevPage != null) { if (Model.Filter.HasValue) { } else { } } else { } @if (Model.NextPage != null) { if (Model.Filter.HasValue) { } else { } } else { }
} @{ async Task RenderJob(Job job, bool withQueue = false) { var id = job.Id.ToStringLower(); var additional = job.Status switch { Job.JobStatus.Delayed when job.RetryCount is 0 => $"for {job.DelayedUntil?.ToLocalTime().ToDisplayStringTz() ?? ""}", // Separated for readability Job.JobStatus.Queued => $"for {job.QueueDuration.ToDurationDisplayString()}", Job.JobStatus.Running => $"for {job.Duration.ToDurationDisplayString()}", Job.JobStatus.Delayed => $"until {job.DelayedUntil?.ToLocalTime().ToDisplayStringTz() ?? ""}", Job.JobStatus.Completed => $"at {job.FinishedAt?.ToLocalTime().ToDisplayStringTz() ?? ""}", Job.JobStatus.Failed => $"at {job.FinishedAt?.ToLocalTime().ToDisplayStringTz() ?? ""}", _ => throw new ArgumentOutOfRangeException() }; var classes = Model.Last != null && new DateTimeOffset(job.LastUpdatedAt).ToUnixTimeMilliseconds() > Model.Last ? "new-item" : ""; var status = job is { Status: Job.JobStatus.Delayed, RetryCount: 0 } ? "Scheduled" : job.Status.ToString(); @if (withQueue) { @id[..8]...@id[24..] @job.Queue } else { @id } @status @additional View details } }