mirror of
https://github.com/lidarr/lidarr.git
synced 2025-08-19 13:10:13 -07:00
Fixed: Prevent two TypeExclusive commands running at once
The check was bypassed if a disk access command was running at the same time.
This commit is contained in:
parent
368363de96
commit
da2b36514a
2 changed files with 56 additions and 43 deletions
|
@ -88,6 +88,25 @@ namespace NzbDrone.Core.Test.Messaging.Commands
|
||||||
command.Should().BeNull();
|
command.Should().BeNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_not_return_type_exclusive_command_if_another_and_disk_access_command_running()
|
||||||
|
{
|
||||||
|
GivenStartedTypeExclusiveCommand();
|
||||||
|
GivenStartedDiskCommand();
|
||||||
|
|
||||||
|
var newCommandModel = Builder<CommandModel>
|
||||||
|
.CreateNew()
|
||||||
|
.With(c => c.Name = "ImportListSync")
|
||||||
|
.With(c => c.Body = new ImportListSyncCommand())
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
Subject.Add(newCommandModel);
|
||||||
|
|
||||||
|
Subject.TryGet(out var command);
|
||||||
|
|
||||||
|
command.Should().BeNull();
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_return_type_exclusive_command_if_another_not_running()
|
public void should_return_type_exclusive_command_if_another_not_running()
|
||||||
{
|
{
|
||||||
|
|
|
@ -134,59 +134,53 @@ namespace NzbDrone.Core.Messaging.Commands
|
||||||
.Select(x => x.Body.Name)
|
.Select(x => x.Body.Name)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
var localItem = _items.Where(c =>
|
var queuedCommands = _items.Where(c => c.Status == CommandStatus.Queued);
|
||||||
{
|
|
||||||
// If an executing command requires disk access don't return a command that
|
|
||||||
// requires disk access. A lower priority or later queued task could be returned
|
|
||||||
// instead, but that will allow other tasks to execute whiule waiting for disk access.
|
|
||||||
if (startedCommands.Any(x => x.Body.RequiresDiskAccess))
|
|
||||||
{
|
|
||||||
return c.Status == CommandStatus.Queued &&
|
|
||||||
!c.Body.RequiresDiskAccess;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If an executing command is TypeExclusive don't return a command with same type
|
if (startedCommands.Any(x => x.Body.RequiresDiskAccess))
|
||||||
if (startedCommands.Any(x => x.Body.IsTypeExclusive)) {
|
{
|
||||||
return c.Status == CommandStatus.Queued && !exclusiveTypes.Any(x => x == c.Body.Name);
|
queuedCommands = queuedCommands.Where(c => !c.Body.RequiresDiskAccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.Status == CommandStatus.Queued;
|
if (startedCommands.Any(x => x.Body.IsTypeExclusive))
|
||||||
})
|
{
|
||||||
.OrderByDescending(c => c.Priority)
|
queuedCommands = queuedCommands.Where(c => !exclusiveTypes.Any(x => x == c.Body.Name));
|
||||||
.ThenBy(c => c.QueuedAt)
|
}
|
||||||
.FirstOrDefault();
|
|
||||||
|
|
||||||
// Nothing queued that meets the requirements
|
var localItem = queuedCommands.OrderByDescending(c => c.Priority)
|
||||||
if (localItem == null)
|
.ThenBy(c => c.QueuedAt)
|
||||||
{
|
.FirstOrDefault();
|
||||||
rval = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If any executing command is exclusive don't want return another command until it completes.
|
// Nothing queued that meets the requirements
|
||||||
else if (startedCommands.Any(c => c.Body.IsExclusive))
|
if (localItem == null)
|
||||||
{
|
{
|
||||||
rval = false;
|
rval = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the next command to execute is exclusive wait for executing commands to complete.
|
// If any executing command is exclusive don't want return another command until it completes.
|
||||||
// This will prevent other tasks from starting so the exclusive task executes in the order it should.
|
else if (startedCommands.Any(c => c.Body.IsExclusive))
|
||||||
else if (localItem.Body.IsExclusive && startedCommands.Any())
|
{
|
||||||
{
|
rval = false;
|
||||||
rval = false;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// A command ready to execute
|
// If the next command to execute is exclusive wait for executing commands to complete.
|
||||||
else
|
// This will prevent other tasks from starting so the exclusive task executes in the order it should.
|
||||||
{
|
else if (localItem.Body.IsExclusive && startedCommands.Any())
|
||||||
localItem.StartedAt = DateTime.UtcNow;
|
{
|
||||||
localItem.Status = CommandStatus.Started;
|
rval = false;
|
||||||
|
}
|
||||||
|
|
||||||
item = localItem;
|
// A command ready to execute
|
||||||
}
|
else
|
||||||
|
{
|
||||||
|
localItem.StartedAt = DateTime.UtcNow;
|
||||||
|
localItem.Status = CommandStatus.Started;
|
||||||
|
|
||||||
|
item = localItem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return rval;
|
return rval;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue