Skip to content

Commit 975ba81

Browse files
committed
Update docs
1 parent 0e0b0fb commit 975ba81

File tree

2 files changed

+110
-52
lines changed

2 files changed

+110
-52
lines changed

docs-src/queuing.md

Lines changed: 96 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,19 @@
11
# Queuing
22

3-
InEngine.NET's queue functionality allows for commands to be run in the background with a simple publish/consume model.
3+
InEngine.NET's queue functionality allows for commands to be run in the background via a [publish/subscribe](https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern) model.
4+
A command should be queued when it is desirable to run the command once, as soon as possible, in a background task.
5+
6+
Queuing is especially important for Web site and applications.
7+
Queuing is like the sister technology of caching.
8+
Caching makes page loads faster when reading data from a database, or serving static assets, by drastically reducing direct database and file system read operations.
9+
Queuing makes page loads faster when writing data to a database, or performing other blocking tasks, by pushing them into the background.
10+
Some common examples are sending emails, importing CSV files into a database, transforming an image file, and processing a shopping cart order.
11+
It is not appropriate to use queuing if output from the task is needed immediately in the response of a Web request.
412

513
## Queue Drivers
614

715
To make use of queue features, a queue driver must be specified in [appsettings.json](configuration).
16+
817
These are the available drivers...
918

1019
### File
@@ -39,26 +48,38 @@ The sync driver causes the publish command to run a published command synchronou
3948
All other queue commands and methods are not supported and will throw an exception if called.
4049
This driver can be useful for plugin development and testing.
4150

42-
## Publishing Commands
51+
## Enqueuing Commands
4352

4453
### With C# Classes
4554

46-
[Commands](commands) can be published programmatically with the **InEngine.Core.Queuing.Queue** class:
55+
[Commands](commands) can be enqueued programmatically with the **InEngine.Core.Queuing.Enqueue** class:
4756

4857
```c#
49-
Queue.Make().Publish(new MyCommand());
58+
Enqueue.Command(new MyCommand())
59+
.Dispatch();
5060
```
5161

52-
Or publish to the secondary queue by passing true to the Make method:
62+
Or enqueue to the secondary queue:
5363

5464
```c#
55-
Queue.Make(true).Publish(new MyCommand());
65+
Enqueue.Command(new MyCommand())
66+
.ToSecondaryQueue()
67+
.Dispatch();
5668
```
5769

58-
!!! note "Do I have to use Queue.Make()?"
59-
Queue.Make() is a factory method that autoloads the queue settings from appsettings.json, creates the appropriate queue driver, and returns an instance of Queue.
60-
You can create your own Queue object an initialize it if you want.
61-
At the very least you can assign the object returned by Queue.Make() to a local variable or load it into a DI container for later use.
70+
Enqueue is just a wrapper.
71+
It is possible to peel back the covers to get to the queue client.
72+
```c#
73+
// Enqueue.Command actually returns a life cycle object...
74+
var commandToDispatch = Enqueue.Command(new MyCommand());
75+
76+
// The life cycle object has a QueueAdapter that can be set...
77+
var shouldUseSecondaryQueue = true;
78+
commandToDispatch.QueueAdapter = QueueAdapter.Make(shouldUseSecondaryQueue);
79+
80+
// Now dispatch the command...
81+
commandToDispatch.Dispatch();
82+
```
6283

6384
### With Lambda Expressions
6485

@@ -68,15 +89,8 @@ The disadvantage to queuing lambdas is that the helpful functionality available
6889
This is how you queue a lambda:
6990

7091
```c#
71-
Queue.Make().Publish(() => Console.WriteLine("Hello, world!"));
72-
```
73-
74-
Here is a neat shortcut for commands without parameters:
75-
76-
```c#
77-
Queue.Make().Publish(() => Foo.Bar());
78-
// Can be rewritten as...
79-
Queue.Make().Publish(Foo.Bar);
92+
Enqueue.Command(() => Console.WriteLine("Hello, world!"))
93+
.Dispatch();
8094
```
8195

8296
### Sequentially In a Chain
@@ -85,26 +99,58 @@ Chained commands run in the order specified.
8599
This is useful for when order matters.
86100

87101
Also, if one command in the chain fails, then subsequent commands are not run at all.
88-
This affords the opportunity to add additional code that records which command failed, then resuming the command chain where it left off.
102+
This affords the opportunity to add additional code that records which command failed to notify someone that manual intervention is necessary,
103+
or some other error handling functionality.
89104

90105
Here is a an example of how to chain a series of (imaginary) file transfer commands together:
91106

92107
```c#
93-
Subject.Publish(new[] {
94-
new MyFileTransfer(filePath1),
95-
new MyFileTransfer(filePath2),
96-
new MyFileTransfer(filePath3),
97-
});
108+
Enqueue.Command(new[] {
109+
new MyFileTransfer(filePath1),
110+
new MyFileTransfer(filePath2),
111+
new MyFileTransfer(filePath3),
112+
})
113+
.Dispatch();
98114
```
99115

116+
It is also possible to enqueue a list of different commands:
117+
118+
```c#
119+
Enqueue.Command(new List<AbstractCommand>() {
120+
new AlwaysSucceed(),
121+
new Echo() { VerbatimText = "Hello, world!"},
122+
})
123+
.Dispatch();
124+
```
125+
126+
### With Life Cycle Methods
127+
128+
Commands have optional life cycle methods that are initialized when a command is enqueued.
129+
This is similar to scheduling life cycle methods, but a queue does not have the **Before** and **After** method.
130+
It has the rest.
131+
132+
It is often useful to hit a URL before or after the command runs:
100133

101134
```c#
102-
Subject.Publish(new List<AbstractCommand>() {
103-
new AlwaysSucceed(),
104-
new Echo() { VerbatimText = "Hello, world!"},
105-
});
135+
Enqueue.Command(new Command())
136+
.EveryFiveMinutes()
137+
.PingBefore("http://example.com")
138+
.PingAfter("http://example.com");
106139
```
107140

141+
The **AbstractCommand** class has an instance of **InEngine.Core.IO.Write**.
142+
This class is more than just a wrapper for **Console.WriteLine**.
143+
144+
It also allows these life cycle methods to send the command's text output to files or an email:
145+
146+
```c#
147+
Enqueue.Command(new Command)
148+
.EveryFiveMinutes()
149+
.WriteOutputTo("/some/path")
150+
.AppendOutputTo("/some/path")
151+
.EmailOutputTo("example@inengine.net");
152+
```
153+
108154
### From the Command Line
109155

110156
Commands can be published from the command line as well.
@@ -129,24 +175,10 @@ inengine.exe -pInEngine.Core queue:publish --command-plugin=InEngine.Core.dll --
129175

130176
## Consuming Commands
131177

132-
### From Code
133-
Consuming a command is also accomplished with the Queue class:
134-
135-
```c#
136-
Queue.Make().Consume();
137-
```
138-
139-
The make method takes an optional second argument to indicate if the secondary queue should be used instead of the primary queue.
140-
141-
```c#
142-
// Uses secondary queue.
143-
Queue.Make(true).Consume();
144-
```
145-
146-
Commands can be consumed from the command line as well with this simple command:
147-
148178
### From the Command Line
149179

180+
Commands can be consumed from the command line with this simple command:
181+
150182
```bash
151183
inengine.exe -pInEngine.Core queue:consume
152184
```
@@ -162,6 +194,24 @@ inengine.exe -pInEngine.Core queue:consume --secondary
162194
The InEngine scheduler is needed to consume queued messages in the background.
163195
There are a variety of [ways to run the scheduler](scheduling/#running-the-scheduler).
164196

197+
### From Code
198+
199+
It should (probably) never be necessary to manually consume commands in code, but it is possible.
200+
201+
Consuming a command is accomplished with the **InEngine.Core.Queuing.Commands.Consume** class:
202+
203+
```c#
204+
new Consume().Run();
205+
```
206+
207+
Or consume the secondary queue:
208+
209+
```c#
210+
new Consume {
211+
UseSecondaryQueue = true
212+
}.Run();
213+
```
214+
165215
## Examining the Queue
166216

167217
### Viewing Queue Lengths
@@ -205,7 +255,7 @@ For example, this queue:peek call retrieves the 100-200 queued commands:
205255
inengine.exe -pInEngine.Core queue:peek --pending --from=100 --to=200
206256
```
207257

208-
## Handling Failed Commands
258+
## Re-queuing Failed Commands
209259

210260
Commands that throw an exception are put in a special "failed" queue.
211261
They can be republished with the **queue:republish** command:

docs-src/scheduling.md

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,17 @@
22

33
[Commands](commands) can be run at certain times on recurring schedules.
44

5+
Scheduled commands are different from queued commands.
6+
A command is queued when it is desirable to run the command once, as soon as possible.
7+
Queued commands are typically configured right before being dispatched.
8+
A command is scheduled when is it is desirable to run the command many times, on a definite schedule.
9+
10+
InEngine.NET takes a strictly programmatic approach to defining a schedule.
11+
A command schedule is defined in code, not in an external data store.
12+
There are several advantages to this approach.
13+
One advantage is that the schedule can be versioned alongside the command code.
14+
Another advantage is that there is no overhead from managing additional state in an external data store.
15+
516
## Scheduling a Command
617

718
A job schedule is created by adding a class to your plugin assembly that implements the **InEngine.Core.ICommandSchedule** interface.
@@ -121,7 +132,7 @@ Run a command daily at a specific time (at 10:30pm in this example):
121132
schedule.Command(new MyCommand()).DailyAt(22, 30);
122133
```
123134

124-
## Scheduling a Chain of Commands
135+
### In a Chain
125136

126137
A group of commands can be scheduled to run as an atomic batch.
127138

@@ -142,7 +153,7 @@ This is a good place to add special logic that will allow the command to be reco
142153
or to alert someone that manual intervention is necessary.
143154

144155

145-
## Life Cycle Methods
156+
### With Life Cycle Methods
146157

147158
Commands have optional life cycle methods that are initialized when a command is scheduled.
148159

@@ -239,17 +250,14 @@ It can also be run on Mac and Linux with Mono via a shell wrapper script:
239250

240251
### On Windows as a Service
241252

242-
#### Installing
243-
Run the Install.ps1 PowerShell script in the scheduler directory to install the scheduler in place.
253+
Run the **Install.ps1** PowerShell script in the scheduler directory to install the scheduler in place.
244254
The script needs to be run as an administrator.
245255
The script will register the service at the location where the script is run.
246256

247257
```bash
248258
ps Install.ps1
249259
```
250260

251-
#### Uninstalling
252-
253261
Simply run the **Uninstall.ps1** script with elevated permissions to remove the service.
254262

255263
```bash

0 commit comments

Comments
 (0)