diff --git a/src/NzbDrone.Core.Test/Messaging/Commands/CommandQueueFixture.cs b/src/NzbDrone.Core.Test/Messaging/Commands/CommandQueueFixture.cs index e7598a914..e044b3630 100644 --- a/src/NzbDrone.Core.Test/Messaging/Commands/CommandQueueFixture.cs +++ b/src/NzbDrone.Core.Test/Messaging/Commands/CommandQueueFixture.cs @@ -3,6 +3,7 @@ using FluentAssertions; using NUnit.Framework; using NzbDrone.Core.Download; using NzbDrone.Core.ImportLists; +using NzbDrone.Core.Indexers; using NzbDrone.Core.Messaging.Commands; using NzbDrone.Core.Music.Commands; using NzbDrone.Core.Test.Framework; @@ -25,6 +26,18 @@ namespace NzbDrone.Core.Test.Messaging.Commands Subject.Add(commandModel); } + private void GivenLongRunningCommand() + { + var commandModel = Builder + .CreateNew() + .With(c => c.Name = "RssSync") + .With(c => c.Body = new RssSyncCommand()) + .With(c => c.Status = CommandStatus.Started) + .Build(); + + Subject.Add(commandModel); + } + private void GivenStartedTypeExclusiveCommand() { var commandModel = Builder @@ -85,6 +98,24 @@ namespace NzbDrone.Core.Test.Messaging.Commands command.Should().BeNull(); } + [Test] + public void should_not_return_exclusive_command_if_long_running_command_running() + { + GivenLongRunningCommand(); + + var newCommandModel = Builder + .CreateNew() + .With(c => c.Name = "ApplicationUpdate") + .With(c => c.Body = new ApplicationUpdateCommand()) + .Build(); + + Subject.Add(newCommandModel); + + Subject.TryGet(out var command); + + command.Should().BeNull(); + } + [Test] public void should_not_return_type_exclusive_command_if_another_and_disk_access_command_running() { diff --git a/src/NzbDrone.Core/Download/ProcessMonitoredDownloadsCommand.cs b/src/NzbDrone.Core/Download/ProcessMonitoredDownloadsCommand.cs index c3c934031..4b39f1347 100644 --- a/src/NzbDrone.Core/Download/ProcessMonitoredDownloadsCommand.cs +++ b/src/NzbDrone.Core/Download/ProcessMonitoredDownloadsCommand.cs @@ -5,5 +5,7 @@ namespace NzbDrone.Core.Download public class ProcessMonitoredDownloadsCommand : Command { public override bool RequiresDiskAccess => true; + + public override bool IsLongRunning => true; } } diff --git a/src/NzbDrone.Core/Indexers/RssSyncCommand.cs b/src/NzbDrone.Core/Indexers/RssSyncCommand.cs index 47b9cca67..519e61f01 100644 --- a/src/NzbDrone.Core/Indexers/RssSyncCommand.cs +++ b/src/NzbDrone.Core/Indexers/RssSyncCommand.cs @@ -5,5 +5,7 @@ namespace NzbDrone.Core.Indexers public class RssSyncCommand : Command { public override bool SendUpdatesToClient => true; + + public override bool IsLongRunning => true; } } diff --git a/src/NzbDrone.Core/Messaging/Commands/Command.cs b/src/NzbDrone.Core/Messaging/Commands/Command.cs index c3fd74616..057c8d4c4 100644 --- a/src/NzbDrone.Core/Messaging/Commands/Command.cs +++ b/src/NzbDrone.Core/Messaging/Commands/Command.cs @@ -26,8 +26,8 @@ namespace NzbDrone.Core.Messaging.Commands public virtual string CompletionMessage => "Completed"; public virtual bool RequiresDiskAccess => false; public virtual bool IsExclusive => false; - public virtual bool IsTypeExclusive => false; + public virtual bool IsLongRunning => false; public string Name { get; private set; } public DateTime? LastExecutionTime { get; set; } diff --git a/src/NzbDrone.Core/Messaging/Commands/CommandQueue.cs b/src/NzbDrone.Core/Messaging/Commands/CommandQueue.cs index ae92ca94e..8b1b1077e 100644 --- a/src/NzbDrone.Core/Messaging/Commands/CommandQueue.cs +++ b/src/NzbDrone.Core/Messaging/Commands/CommandQueue.cs @@ -98,7 +98,7 @@ namespace NzbDrone.Core.Messaging.Commands public List QueuedOrStarted() { return All().Where(q => q.Status == CommandStatus.Queued || q.Status == CommandStatus.Started) - .ToList(); + .ToList(); } public IEnumerable GetConsumingEnumerable() @@ -158,7 +158,7 @@ namespace NzbDrone.Core.Messaging.Commands else { var startedCommands = _items.Where(c => c.Status == CommandStatus.Started) - .ToList(); + .ToList(); var exclusiveTypes = startedCommands.Where(x => x.Body.IsTypeExclusive) .Select(x => x.Body.Name) @@ -176,9 +176,14 @@ namespace NzbDrone.Core.Messaging.Commands queuedCommands = queuedCommands.Where(c => !exclusiveTypes.Any(x => x == c.Body.Name)); } + if (startedCommands.Any(x => x.Body.IsLongRunning)) + { + queuedCommands = queuedCommands.Where(c => c.Status == CommandStatus.Queued && !c.Body.IsExclusive); + } + var localItem = queuedCommands.OrderByDescending(c => c.Priority) - .ThenBy(c => c.QueuedAt) - .FirstOrDefault(); + .ThenBy(c => c.QueuedAt) + .FirstOrDefault(); // Nothing queued that meets the requirements if (localItem == null)