Skip to content

Commit ff36624

Browse files
committed
Abstract away dependence on IScheduler
1 parent dcd3b33 commit ff36624

File tree

10 files changed

+189
-77
lines changed

10 files changed

+189
-77
lines changed

src/InEngine.Core/AbstractCommand.cs

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,15 @@
11
using System;
22
using InEngine.Core.IO;
33
using Konsole;
4-
using NLog;
54
using Quartz;
65

76
namespace InEngine.Core
87
{
98
abstract public class AbstractCommand : ICommand, IFailed, IJob, IWrite
109
{
1110
public IJobExecutionContext JobExecutionContext { get; set; }
12-
public ILogger Logger { get; internal set; }
1311
public ProgressBar ProgressBar { get; internal set; }
14-
string _name;
15-
public string Name
16-
{
17-
get { return _name; }
18-
set
19-
{
20-
_name = value;
21-
Logger = LogManager.GetLogger(_name);
22-
}
23-
}
12+
public string Name { get; set; }
2413
public string SchedulerGroup { get; set; }
2514
public string ScheduleId { get; set; }
2615
public Write Write { get; set; }
@@ -67,20 +56,6 @@ public void Execute(IJobExecutionContext context)
6756
}
6857
}
6958

70-
public JobBuilder MakeJobBuilder()
71-
{
72-
return JobBuilder
73-
.Create(GetType())
74-
.WithIdentity($"{Name}:job:{ScheduleId}", SchedulerGroup);
75-
}
76-
77-
public TriggerBuilder MakeTriggerBuilder()
78-
{
79-
return TriggerBuilder
80-
.Create()
81-
.WithIdentity($"{Name}:trigger:{ScheduleId}", SchedulerGroup);
82-
}
83-
8459
public T GetJobContextData<T>(string key)
8560
{
8661
if (JobExecutionContext == null || JobExecutionContext.MergedJobDataMap == null)

src/InEngine.Core/Commands/SystemProcess.cs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,17 +31,14 @@ public override void Run()
3131
}
3232
};
3333
var commandWithArguments = $"{Command} {Arguments}";
34-
Logger.Debug($"Starting process for command: {commandWithArguments}");
3534
process.Start();
36-
Logger.Debug($"Command ({commandWithArguments}) started with process ID {process.Id}.");
3735
if (process.WaitForExit(Timeout * 1000)) {
38-
Logger.Debug($"Process for command {commandWithArguments} with PID {process.Id} ended with exit code {process.ExitCode}.");
3936
return;
4037
}
41-
Logger.Debug($"The command ({commandWithArguments}) has timed out and is about to be killed...");
38+
Error($"The command ({commandWithArguments}) has timed out and is about to be killed...");
4239
process.Kill();
43-
Logger.Debug($"The command ({commandWithArguments}) has been killed.");
44-
throw new CommandFailedException($"The command timed out after {Timeout} second(s).");
40+
Error($"The command ({commandWithArguments}) has been killed.");
41+
throw new CommandFailedException($"The command ({commandWithArguments}) timed out after {Timeout} second(s).");
4542
}
4643
}
4744
}

src/InEngine.Core/IJobs.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
using Quartz;
1+
using InEngine.Core.Scheduling;
22

33
namespace InEngine.Core
44
{
55
public interface IJobs : IPluginType
66
{
7-
void Schedule(IScheduler scheduler);
7+
void Schedule(Schedule schedule);
88
}
99
}

src/InEngine.Core/InEngine.Core.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,8 @@
2727
<PackageReference Include="StackExchange.Redis" Version="1.2.4" />
2828
<PackageReference Include="Goblinfactory.Konsole" Version="3.1.0" />
2929
</ItemGroup>
30+
<ItemGroup>
31+
<Folder Include="Scheduling\" />
32+
</ItemGroup>
3033
</Project>
3134

src/InEngine.Core/Plugin.cs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
using System.Reflection;
66
using CommandLine;
77
using InEngine.Core.Exceptions;
8-
using NLog;
98

109
namespace InEngine.Core
1110
{
@@ -45,16 +44,13 @@ public List<T> Make<T>() where T : class, IPluginType
4544
public static List<Plugin> Load<T>() where T : IPluginType
4645
{
4746
var pluginList = new List<Plugin>();
48-
var logger = LogManager.GetCurrentClassLogger();
49-
50-
logger.Debug("Loading core plugin...");
5147
try
5248
{
5349
pluginList.Add(new Plugin(Assembly.GetExecutingAssembly()));
5450
}
5551
catch (Exception exception)
5652
{
57-
logger.Error(exception, "Error loading InEngine.Core plugin.");
53+
throw new PluginNotFoundException("Could not load InEngine.Core plugin.", exception);
5854
}
5955

6056
var assemblies = InEngineSettings
@@ -70,7 +66,7 @@ public static List<Plugin> Load<T>() where T : IPluginType
7066
}
7167
catch (Exception exception)
7268
{
73-
logger.Error(exception, "Error loading plugins.");
69+
throw new PluginNotFoundException($"Could not load {assembly.GetName().Name} plugin.", exception);
7470
}
7571
}
7672
if (!pluginList.Any())

src/InEngine.Core/Queue/Jobs.cs

Lines changed: 12 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,29 @@
11
using System;
2-
using Quartz;
3-
using InEngine.Core.Queue.Commands;
4-
using System.Collections.Generic;
52
using System.Linq;
3+
using InEngine.Core.Queue.Commands;
4+
using InEngine.Core.Scheduling;
65

76
namespace InEngine.Core.Queue
87
{
98
public class Jobs : IJobs
109
{
11-
public void Schedule(IScheduler scheduler)
10+
public void Schedule(Schedule schedule)
1211
{
1312
var queueSettings = InEngineSettings.Make().Queue;
14-
ScheduleQueueConsumerJobs(scheduler, queueSettings.PrimaryQueueConsumers);
15-
ScheduleQueueConsumerJobs(scheduler, queueSettings.SecondaryQueueConsumers, true);
13+
ScheduleQueueConsumerJobs(schedule, queueSettings.PrimaryQueueConsumers);
14+
ScheduleQueueConsumerJobs(schedule, queueSettings.SecondaryQueueConsumers, true);
1615
}
1716

18-
private void ScheduleQueueConsumerJobs(IScheduler scheduler, int consumers, bool useSecondaryQueue = false)
17+
private void ScheduleQueueConsumerJobs(Schedule schedule, int consumers, bool useSecondaryQueue = false)
1918
{
20-
if (consumers < 0) {
19+
if (consumers < 0)
2120
throw new ArgumentOutOfRangeException(nameof(consumers), consumers, "The number of queue consumers must be 0 or greater.");
22-
}
23-
foreach (var index in Enumerable.Range(0, consumers).ToList())
24-
{
25-
var consume = new Consume() {
26-
ScheduleId = $"{(useSecondaryQueue ? "secondary" : "primary")}:{index.ToString()}"
27-
};
2821

29-
var job = consume.MakeJobBuilder().Build();
30-
job.JobDataMap.Add("useSecondaryQueue", useSecondaryQueue);
31-
32-
var trigger = consume
33-
.MakeTriggerBuilder()
34-
.StartNow()
35-
.WithSimpleSchedule(x => x.WithIntervalInSeconds(1).RepeatForever())
36-
.Build();
37-
38-
scheduler.ScheduleJob(job, trigger);
39-
}
22+
foreach (var index in Enumerable.Range(0, consumers).ToList())
23+
schedule.Job(new Consume() {
24+
ScheduleId = $"{(useSecondaryQueue ? "secondary" : "primary")}:{index.ToString()}",
25+
UseSecondaryQueue = useSecondaryQueue
26+
}).EverySecond();
4027
}
4128
}
4229
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
using System;
2+
using Quartz;
3+
using Quartz.Impl;
4+
5+
namespace InEngine.Core.Scheduling
6+
{
7+
public class Recurrence
8+
{
9+
public IScheduler Scheduler { get; set; } = StdSchedulerFactory.GetDefaultScheduler();
10+
public AbstractCommand Command { get; set; }
11+
public IJobDetail JobDetail { get; set; }
12+
13+
public TriggerBuilder MakeTriggerBuilder(AbstractCommand command)
14+
{
15+
return TriggerBuilder
16+
.Create()
17+
.WithIdentity($"{command.Name}:job:{command.ScheduleId}", command.SchedulerGroup);
18+
}
19+
20+
public void EverySecond()
21+
{
22+
var trigger = MakeTriggerBuilder(Command)
23+
.StartNow()
24+
.WithSimpleSchedule(x => x.WithIntervalInSeconds(1).RepeatForever())
25+
.Build();
26+
Scheduler.ScheduleJob(JobDetail, trigger);
27+
}
28+
29+
public void EveryMinute()
30+
{
31+
var trigger = MakeTriggerBuilder(Command)
32+
.StartNow()
33+
.WithSimpleSchedule(x => x.WithIntervalInMinutes(1).RepeatForever())
34+
.Build();
35+
Scheduler.ScheduleJob(JobDetail, trigger);
36+
}
37+
38+
public void EveryFiveMinutes()
39+
{
40+
var trigger = MakeTriggerBuilder(Command)
41+
.StartNow()
42+
.WithSimpleSchedule(x => x.WithIntervalInMinutes(5).RepeatForever())
43+
.Build();
44+
Scheduler.ScheduleJob(JobDetail, trigger);
45+
}
46+
47+
public void EveryTenMinutes()
48+
{
49+
var trigger = MakeTriggerBuilder(Command)
50+
.StartNow()
51+
.WithSimpleSchedule(x => x.WithIntervalInMinutes(10).RepeatForever())
52+
.Build();
53+
Scheduler.ScheduleJob(JobDetail, trigger);
54+
}
55+
56+
public void EveryFifteenMinutes()
57+
{
58+
var trigger = MakeTriggerBuilder(Command)
59+
.StartNow()
60+
.WithSimpleSchedule(x => x.WithIntervalInMinutes(15).RepeatForever())
61+
.Build();
62+
Scheduler.ScheduleJob(JobDetail, trigger);
63+
}
64+
65+
public void EveryThirtyMinutes()
66+
{
67+
var trigger = MakeTriggerBuilder(Command)
68+
.StartNow()
69+
.WithSimpleSchedule(x => x.WithIntervalInMinutes(30).RepeatForever())
70+
.Build();
71+
Scheduler.ScheduleJob(JobDetail, trigger);
72+
}
73+
74+
public void Hourly()
75+
{
76+
var trigger = MakeTriggerBuilder(Command)
77+
.StartNow()
78+
.WithSimpleSchedule(x => x.WithIntervalInHours(1).RepeatForever())
79+
.Build();
80+
Scheduler.ScheduleJob(JobDetail, trigger);
81+
}
82+
83+
public void HourlyAt(int minutesAfterTheHour)
84+
{
85+
var trigger = MakeTriggerBuilder(Command)
86+
.StartNow()
87+
.WithCronSchedule($"0 {minutesAfterTheHour} * * * ?")
88+
.Build();
89+
Scheduler.ScheduleJob(JobDetail, trigger);
90+
}
91+
92+
public void Daily()
93+
{
94+
var trigger = MakeTriggerBuilder(Command)
95+
.StartNow()
96+
.WithSimpleSchedule(x => x.WithIntervalInHours(24).RepeatForever())
97+
.Build();
98+
Scheduler.ScheduleJob(JobDetail, trigger);
99+
}
100+
101+
public void DailyAt(TimeOfDay timeOfDay)
102+
{
103+
var trigger = MakeTriggerBuilder(Command)
104+
.StartNow()
105+
.WithDailyTimeIntervalSchedule(x => x.StartingDailyAt(timeOfDay))
106+
.Build();
107+
Scheduler.ScheduleJob(JobDetail, trigger);
108+
}
109+
}
110+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
using System;
2+
using System.Linq;
3+
using Quartz;
4+
using Quartz.Impl;
5+
6+
namespace InEngine.Core.Scheduling
7+
{
8+
public class Schedule
9+
{
10+
public IScheduler Scheduler { get; set; } = StdSchedulerFactory.GetDefaultScheduler();
11+
12+
public Recurrence Job(AbstractCommand command)
13+
{
14+
var jobDetail = MakeJobBuilder(command).Build();
15+
16+
command.GetType()
17+
.GetProperties()
18+
.ToList()
19+
.ForEach(x => jobDetail.JobDataMap.Add(x.Name, x.GetValue(command)));
20+
21+
return new Recurrence() {
22+
JobDetail = jobDetail,
23+
Command = command
24+
};
25+
}
26+
27+
public void Start()
28+
{
29+
Scheduler.Start();
30+
}
31+
32+
public void Shutdown()
33+
{
34+
if (Scheduler.IsStarted)
35+
Scheduler.Shutdown();
36+
}
37+
38+
public JobBuilder MakeJobBuilder(AbstractCommand command)
39+
{
40+
return JobBuilder
41+
.Create(command.GetType())
42+
.WithIdentity($"{command.Name}:job:{command.ScheduleId}", command.SchedulerGroup);
43+
}
44+
}
45+
}

src/InEngine/Jobs.cs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,17 @@
1-
using System;
2-
using InEngine.Core;
3-
using Quartz;
1+
using InEngine.Core;
2+
using InEngine.Core.Scheduling;
43
using NLog;
54

6-
75
namespace InEngine
86
{
97
public static class Jobs
108
{
11-
public static void Schedule(IScheduler scheduler)
9+
public static void Schedule(Schedule schedule)
1210
{
1311
var logger = LogManager.GetCurrentClassLogger();
1412
Plugin.Load<IJobs>().ForEach(x => {
1513
logger.Info($"Registering jobs from plugin: {x.Name}");
16-
x.Make<IJobs>().ForEach(y => y.Schedule(scheduler));
14+
x.Make<IJobs>().ForEach(y => y.Schedule(schedule));
1715
});
1816
}
1917
}

src/InEngine/ServerHost.cs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,30 @@
11
using System;
2+
using InEngine.Core.Scheduling;
23
using Quartz;
34
using Quartz.Impl;
45

56
namespace InEngine
67
{
78
public class ServerHost : IDisposable
89
{
9-
public IScheduler Scheduler { get; set; }
10+
public Schedule Schedule { get; set; }
1011

1112
public ServerHost()
1213
{
13-
Scheduler = StdSchedulerFactory.GetDefaultScheduler();
14+
Schedule = new Schedule();
1415
Common.Logging.LogManager.Adapter = new Common.Logging.Simple.ConsoleOutLoggerFactoryAdapter { Level = Common.Logging.LogLevel.Info };
15-
Jobs.Schedule(Scheduler);
16+
Jobs.Schedule(Schedule);
1617
}
1718

1819
public void Dispose()
1920
{
20-
if (Scheduler != null && Scheduler.IsStarted)
21-
Scheduler.Shutdown();
21+
if (Schedule != null)
22+
Schedule.Shutdown();
2223
}
2324

2425
public void Start()
2526
{
26-
Scheduler.Start();
27+
Schedule.Start();
2728
}
2829
}
2930
}

0 commit comments

Comments
 (0)