@page "/queue/job/{id::guid:required}" @using System.Text.Json @using System.Text.Json.Nodes @using System.Text.Json.Serialization @using Iceshrimp.Backend.Core.Database.Tables @using Iceshrimp.Backend.Core.Extensions @model QueueJobModel @{ ViewData["title"] = $"Job details - {Model.InstanceName}"; } @section head { } @section scripts { }

Queue Dashboard

Job details

@{ var status = Model.Job is { Status: Job.JobStatus.Delayed, RetryCount: 0 } ? "Scheduled" : Model.Job.Status.ToString(); } @if (Model.Job.Status.Equals(Job.JobStatus.Failed)) { } else if (Model.Job.Status.Equals(Job.JobStatus.Delayed)) { var abandonName = Model.Job.RetryCount == 0 ? "Deschedule" : "Abandon"; } @if (Model.Job.Status is not Job.JobStatus.Queued and not Job.JobStatus.Delayed) { } @if (Model.Job.Status is Job.JobStatus.Completed or Job.JobStatus.Failed) { } @if (Model.Job.Status == Job.JobStatus.Delayed) { } @if (TimeSpan.FromMilliseconds(Model.Job.Duration).TotalHours <= 72) { } @if (TimeSpan.FromMilliseconds(Model.Job.QueueDuration).TotalHours <= 72) { } @if (Model.Job.RetryCount > 0) { } @if (Model.Job is { ExceptionMessage: not null, Exception: null }) { } @if (Model.Job is { ExceptionSource: not null, Exception: null }) { }
ID @Model.Job.Id.ToStringLower()
Queue @Model.Job.Queue
Status @status
Actions Retry
Actions @abandonName
Queued at @Model.Job.QueuedAt.ToLocalTime().ToDisplayStringTz()
Started at @(Model.Job.StartedAt?.ToLocalTime().ToDisplayStringTz() ?? "")
Finished at @(Model.Job.FinishedAt?.ToLocalTime().ToDisplayStringTz() ?? "")
Delayed until @(Model.Job.DelayedUntil?.ToLocalTime().ToDisplayStringTz() ?? "")
Duration @Model.Job.Duration.ToDurationDisplayString()
Queue duration @Model.Job.QueueDuration.ToDurationDisplayString()
Retry count @Model.Job.RetryCount
Exception message @Model.Job.ExceptionMessage
Exception source @Model.Job.ExceptionSource
@if (Model.Job is { StackTrace: not null, Exception: null }) {

Exception stack trace

@Model.Job.StackTrace
} @if (Model.Job.Exception != null) {

Exception details

@Model.Job.Exception
}

Job data

@{ var dataOpts = new JsonSerializerOptions { WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull }; var payloadOpts = new JsonSerializerOptions { WriteIndented = true }; if (Model.Lookup.TryGetValue(Model.Job.Queue, out var payloadKey)) { var data = JsonNode.Parse(Model.Job.Data)?.AsObject() ?? throw new Exception($"Failed to deserialize {Model.Job.Queue} job data"); var payloadElem = data[payloadKey]; var payload = payloadElem?.GetValue() ?? throw new Exception($"Failed to deserialize {Model.Job.Queue} job data"); var payloadJson = JsonNode.Parse(payload)?.ToJsonString(payloadOpts) ?? throw new Exception($"Failed to serialize {Model.Job.Queue} job data"); data.Remove(payloadKey); foreach (var item in data.Where(p => p.Value?.GetValueKind() is null or JsonValueKind.Null).ToList()) data.Remove(item.Key); var dataJson = data.ToJsonString(dataOpts);
@dataJson

Job payload

@payloadJson
} else { var json = JsonNode.Parse(Model.Job.Data)?.ToJsonString(payloadOpts) ?? throw new Exception($"Failed to serialize {Model.Job.Queue} job data");
@json
} }