2013-08-29 04:43:26 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
2013-08-31 03:08:19 +00:00
|
|
|
|
using System.Runtime.Remoting;
|
2013-08-29 04:43:26 +00:00
|
|
|
|
using NzbDrone.Common.Cache;
|
|
|
|
|
|
|
|
|
|
namespace NzbDrone.Common.Messaging.Tracking
|
|
|
|
|
{
|
|
|
|
|
public interface ITrackCommands
|
|
|
|
|
{
|
|
|
|
|
TrackedCommand TrackIfNew(ICommand command);
|
2013-08-31 03:08:19 +00:00
|
|
|
|
ExistingCommand TrackNewOrGet(ICommand command);
|
2013-08-29 04:43:26 +00:00
|
|
|
|
TrackedCommand Completed(TrackedCommand trackedCommand, TimeSpan runtime);
|
|
|
|
|
TrackedCommand Failed(TrackedCommand trackedCommand, Exception e);
|
2013-08-30 17:27:17 +00:00
|
|
|
|
List<TrackedCommand> AllTracked();
|
2013-08-29 04:43:26 +00:00
|
|
|
|
Boolean ExistingCommand(ICommand command);
|
2013-08-31 03:08:19 +00:00
|
|
|
|
TrackedCommand FindExisting(ICommand command);
|
2013-08-29 04:43:26 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-08-30 17:27:17 +00:00
|
|
|
|
public class TrackCommands : ITrackCommands, IExecute<TrackedCommandCleanupCommand>
|
2013-08-29 04:43:26 +00:00
|
|
|
|
{
|
|
|
|
|
private readonly ICached<TrackedCommand> _cache;
|
|
|
|
|
|
|
|
|
|
public TrackCommands(ICacheManger cacheManger)
|
|
|
|
|
{
|
|
|
|
|
_cache = cacheManger.GetCache<TrackedCommand>(GetType());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public TrackedCommand TrackIfNew(ICommand command)
|
|
|
|
|
{
|
|
|
|
|
if (ExistingCommand(command))
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var trackedCommand = new TrackedCommand(command, CommandState.Running);
|
2013-08-30 17:27:17 +00:00
|
|
|
|
Store(trackedCommand);
|
2013-08-29 04:43:26 +00:00
|
|
|
|
|
|
|
|
|
return trackedCommand;
|
|
|
|
|
}
|
|
|
|
|
|
2013-08-31 03:08:19 +00:00
|
|
|
|
public ExistingCommand TrackNewOrGet(ICommand command)
|
|
|
|
|
{
|
|
|
|
|
var trackedCommand = FindExisting(command);
|
|
|
|
|
|
|
|
|
|
if (trackedCommand == null)
|
|
|
|
|
{
|
|
|
|
|
trackedCommand = new TrackedCommand(command, CommandState.Running);
|
|
|
|
|
Store(trackedCommand);
|
|
|
|
|
|
|
|
|
|
return new ExistingCommand(false, trackedCommand);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return new ExistingCommand(true, trackedCommand);
|
|
|
|
|
}
|
|
|
|
|
|
2013-08-29 04:43:26 +00:00
|
|
|
|
public TrackedCommand Completed(TrackedCommand trackedCommand, TimeSpan runtime)
|
|
|
|
|
{
|
|
|
|
|
trackedCommand.StateChangeTime = DateTime.UtcNow;
|
|
|
|
|
trackedCommand.State = CommandState.Completed;
|
|
|
|
|
trackedCommand.Runtime = runtime;
|
|
|
|
|
|
2013-08-30 17:27:17 +00:00
|
|
|
|
Store(trackedCommand);
|
2013-08-29 04:43:26 +00:00
|
|
|
|
|
|
|
|
|
return trackedCommand;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public TrackedCommand Failed(TrackedCommand trackedCommand, Exception e)
|
|
|
|
|
{
|
|
|
|
|
trackedCommand.StateChangeTime = DateTime.UtcNow;
|
|
|
|
|
trackedCommand.State = CommandState.Failed;
|
|
|
|
|
trackedCommand.Exception = e;
|
|
|
|
|
|
2013-08-30 17:27:17 +00:00
|
|
|
|
Store(trackedCommand);
|
2013-08-29 04:43:26 +00:00
|
|
|
|
|
|
|
|
|
return trackedCommand;
|
|
|
|
|
}
|
|
|
|
|
|
2013-08-30 17:27:17 +00:00
|
|
|
|
public List<TrackedCommand> AllTracked()
|
2013-08-29 04:43:26 +00:00
|
|
|
|
{
|
2013-08-30 17:27:17 +00:00
|
|
|
|
return _cache.Values.ToList();
|
2013-08-29 04:43:26 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool ExistingCommand(ICommand command)
|
|
|
|
|
{
|
2013-08-31 03:08:19 +00:00
|
|
|
|
return FindExisting(command) != null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public TrackedCommand FindExisting(ICommand command)
|
|
|
|
|
{
|
|
|
|
|
var comparer = new CommandEqualityComparer();
|
|
|
|
|
return Running(command.GetType()).SingleOrDefault(t => comparer.Equals(t.Command, command));
|
|
|
|
|
}
|
2013-08-29 04:43:26 +00:00
|
|
|
|
|
2013-08-31 03:08:19 +00:00
|
|
|
|
private List<TrackedCommand> Running(Type type = null)
|
|
|
|
|
{
|
|
|
|
|
var running = AllTracked().Where(i => i.State == CommandState.Running);
|
|
|
|
|
|
|
|
|
|
if (type != null)
|
|
|
|
|
{
|
|
|
|
|
return running.Where(t => t.Type == type.FullName).ToList();
|
|
|
|
|
}
|
2013-08-29 04:43:26 +00:00
|
|
|
|
|
2013-08-31 03:08:19 +00:00
|
|
|
|
return running.ToList();
|
2013-08-29 04:43:26 +00:00
|
|
|
|
}
|
2013-08-30 17:27:17 +00:00
|
|
|
|
|
|
|
|
|
private void Store(TrackedCommand trackedCommand)
|
|
|
|
|
{
|
|
|
|
|
if (trackedCommand.Command.GetType() == typeof(TrackedCommandCleanupCommand))
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_cache.Set(trackedCommand.Command.CommandId, trackedCommand);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Execute(TrackedCommandCleanupCommand message)
|
|
|
|
|
{
|
2013-08-31 03:08:19 +00:00
|
|
|
|
var old = AllTracked().Where(c => c.State != CommandState.Running && c.StateChangeTime < DateTime.UtcNow.AddMinutes(-5));
|
2013-08-30 17:27:17 +00:00
|
|
|
|
|
|
|
|
|
foreach (var trackedCommand in old)
|
|
|
|
|
{
|
|
|
|
|
_cache.Remove(trackedCommand.Command.CommandId);
|
|
|
|
|
}
|
|
|
|
|
}
|
2013-08-29 04:43:26 +00:00
|
|
|
|
}
|
|
|
|
|
}
|