From 45329f29bdf28ab2946f3ee3ea2d06b4fd4004d7 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Mon, 3 Apr 2023 22:11:43 -0700 Subject: [PATCH] New: Add result to commands to report commands that did not complete successfully (cherry picked from commit 103ce3def4636ef891e72bd687ef8f46b5125233) --- src/Lidarr.Api.V1/Commands/CommandResource.cs | 2 + .../Migration/064_add_result_to_commands.cs | 14 ++++++ .../DownloadedAlbumsCommandService.cs | 11 +++-- .../Messaging/Commands/CommandModel.cs | 3 +- .../Messaging/Commands/CommandQueueManager.cs | 12 ++++++ .../Messaging/Commands/CommandResult.cs | 9 ++++ .../Commands/CommandResultReporter.cs | 43 +++++++++++++++++++ 7 files changed, 90 insertions(+), 4 deletions(-) create mode 100644 src/NzbDrone.Core/Datastore/Migration/064_add_result_to_commands.cs create mode 100644 src/NzbDrone.Core/Messaging/Commands/CommandResult.cs create mode 100644 src/NzbDrone.Core/Messaging/Commands/CommandResultReporter.cs diff --git a/src/Lidarr.Api.V1/Commands/CommandResource.cs b/src/Lidarr.Api.V1/Commands/CommandResource.cs index 25b1032ba..95d7fb306 100644 --- a/src/Lidarr.Api.V1/Commands/CommandResource.cs +++ b/src/Lidarr.Api.V1/Commands/CommandResource.cs @@ -17,6 +17,7 @@ namespace Lidarr.Api.V1.Commands public Command Body { get; set; } public CommandPriority Priority { get; set; } public CommandStatus Status { get; set; } + public CommandResult Result { get; set; } public DateTime Queued { get; set; } public DateTime? Started { get; set; } public DateTime? Ended { get; set; } @@ -102,6 +103,7 @@ namespace Lidarr.Api.V1.Commands Body = model.Body, Priority = model.Priority, Status = model.Status, + Result = model.Result, Queued = model.QueuedAt, Started = model.StartedAt, Ended = model.EndedAt, diff --git a/src/NzbDrone.Core/Datastore/Migration/064_add_result_to_commands.cs b/src/NzbDrone.Core/Datastore/Migration/064_add_result_to_commands.cs new file mode 100644 index 000000000..c44594056 --- /dev/null +++ b/src/NzbDrone.Core/Datastore/Migration/064_add_result_to_commands.cs @@ -0,0 +1,14 @@ +using FluentMigrator; +using NzbDrone.Core.Datastore.Migration.Framework; + +namespace NzbDrone.Core.Datastore.Migration +{ + [Migration(064)] + public class add_result_to_commands : NzbDroneMigrationBase + { + protected override void MainDbUpgrade() + { + Alter.Table("Commands").AddColumn("Result").AsInt32().WithDefaultValue(1); + } + } +} diff --git a/src/NzbDrone.Core/MediaFiles/DownloadedAlbumsCommandService.cs b/src/NzbDrone.Core/MediaFiles/DownloadedAlbumsCommandService.cs index 1a0a3e853..9c9892a0e 100644 --- a/src/NzbDrone.Core/MediaFiles/DownloadedAlbumsCommandService.cs +++ b/src/NzbDrone.Core/MediaFiles/DownloadedAlbumsCommandService.cs @@ -4,6 +4,7 @@ using System.Linq; using NLog; using NzbDrone.Common.Disk; using NzbDrone.Common.Extensions; +using NzbDrone.Common.Instrumentation.Extensions; using NzbDrone.Core.Download; using NzbDrone.Core.Download.TrackedDownloads; using NzbDrone.Core.MediaFiles.Commands; @@ -18,18 +19,21 @@ namespace NzbDrone.Core.MediaFiles private readonly ITrackedDownloadService _trackedDownloadService; private readonly IDiskProvider _diskProvider; private readonly ICompletedDownloadService _completedDownloadService; + private readonly ICommandResultReporter _commandResultReporter; private readonly Logger _logger; public DownloadedAlbumsCommandService(IDownloadedTracksImportService downloadedTracksImportService, ITrackedDownloadService trackedDownloadService, IDiskProvider diskProvider, ICompletedDownloadService completedDownloadService, + ICommandResultReporter commandResultReporter, Logger logger) { _downloadedTracksImportService = downloadedTracksImportService; _trackedDownloadService = trackedDownloadService; _diskProvider = diskProvider; _completedDownloadService = completedDownloadService; + _commandResultReporter = commandResultReporter; _logger = logger; } @@ -77,9 +81,10 @@ namespace NzbDrone.Core.MediaFiles if (importResults == null || importResults.All(v => v.Result != ImportResultType.Imported)) { - // Atm we don't report it as a command failure, coz that would cause the download to be failed. - // Changing the message won't do a thing either, coz it will get set to 'Completed' a msec later. - // message.SetMessage("Failed to import"); + // Allow the command to complete successfully, but report as unsuccessful + + _logger.ProgressDebug("Failed to import"); + _commandResultReporter.Report(CommandResult.Unsuccessful); } } } diff --git a/src/NzbDrone.Core/Messaging/Commands/CommandModel.cs b/src/NzbDrone.Core/Messaging/Commands/CommandModel.cs index 276a9b3ca..d7ec0dc37 100644 --- a/src/NzbDrone.Core/Messaging/Commands/CommandModel.cs +++ b/src/NzbDrone.Core/Messaging/Commands/CommandModel.cs @@ -1,4 +1,4 @@ -using System; +using System; using NzbDrone.Common.Messaging; using NzbDrone.Core.Datastore; @@ -10,6 +10,7 @@ namespace NzbDrone.Core.Messaging.Commands public Command Body { get; set; } public CommandPriority Priority { get; set; } public CommandStatus Status { get; set; } + public CommandResult Result { get; set; } public DateTime QueuedAt { get; set; } public DateTime? StartedAt { get; set; } public DateTime? EndedAt { get; set; } diff --git a/src/NzbDrone.Core/Messaging/Commands/CommandQueueManager.cs b/src/NzbDrone.Core/Messaging/Commands/CommandQueueManager.cs index cf11f4320..c830e74e0 100644 --- a/src/NzbDrone.Core/Messaging/Commands/CommandQueueManager.cs +++ b/src/NzbDrone.Core/Messaging/Commands/CommandQueueManager.cs @@ -26,6 +26,7 @@ namespace NzbDrone.Core.Messaging.Commands CommandModel Get(int id); List GetStarted(); void SetMessage(CommandModel command, string message); + void SetResult(CommandModel command, CommandResult result); void Start(CommandModel command); void Complete(CommandModel command, string message); void Fail(CommandModel command, string message, Exception e); @@ -180,6 +181,11 @@ namespace NzbDrone.Core.Messaging.Commands command.Message = message; } + public void SetResult(CommandModel command, CommandResult result) + { + command.Result = result; + } + public void Start(CommandModel command) { // Marks the command as started in the DB, the queue takes care of marking it as started on it's own @@ -189,6 +195,12 @@ namespace NzbDrone.Core.Messaging.Commands public void Complete(CommandModel command, string message) { + // If the result hasn't been set yet then set it to successful + if (command.Result == CommandResult.Unknown) + { + command.Result = CommandResult.Successful; + } + Update(command, CommandStatus.Completed, message); _commandQueue.PulseAllConsumers(); diff --git a/src/NzbDrone.Core/Messaging/Commands/CommandResult.cs b/src/NzbDrone.Core/Messaging/Commands/CommandResult.cs new file mode 100644 index 000000000..9e865df92 --- /dev/null +++ b/src/NzbDrone.Core/Messaging/Commands/CommandResult.cs @@ -0,0 +1,9 @@ +namespace NzbDrone.Core.Messaging.Commands +{ + public enum CommandResult + { + Unknown = 0, + Successful = 1, + Unsuccessful = 2 + } +} diff --git a/src/NzbDrone.Core/Messaging/Commands/CommandResultReporter.cs b/src/NzbDrone.Core/Messaging/Commands/CommandResultReporter.cs new file mode 100644 index 000000000..c74d2c06b --- /dev/null +++ b/src/NzbDrone.Core/Messaging/Commands/CommandResultReporter.cs @@ -0,0 +1,43 @@ +using NzbDrone.Core.ProgressMessaging; + +namespace NzbDrone.Core.Messaging.Commands +{ + public interface ICommandResultReporter + { + void Report(CommandResult result); + } + + public class CommandResultReporter : ICommandResultReporter + { + private readonly IManageCommandQueue _commandQueueManager; + + public CommandResultReporter(IManageCommandQueue commandQueueManager) + { + _commandQueueManager = commandQueueManager; + } + + public void Report(CommandResult result) + { + var command = ProgressMessageContext.CommandModel; + + if (command == null) + { + return; + } + + if (!ProgressMessageContext.LockReentrancy()) + { + return; + } + + try + { + _commandQueueManager.SetResult(command, result); + } + finally + { + ProgressMessageContext.UnlockReentrancy(); + } + } + } +}