Progress reporting infrastructure.

This commit is contained in:
Taloth Saldono 2017-12-14 20:26:28 +01:00
parent 74fbc97835
commit 2c8489de43
3 changed files with 179 additions and 0 deletions

View File

@ -215,9 +215,11 @@
<Compile Include="ServiceFactory.cs" />
<Compile Include="ServiceProvider.cs" />
<Compile Include="Extensions\StringExtensions.cs" />
<Compile Include="Timeline\TimelineContext.cs" />
<Compile Include="TinyIoC.cs" />
<Compile Include="TPL\Debouncer.cs" />
<Compile Include="TPL\LimitedConcurrencyLevelTaskScheduler.cs" />
<Compile Include="Timeline\ProgressReporter.cs" />
<Compile Include="TPL\RateLimitService.cs" />
<Compile Include="TPL\TaskExtensions.cs" />
<Compile Include="Extensions\TryParseExtensions.cs" />

View File

@ -0,0 +1,77 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace NzbDrone.Common.Timeline
{
public interface IProgressReporter
{
long Raw { get; }
long Total { get; }
double Progress { get; }
void UpdateProgress(long currentProgress, long maxProgress);
void FinishProgress();
}
public class ProgressReporter : IProgressReporter
{
private readonly int _maxSteps;
public long Raw { get; protected set; }
public long Total { get; private set; }
public double Progress => Total == 0 ? 1.0 : Math.Min(Raw, Total) / Total;
//public TimeSpan? EstimatedDurationRemaining { get; private set; }
public ProgressReporter(long initialProgress, long maxProgress, int maxSteps = 100)
{
_maxSteps = maxSteps;
Raw = initialProgress;
Total = maxProgress;
}
public void UpdateProgress(long currentProgress, long maxProgress)
{
bool shouldRaiseEvent;
lock (this)
{
var oldRaw = Raw;
var oldTotal = Total;
Raw = currentProgress;
Total = Total;
var oldStep = oldTotal <= 0 ? _maxSteps : oldRaw * _maxSteps / oldTotal;
var newStep = Total <= 0 ? _maxSteps : Raw * _maxSteps / Total;
shouldRaiseEvent = (oldStep != newStep);
}
if (shouldRaiseEvent)
{
RaiseEvent();
}
}
public void FinishProgress()
{
lock (this)
{
Raw = Total;
}
RaiseEvent();
}
protected virtual void RaiseEvent()
{
// TODO
}
}
}

View File

@ -0,0 +1,100 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace NzbDrone.Common.Timeline
{
public enum TimelineState
{
Pending,
Started,
Completed,
Failed
}
public interface ITimelineContext : IProgressReporter
{
string Name { get; }
TimelineState State { get; }
void UpdateState(TimelineState state);
ITimelineContext AppendTimeline(string name, long initialProgress = 0, long maxProgress = 1);
void AppendTimeline(ITimelineContext timeline);
}
public class TimelineContext : ProgressReporter, ITimelineContext
{
private List<ITimelineContext> _timelines = new List<ITimelineContext>();
public string Name { get; private set; }
public TimelineState State { get; private set; }
public IEnumerable<ITimelineContext> Timelines
{
get
{
lock (this)
{
return _timelines.ToArray();
}
}
}
public TimelineContext(string name, long initialProgress, long maxProgress)
: base(initialProgress, maxProgress)
{
Name = name;
}
public void UpdateState(TimelineState state)
{
lock (this)
{
State = state;
if (State == TimelineState.Completed || State == TimelineState.Failed)
{
Raw = Total;
}
}
RaiseEvent();
}
public ITimelineContext AppendTimeline(string name, long initialProgress = 0, long maxProgress = 1)
{
lock (this)
{
var timeline = new TimelineContext(name, initialProgress, maxProgress);
_timelines.Add(timeline);
return timeline;
}
}
public void AppendTimeline(ITimelineContext timeline)
{
lock (this)
{
_timelines.Add(timeline);
}
}
protected override void RaiseEvent()
{
lock (this)
{
if (Raw == Total)
{
State = TimelineState.Completed;
}
else
{
State = TimelineState.Started;
}
}
base.RaiseEvent();
}
}
}