jobly 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +98 -6
- data/lib/jobly.rb +1 -0
- data/lib/jobly/commands/worker.rb +25 -3
- data/lib/jobly/job.rb +46 -3
- data/lib/jobly/job_extensions/actions.rb +55 -0
- data/lib/jobly/job_extensions/option_accessors.rb +29 -0
- data/lib/jobly/refinements/convert_to_typed.rb +2 -0
- data/lib/jobly/refinements/keyword_args.rb +15 -0
- data/lib/jobly/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2e477c569a3ff769ded464f2d52e4775b254b348464057de68d3a63f2eec053c
|
4
|
+
data.tar.gz: 4bfdc207e0b541a52eb7e363cce13ed54635ed0b63e15e61ac5f2b17959ec98d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1a427c799068ede5b6a1b97b92f22d14cbc6569cd373d06168058e75f7b91a7cc3bb54e9a91774327ca557bef6c9de54af9e0f28bb7359db514ff7ef1f0bcad3
|
7
|
+
data.tar.gz: deacef64bbfa47d091134103d7450701a5dcdda4e9f5c21175c05969d17b9370552abc7f8e930a00d2271fc79669752e7aec0a5781d1c0e58cb59060b6fd6f82
|
data/README.md
CHANGED
@@ -15,20 +15,34 @@ Compact job server with API, CLI, Web UI and a Sidekiq heart.
|
|
15
15
|
|
16
16
|
---
|
17
17
|
|
18
|
+
<table><tr>
|
19
|
+
<td width='50%'><a target='_screenshot' href='/demo/terminal.gif'><img src='/demo/terminal.gif'/></a></td>
|
20
|
+
<td width='50%'><a target='_screenshot' href='/demo/screen.gif'><img src='/demo/screen.gif'/></a></td>
|
21
|
+
</tr></table>
|
22
|
+
|
23
|
+
---
|
24
|
+
|
18
25
|
* [Installation](#installation)
|
19
26
|
* [What's in the Box](#whats-in-the-box)
|
20
27
|
* [Quick Start](#quick-start)
|
21
28
|
* [Usage](#usage)
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
29
|
+
* [Server](#server)
|
30
|
+
* [Worker](#worker)
|
31
|
+
* [Running jobs from the command line](#running-jobs-from-the-command-line)
|
32
|
+
* [Running jobs through the API](#running-jobs-through-the-api)
|
26
33
|
* [Building Jobs](#building-jobs)
|
34
|
+
* [The Job Class](#the-job-class)
|
35
|
+
* [Job Options](#job-options)
|
36
|
+
* [Before, After, On Failure and On Success](#before-after-on-failure-and-on-success)
|
27
37
|
* [Loading Additional Code](#loading-additional-code)
|
28
38
|
* [Configuration](#configuration)
|
39
|
+
* [Worker Configuration](#worker-configuration)
|
29
40
|
|
30
41
|
---
|
31
42
|
|
43
|
+
Follow development progress:
|
44
|
+
[](https://waffle.io/DannyBen/jobly)
|
45
|
+
|
32
46
|
Installation
|
33
47
|
--------------------------------------------------
|
34
48
|
|
@@ -126,8 +140,11 @@ subfolder inside it. All your job classes go in this folder (configurable).
|
|
126
140
|
|
127
141
|
All job classes will be loaded by any of Jobly's commands.
|
128
142
|
|
143
|
+
|
144
|
+
### The Job Class
|
145
|
+
|
129
146
|
A job class is a simple Ruby class inheriting from
|
130
|
-
`
|
147
|
+
[`Jobly::Job`](/lib/jobly/job.rb).
|
131
148
|
|
132
149
|
The only requirement is that your class implements an `execute` method that
|
133
150
|
optionally accepts keyword arguments (recommended), or a hash.
|
@@ -144,12 +161,71 @@ end
|
|
144
161
|
```
|
145
162
|
|
146
163
|
Note that these classes are simply Jobly-flavored sidekiq jobs, with these
|
147
|
-
differences:
|
164
|
+
key differences:
|
148
165
|
|
149
166
|
- You need to implement `execute` instead of `perform`
|
150
167
|
- Job arguments are defined as keyword arguments, instead of positional
|
151
168
|
arguments.
|
152
169
|
|
170
|
+
#### Job Options
|
171
|
+
|
172
|
+
The `Jobly::Job` class supports these options:
|
173
|
+
|
174
|
+
| Key | Default | Purpose
|
175
|
+
|-------------|-----------|---------------
|
176
|
+
| `queue` | `default` | set the name of the queue for this job.
|
177
|
+
| `retries` | `5` | number of times to retry on failure.
|
178
|
+
| `backtrace` | `5` | number of backtrace lines to show in case of failures. Can be `true`, `false` or a number of lines to save.
|
179
|
+
|
180
|
+
For example:
|
181
|
+
|
182
|
+
```ruby
|
183
|
+
class Deploy < Jobly::Job
|
184
|
+
queue 'critical'
|
185
|
+
backtrace 10
|
186
|
+
retries 3
|
187
|
+
|
188
|
+
def execute
|
189
|
+
puts "Deploying"
|
190
|
+
end
|
191
|
+
end
|
192
|
+
```
|
193
|
+
|
194
|
+
|
195
|
+
#### Before, After, On Failure and On Success
|
196
|
+
|
197
|
+
The `Jobly::Job` class supports these callback methods:
|
198
|
+
|
199
|
+
| Method | Description
|
200
|
+
|--------------|-------------
|
201
|
+
| `before` | Executes before the job starts
|
202
|
+
| `on_success` | Executes after the job finishes, and only if it succeeds
|
203
|
+
| `on_failure` | Executes after the job finishes, and only if it fails
|
204
|
+
| `after` | Executes after the job finishes, regardless of success or failure
|
205
|
+
|
206
|
+
Each callback method can either be a block or a symbol that points to a local
|
207
|
+
method. WHen using a block, you will have the `params` variable available, with
|
208
|
+
all the parameteres sent to the job.
|
209
|
+
|
210
|
+
For example:
|
211
|
+
|
212
|
+
```ruby
|
213
|
+
class Greet < Jobly::Job
|
214
|
+
before do
|
215
|
+
logger.info "Starting with #{params[:message]}"
|
216
|
+
end
|
217
|
+
|
218
|
+
after :reboot_computer
|
219
|
+
|
220
|
+
def execute(message: "Hello")
|
221
|
+
puts message
|
222
|
+
end
|
223
|
+
|
224
|
+
def reboot_computer
|
225
|
+
system "reboot"
|
226
|
+
end
|
227
|
+
end
|
228
|
+
```
|
153
229
|
|
154
230
|
|
155
231
|
Loading Additional Code
|
@@ -173,3 +249,19 @@ Configuring Jobly can be done by one of two methods:
|
|
173
249
|
See this [example config file](/examples/02-full/config/jobly.rb) for a full
|
174
250
|
annotated configuration example and a list of options with their respective
|
175
251
|
environment variables.
|
252
|
+
|
253
|
+
|
254
|
+
### Worker Configuration
|
255
|
+
|
256
|
+
For advanced configuration of the sidekiq worker, beyond what the
|
257
|
+
`jobly worker` command provides, you can place YAML files in the config
|
258
|
+
folder and point the workers to their config file with
|
259
|
+
`jobly worker --config name`.
|
260
|
+
|
261
|
+
These files are simply [sidekiq configuration files][1].
|
262
|
+
|
263
|
+
See the [worker-config](/examples/06-worker-config) example for more
|
264
|
+
information.
|
265
|
+
|
266
|
+
|
267
|
+
[1]: https://github.com/mperham/sidekiq/wiki/Advanced-Options
|
data/lib/jobly.rb
CHANGED
@@ -2,18 +2,40 @@ module Jobly
|
|
2
2
|
module Commands
|
3
3
|
class WorkerCmd < Base
|
4
4
|
summary "Start a job worker"
|
5
|
-
usage "jobly worker [
|
5
|
+
usage "jobly worker [-c COUNT -C PATH (-q NAME)...]"
|
6
6
|
usage "jobly worker (-h|--help)"
|
7
7
|
option "-c, --concurrency COUNT", "Number of parallel jobs [default: 4]"
|
8
|
+
option "-C, --config PATH", "Specify a path to a YAML config file. The provided path should be relative to the global config_path directory and without the yml extension"
|
9
|
+
option "-q, --queue NAME[,WEIGHT]", "Specify one or more queues that this worker should handle"
|
10
|
+
|
11
|
+
example "jobly worker --concurrency 10"
|
12
|
+
example "jobly worker -q critical -q default -q low"
|
13
|
+
example "jobly worker --config primary"
|
8
14
|
|
9
15
|
def run
|
10
|
-
concurrency = args['--concurrency']
|
11
16
|
say "Starting sidekiq"
|
12
|
-
exec "sidekiq
|
17
|
+
exec "sidekiq #{options_from_args}"
|
13
18
|
end
|
14
19
|
|
15
20
|
private
|
16
21
|
|
22
|
+
def options_from_args
|
23
|
+
result = []
|
24
|
+
result << "--environment #{Jobly.environment}"
|
25
|
+
result << "--require \"#{boot_file}\""
|
26
|
+
result << "--concurrency #{args['--concurrency']}" if args['--concurrency']
|
27
|
+
|
28
|
+
if args['--config']
|
29
|
+
config_file = "#{Jobly.config_path}/#{args['--config']}.yml"
|
30
|
+
raise ArgumentError, "Config not found: #{config_file}" unless File.exist? config_file
|
31
|
+
result << "--config \"#{config_file}\""
|
32
|
+
end
|
33
|
+
|
34
|
+
args['--queue'].each { |q| result << "--queue #{q}" }
|
35
|
+
|
36
|
+
result.join ' '
|
37
|
+
end
|
38
|
+
|
17
39
|
def boot_file
|
18
40
|
@boot_file ||= File.expand_path '../boot.rb', __dir__
|
19
41
|
end
|
data/lib/jobly/job.rb
CHANGED
@@ -2,15 +2,58 @@ module Jobly
|
|
2
2
|
class Job
|
3
3
|
include Sidekiq::Worker
|
4
4
|
include Sidekiq::Status::Worker
|
5
|
-
|
5
|
+
include JobExtensions::OptionAccessors
|
6
|
+
include JobExtensions::Actions
|
7
|
+
using KeywordArgs
|
6
8
|
|
9
|
+
sidekiq_options retry: 5, backtrace: 5
|
10
|
+
attr_reader :params
|
11
|
+
|
12
|
+
class << self
|
13
|
+
# Allow inheriting jobs to use `execute_async` instead of
|
14
|
+
# `perform_async` for consistency with `execute`
|
15
|
+
alias_method :execute_async, :perform_async
|
16
|
+
|
17
|
+
# Allow calling a job with `JobName.execute` instead of
|
18
|
+
# `JobName.new.execute`, for consistency.
|
19
|
+
def execute(*args)
|
20
|
+
new.execute *args
|
21
|
+
end
|
22
|
+
|
23
|
+
# Allow calling a job with `JobName.perform` instead of
|
24
|
+
# `JobName.new.perform`, for consistency.
|
25
|
+
def perform(*args)
|
26
|
+
new.perform *args
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
# This is the method sidekiq will call. We capture this call and convert
|
32
|
+
# the hash argument which was converted to array on sidekiq's side, back
|
33
|
+
# to a hash so we can forward to the job's `execute` method, which may
|
34
|
+
# implement keyword args.
|
7
35
|
def perform(params={})
|
8
|
-
params = params
|
9
|
-
|
36
|
+
@params = params
|
37
|
+
run_actions :before
|
38
|
+
|
39
|
+
begin
|
40
|
+
params.empty? ? execute : execute(params.to_kwargs)
|
41
|
+
run_actions :success
|
42
|
+
|
43
|
+
rescue
|
44
|
+
run_actions :failure
|
45
|
+
raise
|
46
|
+
|
47
|
+
ensure
|
48
|
+
run_actions :after
|
49
|
+
|
50
|
+
end
|
10
51
|
end
|
11
52
|
|
53
|
+
# Inheriting classes must implement this method only.
|
12
54
|
def execute(params={})
|
13
55
|
raise NotImplementedError
|
14
56
|
end
|
57
|
+
|
15
58
|
end
|
16
59
|
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Jobly
|
2
|
+
module JobExtensions
|
3
|
+
module Actions
|
4
|
+
|
5
|
+
def self.included(base)
|
6
|
+
base.extend ClassMethods
|
7
|
+
end
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
def before(sym = nil, &block)
|
11
|
+
actions[:before] ||= []
|
12
|
+
actions[:before] << (sym || block)
|
13
|
+
end
|
14
|
+
|
15
|
+
def after(sym = nil, &block)
|
16
|
+
actions[:after] ||= []
|
17
|
+
actions[:after] << (sym || block)
|
18
|
+
end
|
19
|
+
|
20
|
+
def on_success(sym = nil, &block)
|
21
|
+
actions[:success] ||= []
|
22
|
+
actions[:success] << (sym || block)
|
23
|
+
end
|
24
|
+
|
25
|
+
def on_failure(sym = nil, &block)
|
26
|
+
actions[:failure] ||= []
|
27
|
+
actions[:failure] << (sym || block)
|
28
|
+
end
|
29
|
+
|
30
|
+
def actions
|
31
|
+
@actions ||= {}
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
protected
|
36
|
+
|
37
|
+
def actions
|
38
|
+
self.class.actions
|
39
|
+
end
|
40
|
+
|
41
|
+
def run_actions(list)
|
42
|
+
return unless actions[list]
|
43
|
+
|
44
|
+
actions[list].each do |action|
|
45
|
+
if action.is_a? Symbol
|
46
|
+
send action
|
47
|
+
else
|
48
|
+
instance_eval &action
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Jobly
|
2
|
+
module JobExtensions
|
3
|
+
module OptionAccessors
|
4
|
+
|
5
|
+
def self.included(base)
|
6
|
+
base.extend ClassMethods
|
7
|
+
end
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
def options
|
11
|
+
sidekiq_options
|
12
|
+
end
|
13
|
+
|
14
|
+
def queue(name)
|
15
|
+
options['queue'] = name
|
16
|
+
end
|
17
|
+
|
18
|
+
def retries(count)
|
19
|
+
options['retry'] = count
|
20
|
+
end
|
21
|
+
|
22
|
+
def backtrace(count)
|
23
|
+
options['backtrace'] = count
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/jobly/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jobly
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Danny Ben Shitrit
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-03-
|
11
|
+
date: 2019-03-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mister_bin
|
@@ -185,10 +185,13 @@ files:
|
|
185
185
|
- lib/jobly/config.ru
|
186
186
|
- lib/jobly/exceptions.rb
|
187
187
|
- lib/jobly/job.rb
|
188
|
+
- lib/jobly/job_extensions/actions.rb
|
189
|
+
- lib/jobly/job_extensions/option_accessors.rb
|
188
190
|
- lib/jobly/jobs.rb
|
189
191
|
- lib/jobly/module_functions.rb
|
190
192
|
- lib/jobly/refinements/argument_converters.rb
|
191
193
|
- lib/jobly/refinements/convert_to_typed.rb
|
194
|
+
- lib/jobly/refinements/keyword_args.rb
|
192
195
|
- lib/jobly/server.rb
|
193
196
|
- lib/jobly/sidekiq.rb
|
194
197
|
- lib/jobly/version.rb
|