New: Store Task StartTime, Show Duration in UI

Closes #5266
This commit is contained in:
Qstick 2019-12-15 00:34:45 -05:00 committed by Mark McDowall
parent 11e6e12676
commit b98ce7fb17
12 changed files with 63 additions and 9 deletions

View File

@ -5,6 +5,7 @@
} }
.lastExecution, .lastExecution,
.lastDuration,
.nextExecution { .nextExecution {
composes: cell from '~Components/Table/Cells/TableRowCell.css'; composes: cell from '~Components/Table/Cells/TableRowCell.css';

View File

@ -7,6 +7,7 @@ import TableRow from 'Components/Table/TableRow';
import { icons } from 'Helpers/Props'; import { icons } from 'Helpers/Props';
import formatDate from 'Utilities/Date/formatDate'; import formatDate from 'Utilities/Date/formatDate';
import formatDateTime from 'Utilities/Date/formatDateTime'; import formatDateTime from 'Utilities/Date/formatDateTime';
import formatTimeSpan from 'Utilities/Date/formatTimeSpan';
import styles from './ScheduledTaskRow.css'; import styles from './ScheduledTaskRow.css';
function getFormattedDates(props) { function getFormattedDates(props) {
@ -91,6 +92,8 @@ class ScheduledTaskRow extends Component {
name, name,
interval, interval,
lastExecution, lastExecution,
lastStartTime,
lastDuration,
nextExecution, nextExecution,
isQueued, isQueued,
isExecuting, isExecuting,
@ -108,6 +111,7 @@ class ScheduledTaskRow extends Component {
const executeNow = !isDisabled && moment().isAfter(nextExecution); const executeNow = !isDisabled && moment().isAfter(nextExecution);
const hasNextExecutionTime = !isDisabled && !executeNow; const hasNextExecutionTime = !isDisabled && !executeNow;
const duration = moment.duration(interval, 'minutes').humanize().replace(/an?(?=\s)/, '1'); const duration = moment.duration(interval, 'minutes').humanize().replace(/an?(?=\s)/, '1');
const hasLastStartTime = moment(lastStartTime).isAfter('2010-01-01');
return ( return (
<TableRow> <TableRow>
@ -125,6 +129,21 @@ class ScheduledTaskRow extends Component {
{lastExecutionTime} {lastExecutionTime}
</TableRowCell> </TableRowCell>
{
!hasLastStartTime &&
<TableRowCell className={styles.lastDuration}>-</TableRowCell>
}
{
hasLastStartTime &&
<TableRowCell
className={styles.lastDuration}
title={lastDuration}
>
{formatTimeSpan(lastDuration)}
</TableRowCell>
}
{ {
isDisabled && isDisabled &&
<TableRowCell className={styles.nextExecution}>-</TableRowCell> <TableRowCell className={styles.nextExecution}>-</TableRowCell>
@ -169,6 +188,8 @@ ScheduledTaskRow.propTypes = {
name: PropTypes.string.isRequired, name: PropTypes.string.isRequired,
interval: PropTypes.number.isRequired, interval: PropTypes.number.isRequired,
lastExecution: PropTypes.string.isRequired, lastExecution: PropTypes.string.isRequired,
lastStartTime: PropTypes.string.isRequired,
lastDuration: PropTypes.string.isRequired,
nextExecution: PropTypes.string.isRequired, nextExecution: PropTypes.string.isRequired,
isQueued: PropTypes.bool.isRequired, isQueued: PropTypes.bool.isRequired,
isExecuting: PropTypes.bool.isRequired, isExecuting: PropTypes.bool.isRequired,

View File

@ -22,6 +22,11 @@ const columns = [
label: 'Last Execution', label: 'Last Execution',
isVisible: true isVisible: true
}, },
{
name: 'lastDuration',
label: 'Last Duration',
isVisible: true
},
{ {
name: 'nextExecution', name: 'nextExecution',
label: 'Next Execution', label: 'Next Execution',

View File

@ -0,0 +1,14 @@
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
{
[Migration(180)]
public class task_duration : NzbDroneMigrationBase
{
protected override void MainDbUpgrade()
{
Alter.Table("ScheduledTasks").AddColumn("LastStartTime").AsDateTime().Nullable();
}
}
}

View File

@ -10,6 +10,7 @@ namespace NzbDrone.Core.Jobs
public int Interval { get; set; } public int Interval { get; set; }
public DateTime LastExecution { get; set; } public DateTime LastExecution { get; set; }
public CommandPriority Priority { get; set; } public CommandPriority Priority { get; set; }
public DateTime LastStartTime { get; set; }
public ScheduledTask() public ScheduledTask()
{ {

View File

@ -8,7 +8,7 @@ namespace NzbDrone.Core.Jobs
public interface IScheduledTaskRepository : IBasicRepository<ScheduledTask> public interface IScheduledTaskRepository : IBasicRepository<ScheduledTask>
{ {
ScheduledTask GetDefinition(Type type); ScheduledTask GetDefinition(Type type);
void SetLastExecutionTime(int id, DateTime executionTime); void SetLastExecutionTime(int id, DateTime executionTime, DateTime startTime);
} }
public class ScheduledTaskRepository : BasicRepository<ScheduledTask>, IScheduledTaskRepository public class ScheduledTaskRepository : BasicRepository<ScheduledTask>, IScheduledTaskRepository
@ -23,15 +23,16 @@ namespace NzbDrone.Core.Jobs
return Query(c => c.TypeName == type.FullName).Single(); return Query(c => c.TypeName == type.FullName).Single();
} }
public void SetLastExecutionTime(int id, DateTime executionTime) public void SetLastExecutionTime(int id, DateTime executionTime, DateTime startTime)
{ {
var task = new ScheduledTask var task = new ScheduledTask
{ {
Id = id, Id = id,
LastExecution = executionTime LastExecution = executionTime,
LastStartTime = startTime
}; };
SetFields(task, scheduledTask => scheduledTask.LastExecution); SetFields(task, scheduledTask => scheduledTask.LastExecution, scheduledTask => scheduledTask.LastStartTime);
} }
} }
} }

View File

@ -39,7 +39,7 @@ namespace NzbDrone.Core.Jobs
foreach (var task in tasks) foreach (var task in tasks)
{ {
_commandQueueManager.Push(task.TypeName, task.LastExecution, task.Priority, CommandTrigger.Scheduled); _commandQueueManager.Push(task.TypeName, task.LastExecution, task.LastStartTime, task.Priority, CommandTrigger.Scheduled);
} }
} }
finally finally

View File

@ -208,9 +208,14 @@ namespace NzbDrone.Core.Jobs
_logger.Trace("Updating last run time for: {0}", scheduledTask.TypeName); _logger.Trace("Updating last run time for: {0}", scheduledTask.TypeName);
var lastExecution = DateTime.UtcNow; var lastExecution = DateTime.UtcNow;
var startTime = message.Command.StartedAt.Value;
_scheduledTaskRepository.SetLastExecutionTime(scheduledTask.Id, lastExecution); _scheduledTaskRepository.SetLastExecutionTime(scheduledTask.Id, lastExecution, startTime);
_cache.Find(scheduledTask.TypeName).LastExecution = lastExecution;
var cached = _cache.Find(scheduledTask.TypeName);
cached.LastExecution = lastExecution;
cached.LastStartTime = startTime;
} }
} }

View File

@ -30,6 +30,7 @@ namespace NzbDrone.Core.Messaging.Commands
public string Name { get; private set; } public string Name { get; private set; }
public DateTime? LastExecutionTime { get; set; } public DateTime? LastExecutionTime { get; set; }
public DateTime? LastStartTime { get; set; }
public CommandTrigger Trigger { get; set; } public CommandTrigger Trigger { get; set; }
public bool SuppressMessages { get; set; } public bool SuppressMessages { get; set; }

View File

@ -20,7 +20,7 @@ namespace NzbDrone.Core.Messaging.Commands
where TCommand : Command; where TCommand : Command;
CommandModel Push<TCommand>(TCommand command, CommandPriority priority = CommandPriority.Normal, CommandTrigger trigger = CommandTrigger.Unspecified) CommandModel Push<TCommand>(TCommand command, CommandPriority priority = CommandPriority.Normal, CommandTrigger trigger = CommandTrigger.Unspecified)
where TCommand : Command; where TCommand : Command;
CommandModel Push(string commandName, DateTime? lastExecutionTime, CommandPriority priority = CommandPriority.Normal, CommandTrigger trigger = CommandTrigger.Unspecified); CommandModel Push(string commandName, DateTime? lastExecutionTime, DateTime? lastStartTime, CommandPriority priority = CommandPriority.Normal, CommandTrigger trigger = CommandTrigger.Unspecified);
IEnumerable<CommandModel> Queue(CancellationToken cancellationToken); IEnumerable<CommandModel> Queue(CancellationToken cancellationToken);
List<CommandModel> All(); List<CommandModel> All();
CommandModel Get(int id); CommandModel Get(int id);
@ -136,10 +136,11 @@ namespace NzbDrone.Core.Messaging.Commands
} }
} }
public CommandModel Push(string commandName, DateTime? lastExecutionTime, CommandPriority priority = CommandPriority.Normal, CommandTrigger trigger = CommandTrigger.Unspecified) public CommandModel Push(string commandName, DateTime? lastExecutionTime, DateTime? lastStartTime, CommandPriority priority = CommandPriority.Normal, CommandTrigger trigger = CommandTrigger.Unspecified)
{ {
dynamic command = GetCommand(commandName); dynamic command = GetCommand(commandName);
command.LastExecutionTime = lastExecutionTime; command.LastExecutionTime = lastExecutionTime;
command.LastStartTime = lastStartTime;
command.Trigger = trigger; command.Trigger = trigger;
return Push(command, priority, trigger); return Push(command, priority, trigger);

View File

@ -55,6 +55,7 @@ namespace Sonarr.Api.V3.System.Tasks
TaskName = taskName, TaskName = taskName,
Interval = scheduledTask.Interval, Interval = scheduledTask.Interval,
LastExecution = scheduledTask.LastExecution, LastExecution = scheduledTask.LastExecution,
LastStartTime = scheduledTask.LastStartTime,
NextExecution = scheduledTask.LastExecution.AddMinutes(scheduledTask.Interval) NextExecution = scheduledTask.LastExecution.AddMinutes(scheduledTask.Interval)
}; };
} }

View File

@ -9,6 +9,9 @@ namespace Sonarr.Api.V3.System.Tasks
public string TaskName { get; set; } public string TaskName { get; set; }
public int Interval { get; set; } public int Interval { get; set; }
public DateTime LastExecution { get; set; } public DateTime LastExecution { get; set; }
public DateTime LastStartTime { get; set; }
public DateTime NextExecution { get; set; } public DateTime NextExecution { get; set; }
public TimeSpan LastDuration => LastExecution - LastStartTime;
} }
} }