Skip to content
This repository has been archived by the owner on Apr 7, 2023. It is now read-only.

Commit

Permalink
improve scheduler and git cache
Browse files Browse the repository at this point in the history
  • Loading branch information
Aimeast committed Dec 13, 2015
1 parent e1a6278 commit b0f2aa7
Show file tree
Hide file tree
Showing 8 changed files with 58 additions and 58 deletions.
29 changes: 15 additions & 14 deletions GitCandy/Git/Cache/GitCacheAccessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ public static void Initialize()
Logger.Info("Delete cache directory {0}", dir);
Directory.Delete(dir, true);
}
}, 60));
}, JobType.LongRunning));

enabled = true;
}
Expand Down Expand Up @@ -126,7 +126,7 @@ public static void Delete(string project)
Directory.Delete(path, true);
}

}, 60));
}, JobType.LongRunning));
}

protected void RemoveFromRunningPool()
Expand All @@ -143,7 +143,7 @@ protected virtual void LoadOrCalculate()
{
var loaded = enabled && Load();
task = loaded
? Task.Run(() => { })
? new Task(() => { })
: new Task(() =>
{
try
Expand All @@ -164,16 +164,17 @@ protected virtual void LoadOrCalculate()
RemoveFromRunningPool();
});

if (!loaded)
if (loaded)
{
if (IsAsync)
{
Scheduler.Instance.AddJob(new SingleJob(task));
}
else
{
task.Start();
}
task.Start();
}
else if (IsAsync)
{
Scheduler.Instance.AddJob(new SingleJob(task));
}
else
{
task.Start();
}
}

Expand All @@ -200,12 +201,12 @@ protected virtual void LoadOrCalculate()

public override bool Equals(object obj)
{
return base.Equals(obj);
throw new NotImplementedException("Must override this method");
}

public override int GetHashCode()
{
return base.GetHashCode();
throw new NotImplementedException("Must override this method");
}
}

Expand Down
1 change: 1 addition & 0 deletions GitCandy/GitCandy.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,7 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Schedules\IJob.cs" />
<Compile Include="Schedules\JobContext.cs" />
<Compile Include="Schedules\JobType.cs" />
<Compile Include="Schedules\LogJob.cs" />
<Compile Include="Schedules\Runner.cs" />
<Compile Include="Schedules\Scheduler.cs" />
Expand Down
2 changes: 1 addition & 1 deletion GitCandy/Schedules/IJob.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ public interface IJob
{
void Execute(JobContext jobContext);
TimeSpan GetNextInterval(JobContext jobContext);
TimeSpan Due { get; }
JobType JobType { get; }
}
}
8 changes: 8 additions & 0 deletions GitCandy/Schedules/JobType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace GitCandy.Schedules
{
public enum JobType
{
RealTime,
LongRunning,
}
}
6 changes: 3 additions & 3 deletions GitCandy/Schedules/LogJob.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ public class LogJob : IJob
{
public void Execute(JobContext jobContext)
{
if (jobContext.ExecutionTimes != 0)
if (jobContext.ExecutionTimes > 1)
Logger.SetLogPath();
}

Expand All @@ -16,9 +16,9 @@ public TimeSpan GetNextInterval(JobContext jobContext)
return TimeSpan.FromSeconds(24 * 3600) - DateTime.Now.TimeOfDay;
}

public TimeSpan Due
public JobType JobType
{
get { return TimeSpan.FromSeconds(1.0); }
get { return JobType.RealTime; }
}
}
}
26 changes: 10 additions & 16 deletions GitCandy/Schedules/Runner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace GitCandy.Schedules
{
internal sealed class Runner
{
private readonly static int IntervalOfTask = Environment.ProcessorCount * 1000;
private readonly static int IntervalOfTask = 100;

private readonly object _syncRoot = new object();
private readonly Scheduler _scheduler;
Expand All @@ -17,10 +17,10 @@ internal sealed class Runner
private CancellationTokenSource _tokenSource;
private Task _task;

public Runner(Scheduler scheduler, RunnerType runnerType)
public Runner(Scheduler scheduler, JobType jobType)
{
_scheduler = scheduler;
RunnerType = runnerType;
JobType = jobType;
ID = Interlocked.Increment(ref _id);
}

Expand All @@ -39,7 +39,8 @@ public void Start()
}

public int ID { get; private set; }
public RunnerType RunnerType { get; private set; }
public JobType JobType { get; private set; }
public DateTime LastExecution { get; private set; }

public void Stop()
{
Expand All @@ -64,7 +65,7 @@ private void RunnerLoop()
if (_tokenSource.IsCancellationRequested)
break;

var context = _scheduler.GetNextJobContext(RunnerType);
var context = _scheduler.GetNextJobContext(JobType);
if (context != null)
{
var jobName = context.Job.GetType().FullName;
Expand All @@ -73,6 +74,8 @@ private void RunnerLoop()
try
{
var utcStart = DateTime.UtcNow;
LastExecution = utcStart;

context.UtcStart = utcStart;

context.OnExecuting(this, context);
Expand All @@ -95,21 +98,12 @@ private void RunnerLoop()
}
context.Scheduler.JobExecuted(context);
}

if (_tokenSource.IsCancellationRequested)
break;

Task.Delay(IntervalOfTask).Wait();
else
Task.Delay(IntervalOfTask).Wait();
}

_tokenSource = null;
Logger.Info("Exit schedule runner #{0} loop", ID);
}
}

internal enum RunnerType
{
RealTime,
LongRunning,
}
}
28 changes: 12 additions & 16 deletions GitCandy/Schedules/Scheduler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,11 @@ namespace GitCandy.Schedules
{
public sealed class Scheduler
{
const double RealTimeDuration = 3.0;

private readonly static Scheduler _instance = new Scheduler();

private readonly object _syncRoot = new object();
private readonly LinkedList<JobContext> _jobs = new LinkedList<JobContext>();
private readonly Runner[] _runners;
internal readonly LinkedList<JobContext> _jobs = new LinkedList<JobContext>();
internal readonly Runner[] _runners;

public static Scheduler Instance { get { return _instance; } }

Expand All @@ -22,7 +20,7 @@ public Scheduler()
var div = Math.Min(_runners.Length / 4, 3);
for (int i = 0; i < _runners.Length; i++)
{
_runners[i] = new Runner(this, i < div ? RunnerType.RealTime : RunnerType.LongRunning);
_runners[i] = new Runner(this, i < div ? JobType.RealTime : JobType.LongRunning);
}
}

Expand All @@ -40,7 +38,7 @@ public void StartAll()
for (int i = 0; i < _runners.Length; i++)
{
_runners[i].Start();
Logger.Info("Schedule runner #{0} {1} started", _runners[i].ID, _runners[i].RunnerType);
Logger.Info("Schedule runner #{0} {1} started", _runners[i].ID, _runners[i].JobType);
}
}

Expand Down Expand Up @@ -80,8 +78,7 @@ private void InsertJobContext(JobContext context)
var node = _jobs.First;
while (node != null)
{
if ((node.Previous == null || context.UtcNextExecution <= context.UtcNextExecution)
&& context.UtcNextExecution < node.Value.UtcNextExecution)
if (context.UtcNextExecution < node.Value.UtcNextExecution)
{
_jobs.AddBefore(node, context);
break;
Expand All @@ -93,21 +90,20 @@ private void InsertJobContext(JobContext context)
}
}

internal JobContext GetNextJobContext(RunnerType runnerType)
internal JobContext GetNextJobContext(JobType jobType)
{
lock (_syncRoot)
{
var utcNow = DateTime.UtcNow;
var node = _jobs.First;
while (node != null)

while (node != null && utcNow >= node.Value.UtcNextExecution)
{
var context = node.Value;
var due = context.Job.Due.Seconds;
if (DateTime.UtcNow >= context.UtcNextExecution
&& (runnerType == RunnerType.RealTime && due < RealTimeDuration
|| runnerType == RunnerType.LongRunning))
if (jobType == JobType.RealTime && node.Value.Job.JobType == JobType.RealTime
|| jobType == JobType.LongRunning)
{
_jobs.Remove(node);
return context;
return node.Value;
}

node = node.Next;
Expand Down
16 changes: 8 additions & 8 deletions GitCandy/Schedules/SingleJob.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,27 @@ namespace GitCandy.Schedules
public class SingleJob : IJob
{
private Task _task;
private double _secondDue;
private JobType _jobType;

[ImportingConstructor]
public SingleJob()
: this(() => { }, 1.0)
: this(() => { }, JobType.RealTime)
{ }

public SingleJob(Action action, double secondDue = 4.0)
public SingleJob(Action action, JobType jobType = JobType.LongRunning)
{
Contract.Requires(action != null);

_task = new Task(action);
_secondDue = secondDue;
_jobType = jobType;
}

public SingleJob(Task task, double secondDue = 4.0)
public SingleJob(Task task, JobType jobType = JobType.LongRunning)
{
Contract.Requires(task != null);

_task = task;
_secondDue = secondDue;
_jobType = jobType;
}

public void Execute(JobContext jobContext)
Expand All @@ -42,9 +42,9 @@ public TimeSpan GetNextInterval(JobContext jobContext)
return TimeSpan.MaxValue;
}

public TimeSpan Due
public JobType JobType
{
get { return TimeSpan.FromSeconds(_secondDue); }
get { return _jobType; }
}
}
}

0 comments on commit b0f2aa7

Please sign in to comment.