Skip to content

Commit d5b1d2d

Browse files
committed
Add some scheduling helper methods and update docs
1 parent a231252 commit d5b1d2d

File tree

7 files changed

+179
-30
lines changed

7 files changed

+179
-30
lines changed

docs-src/scheduling.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,62 @@
22

33
[Commands](commands) can be scheduled to run by leveraging the InEngineScheduler.exe program, available as a download from a recent [release](https://github.com/InEngine-NET/InEngine.NET/releases).
44

5+
## Scheduling a Command
6+
7+
A job schedule is created by adding a class to your plugin assembly that implements the **InEngine.Core.Jobs** interface.
8+
9+
```csharp
10+
11+
using System;
12+
using Quartz;
13+
14+
namespace MyCommandPlugin
15+
{
16+
public class Jobs : IJobs
17+
{
18+
public void Schedule(IScheduler scheduler)
19+
{
20+
// Schedule some jobs
21+
}
22+
}
23+
}
24+
```
25+
26+
This class is automatically discovered by the InEngine.NET scheduler.
27+
It will call the Jobs.Schedule method with an initialized Quartz.NET scheduler object.
28+
29+
```csharp
30+
using System;
31+
using Quartz;
32+
using InEngine.Core.Queue.Commands;
33+
using System.Collections.Generic;
34+
using System.Linq;
35+
36+
namespace InEngine.Core.Queue
37+
{
38+
public class Jobs : IJobs
39+
{
40+
public void Schedule(IScheduler scheduler)
41+
{
42+
var myCommand = new MyCommand();
43+
44+
// Generate a schedulable job with the command
45+
var job = myCommand.MakeTriggerBuilder().Build();
46+
47+
// Generate a trigger for the job, and set its schedule to every 10 seconds.
48+
var trigger = myCommand.MakeTriggerBuilder().Build()
49+
.StartNow()
50+
.WithSimpleSchedule(x => x.WithIntervalInSeconds(10).RepeatForever())
51+
.Build();
52+
53+
// Register the job and trigger with the scheduler
54+
scheduler.ScheduleJob(job, trigger);
55+
}
56+
}
57+
}
58+
59+
```
60+
561
## Running the Scheduler
662

763
### Manually from the CLI

docs/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,5 +146,5 @@ <h4 class="modal-title" id="exampleModalLabel">Search</h4>
146146

147147
<!--
148148
MkDocs version : 0.16.3
149-
Build Date UTC : 2017-11-21 12:28:19
149+
Build Date UTC : 2017-11-21 14:06:37
150150
-->

docs/mkdocs/search_index.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,19 @@
6262
},
6363
{
6464
"location": "/scheduling/",
65-
"text": "Scheduling\n\n\nCommands\n can be scheduled to run by leveraging the InEngineScheduler.exe program, available as a download from a recent \nrelease\n.\n\n\nRunning the Scheduler\n\n\nManually from the CLI\n\n\nRunning the scheduler from the CommandLine is useful for debugging or local development. Simply run \nInEngineScheduler.exe\n from the command line.\n\n\nInEngineScheduler.exe\n\n\n\n\nIt can also be run on Mac/Linux with Mono.\n\n\nmono InEngineScheduler.exe\n\n\n\n\nOn Windows as a Service\n\n\nInstalling\n\n\nRun the Install.ps1 PowerShell script in the scheduler directory to install the scheduler in place. The script needs to be run as an administrator. The script will register the service at the location where the script is run. \n\n\nps Install.ps1\n\n\n\n\nUninstalling\n\n\nSimply run the \nUninstall.ps1\n script with elevated permissions to unregister the service.\n\n\nps Uninstall.ps1\n\n\n\n\nOn Linux with Supervisor\n\n\nSupervisor is a process control system for Linux. It has extensive \ndocumentation\n, but the following should be enough to get started.\n\n\nInstalling Supervisor\n\n\nThis command installs Supervisor on Ubuntu:\n\n\nsudo apt-get install supervisor\n\n\n\n\nConfiguring Supervisor\n\n\nSupervisor configuration files are stored in the \n/etc/supervisor/conf.d\n directory. Multiple files can be created in this directory to specify different programs, or multiple instances of the same program, for Supervisor to monitor. Copy this sample config into a file called \n/etc/supervisor/conf.d/inengine-scheduler.conf\n. \n\n\n[program:inengine-scheudler]\nprocess_name=%(program_name)s_%(process_num)02d\ndirectory=/path/to/scheduler\ncommand=mono InEngineScheduler.exe\nautostart=true\nautorestart=true\nuser=InEngine\nnumprocs=1\nredirect_stderr=true\nstdout_logfile=./scheduler.log\n\n\n\n\nStarting Supervisor\n\n\nWhenever a configuration change happens to files in the Supervisor config files, Supervisor needs to be instructed to reload its configuration.\n\n\nsudo supervisorctl reread\nsudo supervisorctl update\n\n\n\n\nNow, simply start the InEngine Scheduler.\n\n\nsudo supervisorctl start inengine-scheduler:*",
65+
"text": "Scheduling\n\n\nCommands\n can be scheduled to run by leveraging the InEngineScheduler.exe program, available as a download from a recent \nrelease\n.\n\n\nScheduling a Command\n\n\nA job schedule is created by adding a class to your plugin assembly that implements the \nInEngine.Core.Jobs\n interface.\n\n\n\nusing System;\nusing Quartz;\n\nnamespace MyCommandPlugin\n{\n public class Jobs : IJobs\n {\n public void Schedule(IScheduler scheduler)\n {\n // Schedule some jobs\n }\n }\n}\n\n\n\n\nThis class is automatically discovered by the InEngine.NET scheduler.\nIt will call the Jobs.Schedule method with an initialized Quartz.NET scheduler object.\n\n\nusing System;\nusing Quartz;\nusing InEngine.Core.Queue.Commands;\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace InEngine.Core.Queue\n{\n public class Jobs : IJobs\n {\n public void Schedule(IScheduler scheduler)\n {\n var myCommand = new MyCommand();\n\n // Generate a schedulable job with the command\n var job = myCommand.MakeTriggerBuilder().Build();\n\n // Generate a trigger for the job, and set its schedule to every 10 seconds.\n var trigger = myCommand.MakeTriggerBuilder().Build()\n .StartNow()\n .WithSimpleSchedule(x =\n x.WithIntervalInSeconds(10).RepeatForever())\n .Build();\n\n // Register the job and trigger with the scheduler\n scheduler.ScheduleJob(job, trigger);\n }\n }\n}\n\n\n\n\n\nRunning the Scheduler\n\n\nManually from the CLI\n\n\nRunning the scheduler from the CommandLine is useful for debugging or local development. Simply run \nInEngineScheduler.exe\n from the command line.\n\n\nInEngineScheduler.exe\n\n\n\n\nIt can also be run on Mac/Linux with Mono.\n\n\nmono InEngineScheduler.exe\n\n\n\n\nOn Windows as a Service\n\n\nInstalling\n\n\nRun the Install.ps1 PowerShell script in the scheduler directory to install the scheduler in place. The script needs to be run as an administrator. The script will register the service at the location where the script is run. \n\n\nps Install.ps1\n\n\n\n\nUninstalling\n\n\nSimply run the \nUninstall.ps1\n script with elevated permissions to unregister the service.\n\n\nps Uninstall.ps1\n\n\n\n\nOn Linux with Supervisor\n\n\nSupervisor is a process control system for Linux. It has extensive \ndocumentation\n, but the following should be enough to get started.\n\n\nInstalling Supervisor\n\n\nThis command installs Supervisor on Ubuntu:\n\n\nsudo apt-get install supervisor\n\n\n\n\nConfiguring Supervisor\n\n\nSupervisor configuration files are stored in the \n/etc/supervisor/conf.d\n directory. Multiple files can be created in this directory to specify different programs, or multiple instances of the same program, for Supervisor to monitor. Copy this sample config into a file called \n/etc/supervisor/conf.d/inengine-scheduler.conf\n. \n\n\n[program:inengine-scheudler]\nprocess_name=%(program_name)s_%(process_num)02d\ndirectory=/path/to/scheduler\ncommand=mono InEngineScheduler.exe\nautostart=true\nautorestart=true\nuser=InEngine\nnumprocs=1\nredirect_stderr=true\nstdout_logfile=./scheduler.log\n\n\n\n\nStarting Supervisor\n\n\nWhenever a configuration change happens to files in the Supervisor config files, Supervisor needs to be instructed to reload its configuration.\n\n\nsudo supervisorctl reread\nsudo supervisorctl update\n\n\n\n\nNow, simply start the InEngine Scheduler.\n\n\nsudo supervisorctl start inengine-scheduler:*",
6666
"title": "Scheduling"
6767
},
6868
{
6969
"location": "/scheduling/#scheduling",
7070
"text": "Commands can be scheduled to run by leveraging the InEngineScheduler.exe program, available as a download from a recent release .",
7171
"title": "Scheduling"
7272
},
73+
{
74+
"location": "/scheduling/#scheduling-a-command",
75+
"text": "A job schedule is created by adding a class to your plugin assembly that implements the InEngine.Core.Jobs interface. \nusing System;\nusing Quartz;\n\nnamespace MyCommandPlugin\n{\n public class Jobs : IJobs\n {\n public void Schedule(IScheduler scheduler)\n {\n // Schedule some jobs\n }\n }\n} This class is automatically discovered by the InEngine.NET scheduler.\nIt will call the Jobs.Schedule method with an initialized Quartz.NET scheduler object. using System;\nusing Quartz;\nusing InEngine.Core.Queue.Commands;\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace InEngine.Core.Queue\n{\n public class Jobs : IJobs\n {\n public void Schedule(IScheduler scheduler)\n {\n var myCommand = new MyCommand();\n\n // Generate a schedulable job with the command\n var job = myCommand.MakeTriggerBuilder().Build();\n\n // Generate a trigger for the job, and set its schedule to every 10 seconds.\n var trigger = myCommand.MakeTriggerBuilder().Build()\n .StartNow()\n .WithSimpleSchedule(x = x.WithIntervalInSeconds(10).RepeatForever())\n .Build();\n\n // Register the job and trigger with the scheduler\n scheduler.ScheduleJob(job, trigger);\n }\n }\n}",
76+
"title": "Scheduling a Command"
77+
},
7378
{
7479
"location": "/scheduling/#running-the-scheduler",
7580
"text": "",

docs/scheduling/index.html

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,13 +98,65 @@
9898
<div class="col-md-3"><div class="bs-sidebar hidden-print affix well" role="complementary">
9999
<ul class="nav bs-sidenav">
100100
<li class="main active"><a href="#scheduling">Scheduling</a></li>
101+
<li><a href="#scheduling-a-command">Scheduling a Command</a></li>
101102
<li><a href="#running-the-scheduler">Running the Scheduler</a></li>
102103
</ul>
103104
</div></div>
104105
<div class="col-md-9" role="main">
105106

106107
<h1 id="scheduling">Scheduling</h1>
107108
<p><a href="../commands">Commands</a> can be scheduled to run by leveraging the InEngineScheduler.exe program, available as a download from a recent <a href="https://github.com/InEngine-NET/InEngine.NET/releases">release</a>.</p>
109+
<h2 id="scheduling-a-command">Scheduling a Command</h2>
110+
<p>A job schedule is created by adding a class to your plugin assembly that implements the <strong>InEngine.Core.Jobs</strong> interface.</p>
111+
<pre><code class="csharp">
112+
using System;
113+
using Quartz;
114+
115+
namespace MyCommandPlugin
116+
{
117+
public class Jobs : IJobs
118+
{
119+
public void Schedule(IScheduler scheduler)
120+
{
121+
// Schedule some jobs
122+
}
123+
}
124+
}
125+
</code></pre>
126+
127+
<p>This class is automatically discovered by the InEngine.NET scheduler.
128+
It will call the Jobs.Schedule method with an initialized Quartz.NET scheduler object.</p>
129+
<pre><code class="csharp">using System;
130+
using Quartz;
131+
using InEngine.Core.Queue.Commands;
132+
using System.Collections.Generic;
133+
using System.Linq;
134+
135+
namespace InEngine.Core.Queue
136+
{
137+
public class Jobs : IJobs
138+
{
139+
public void Schedule(IScheduler scheduler)
140+
{
141+
var myCommand = new MyCommand();
142+
143+
// Generate a schedulable job with the command
144+
var job = myCommand.MakeTriggerBuilder().Build();
145+
146+
// Generate a trigger for the job, and set its schedule to every 10 seconds.
147+
var trigger = myCommand.MakeTriggerBuilder().Build()
148+
.StartNow()
149+
.WithSimpleSchedule(x =&gt; x.WithIntervalInSeconds(10).RepeatForever())
150+
.Build();
151+
152+
// Register the job and trigger with the scheduler
153+
scheduler.ScheduleJob(job, trigger);
154+
}
155+
}
156+
}
157+
158+
</code></pre>
159+
108160
<h2 id="running-the-scheduler">Running the Scheduler</h2>
109161
<h3 id="manually-from-the-cli">Manually from the CLI</h3>
110162
<p>Running the scheduler from the CommandLine is useful for debugging or local development. Simply run <em>InEngineScheduler.exe</em> from the command line.</p>

src/InEngine.Core/AbstractCommand.cs

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using Konsole;
1+
using System;
2+
using Konsole;
23
using NLog;
34
using Quartz;
45

@@ -19,27 +20,34 @@ public string Name
1920
Logger = LogManager.GetLogger(_name);
2021
}
2122
}
23+
public string SchedulerGroup { get; set; }
24+
public string ScheduleId { get; set; }
2225

2326
protected AbstractCommand()
2427
{
28+
ScheduleId = Guid.NewGuid().ToString();
2529
Name = GetType().FullName;
30+
SchedulerGroup = GetType().AssemblyQualifiedName;
2631
}
2732

2833
public virtual CommandResult Run()
2934
{
30-
throw new System.NotImplementedException();
35+
throw new NotImplementedException();
3136
}
3237

38+
#region ProgressBar
3339
public void SetProgressBarMaxTicks(int maxTicks)
3440
{
3541
ProgressBar = new ProgressBar(maxTicks);
3642
}
3743

3844
public void UpdateProgress(int tick)
3945
{
40-
ProgressBar.Refresh(tick, Name);
46+
ProgressBar.Refresh(tick, Name);
4147
}
48+
#endregion
4249

50+
#region Scheduling
4351
public void Execute(IJobExecutionContext context)
4452
{
4553
JobExecutionContext = context;
@@ -51,7 +59,22 @@ public T GetJobContextData<T>(string key)
5159
if (JobExecutionContext == null || JobExecutionContext.MergedJobDataMap == null)
5260
return default(T);
5361
var objectVal = JobExecutionContext.MergedJobDataMap.Get(key);
54-
return objectVal == null ? default(T) : (T)objectVal;
62+
return objectVal == null ? default(T) : (T)objectVal;
5563
}
64+
65+
public JobBuilder MakeJobBuilder()
66+
{
67+
return JobBuilder
68+
.Create(GetType())
69+
.WithIdentity($"{Name}:job:{ScheduleId}", SchedulerGroup);
70+
}
71+
72+
public TriggerBuilder MakeTriggerBuilder()
73+
{
74+
return TriggerBuilder
75+
.Create()
76+
.WithIdentity($"{Name}:trigger:{ScheduleId}", SchedulerGroup);
77+
}
78+
#endregion
5679
}
5780
}

src/InEngine.Core/Queue/Jobs.cs

Lines changed: 37 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -10,36 +10,50 @@ public class Jobs : IJobs
1010
{
1111
public void Schedule(IScheduler scheduler)
1212
{
13-
var consume = new Consume();
14-
foreach (var index in Enumerable.Range(0, 8).ToList())
15-
{
16-
var primaryQueueConsumer = JobBuilder
17-
.Create<Consume>()
18-
.WithIdentity(consume.Name + index, "primaryQueueConsumer")
19-
.Build();
13+
ScheduleQueueConsumerJobs(scheduler);
14+
ScheduleQueueConsumerJobs(scheduler, true);
15+
//foreach (var index in Enumerable.Range(0, 8).ToList())
16+
//{
17+
// var consume = new Consume();
18+
// consume.Name = consume.Name + index;
19+
// var primaryQueueConsumer = consume.MakeJobBuilder().Build();
20+
// var secondaryQueueConsumer = consume.MakeJobBuilder().Build();
21+
// secondaryQueueConsumer.JobDataMap.Add("useSecondaryQueue", true);
2022

21-
var secondaryQueueConsumer = JobBuilder
22-
.Create<Consume>()
23-
.WithIdentity(consume.Name + index, "secondaryQueueConsumer")
24-
.Build();
25-
secondaryQueueConsumer.JobDataMap.Add("useSecondaryQueue", true);
23+
// var primaryTrigger = consume
24+
// .MakeTriggerBuilder()
25+
// .StartNow()
26+
// .WithSimpleSchedule(x => x.WithIntervalInSeconds(1).RepeatForever())
27+
// .Build();
2628

27-
var primaryTrigger = TriggerBuilder
28-
.Create()
29-
.WithIdentity($"{consume.Name}-primary-{index}", "queue")
30-
.StartNow()
31-
.WithSimpleSchedule(x => x.WithIntervalInSeconds(1).RepeatForever())
32-
.Build();
29+
// var secondaryTrigger = consume
30+
// .MakeTriggerBuilder()
31+
// .StartNow()
32+
// .WithSimpleSchedule(x => x.WithIntervalInSeconds(1).RepeatForever())
33+
// .Build();
34+
35+
// scheduler.ScheduleJob(primaryQueueConsumer, primaryTrigger);
36+
// scheduler.ScheduleJob(secondaryQueueConsumer, secondaryTrigger);
37+
//}
38+
}
39+
40+
private void ScheduleQueueConsumerJobs(IScheduler scheduler, bool useSecondaryQueue = false)
41+
{
42+
foreach (var index in Enumerable.Range(0, 8).ToList())
43+
{
44+
var consume = new Consume() {
45+
ScheduleId = $"{(useSecondaryQueue ? "secondary" : "primary")}:{index.ToString()}"
46+
};
47+
var job = consume.MakeJobBuilder().Build();
48+
job.JobDataMap.Add("useSecondaryQueue", useSecondaryQueue);
3349

34-
var secondaryTrigger = TriggerBuilder
35-
.Create()
36-
.WithIdentity($"{consume.Name}-secondary-{index}", "queue")
50+
var trigger = consume
51+
.MakeTriggerBuilder()
3752
.StartNow()
3853
.WithSimpleSchedule(x => x.WithIntervalInSeconds(1).RepeatForever())
3954
.Build();
4055

41-
scheduler.ScheduleJob(primaryQueueConsumer, primaryTrigger);
42-
scheduler.ScheduleJob(secondaryQueueConsumer, secondaryTrigger);
56+
scheduler.ScheduleJob(job, trigger);
4357
}
4458
}
4559
}

src/InEngineCli/ArgumentInterpreter.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using System;
22
using System.Linq;
3-
using System.Reflection;
43
using CommandLine;
54
using InEngine.Core;
65
using InEngine.Core.Exceptions;

0 commit comments

Comments
 (0)