jobly 0.1.3 → 0.2.0
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 +5 -216
- data/lib/jobly.rb +1 -0
- data/lib/jobly/extensions/integer.rb +21 -0
- data/lib/jobly/job.rb +26 -14
- data/lib/jobly/job_extensions/actions.rb +13 -1
- data/lib/jobly/job_extensions/solo.rb +54 -0
- data/lib/jobly/module_functions.rb +2 -2
- data/lib/jobly/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 19d048c26e395618f64751b5d44598f0456782733361ea19f301bb8a3c30f056
|
4
|
+
data.tar.gz: c9407a5d8ac2915115448a6de9d022127fc92d06b81e1952835680c6309f00cc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9debe7765379021f9fda73fceecbd70b5967fe8b61c1888d628814be0f0e8302d51a7ce49b1c2c610750b8590611768f0e4b1b14ab041d4f0fa12f3a8e3cde8c
|
7
|
+
data.tar.gz: e6cb27d5c6ff080c6518e360d2b4409332548f07b4d26cfcb94ad4040ea08751daaa46df2476b1dc512ddda0e899dc0e8a48ac7b95e31c13dbcccca232b4964a
|
data/README.md
CHANGED
@@ -22,24 +22,6 @@ Compact job server with API, CLI, Web UI and a Sidekiq heart.
|
|
22
22
|
|
23
23
|
---
|
24
24
|
|
25
|
-
* [Installation](#installation)
|
26
|
-
* [What's in the Box](#whats-in-the-box)
|
27
|
-
* [Quick Start](#quick-start)
|
28
|
-
* [Usage](#usage)
|
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)
|
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)
|
37
|
-
* [Loading Additional Code](#loading-additional-code)
|
38
|
-
* [Configuration](#configuration)
|
39
|
-
* [Worker Configuration](#worker-configuration)
|
40
|
-
|
41
|
-
---
|
42
|
-
|
43
25
|
Follow development progress:
|
44
26
|
[](https://waffle.io/DannyBen/jobly)
|
45
27
|
|
@@ -48,6 +30,7 @@ Installation
|
|
48
30
|
|
49
31
|
$ gem install jobly
|
50
32
|
|
33
|
+
Or with the official [Jobly docker image][2].
|
51
34
|
|
52
35
|
|
53
36
|
What's in the Box
|
@@ -63,205 +46,11 @@ sidekiq backgronud jobs system. It includes the following components:
|
|
63
46
|
|
64
47
|
|
65
48
|
|
66
|
-
|
67
|
-
--------------------------------------------------
|
68
|
-
|
69
|
-
Follow one of these annotated [examples](/examples).
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
Usage
|
49
|
+
Documentation
|
74
50
|
--------------------------------------------------
|
75
51
|
|
76
|
-
|
77
|
-
### Server
|
78
|
-
|
79
|
-
To start the server run `jobly server` and open <http://localhost:3000/>
|
80
|
-
in your browser.
|
81
|
-
|
82
|
-
This will start a webserver with two primary entrypoints:
|
83
|
-
|
84
|
-
- `/` (root) - a dashboard for your background job processes.
|
85
|
-
- `/do/JobName?param=value` - an API for executing jobs
|
86
|
-
|
87
|
-
|
88
|
-
### Worker
|
89
|
-
|
90
|
-
To start processing jobs, run `jobly worker`
|
91
|
-
|
92
|
-
|
93
|
-
### Running jobs from the command line
|
94
|
-
|
95
|
-
There are three ways to run a job from the command line:
|
96
|
-
|
97
|
-
Run the job locally, without going through any of the background job
|
98
|
-
processing chain:
|
99
|
-
|
100
|
-
$ jobly run JobName param:value
|
101
|
-
|
102
|
-
|
103
|
-
Run the job locally, but wait for a worker to process it.
|
104
|
-
|
105
|
-
$ jobly run --later JobName param:value
|
106
|
-
|
107
|
-
|
108
|
-
Send a job through the API (either localhost or remote).
|
109
|
-
|
110
|
-
$ jobly send JobName param:value
|
111
|
-
|
112
|
-
|
113
|
-
### Running jobs through the API
|
114
|
-
|
115
|
-
The API supports running jobs either by GET or by POST in the following URL
|
116
|
-
structure:
|
117
|
-
|
118
|
-
<http://localhost:3000/do/JobName>
|
119
|
-
|
120
|
-
Using GET:
|
121
|
-
|
122
|
-
```
|
123
|
-
$ curl localhost:3000/do/Build?deploy=no
|
124
|
-
# => {"status":"received","job":"Build","params":{"deploy":"no"}}
|
125
|
-
```
|
126
|
-
|
127
|
-
Using POST:
|
128
|
-
|
129
|
-
```
|
130
|
-
$ curl -XPOST localhost:3000/do/Build -d deploy=yes
|
131
|
-
{"status":"received","job":"Build","params":{"deploy":"yes"}}
|
132
|
-
```
|
133
|
-
|
134
|
-
|
135
|
-
Building Jobs
|
136
|
-
--------------------------------------------------
|
137
|
-
|
138
|
-
To build a jobs "workspace", start in an empty folder and create a `./jobs`
|
139
|
-
subfolder inside it. All your job classes go in this folder (configurable).
|
140
|
-
|
141
|
-
All job classes will be loaded by any of Jobly's commands.
|
142
|
-
|
143
|
-
|
144
|
-
### The Job Class
|
145
|
-
|
146
|
-
A job class is a simple Ruby class inheriting from
|
147
|
-
[`Jobly::Job`](/lib/jobly/job.rb).
|
148
|
-
|
149
|
-
The only requirement is that your class implements an `execute` method that
|
150
|
-
optionally accepts keyword arguments (recommended), or a hash.
|
151
|
-
|
152
|
-
Example:
|
153
|
-
|
154
|
-
```ruby
|
155
|
-
class Hello < Jobly::Job
|
156
|
-
def execute(name: 'bob')
|
157
|
-
puts "Hello #{name}"
|
158
|
-
logger.info "said hello to #{name}"
|
159
|
-
end
|
160
|
-
end
|
161
|
-
```
|
162
|
-
|
163
|
-
Note that these classes are simply Jobly-flavored sidekiq jobs, with these
|
164
|
-
key differences:
|
165
|
-
|
166
|
-
- You need to implement `execute` instead of `perform`
|
167
|
-
- Job arguments are defined as keyword arguments, instead of positional
|
168
|
-
arguments.
|
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
|
-
```
|
229
|
-
|
230
|
-
|
231
|
-
Loading Additional Code
|
232
|
-
--------------------------------------------------
|
233
|
-
|
234
|
-
In case your jobs require additional functionality, you may create the
|
235
|
-
`./app` folder as a sibling to the `./jobs` folder (configurable).
|
236
|
-
|
237
|
-
Any ruby files in this folder (and subfolders) will be autmatically loaded
|
238
|
-
and available to your jobs.
|
239
|
-
|
240
|
-
|
241
|
-
Configuration
|
242
|
-
--------------------------------------------------
|
243
|
-
|
244
|
-
Configuring Jobly can be done by one of two methods:
|
245
|
-
|
246
|
-
1. Setting environment variables.
|
247
|
-
2. Adding a `./config/jobly.rb` file.
|
248
|
-
|
249
|
-
See this [example config file](/examples/02-full/config/jobly.rb) for a full
|
250
|
-
annotated configuration example and a list of options with their respective
|
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.
|
52
|
+
Visit the [Jobly Documentation][1].
|
265
53
|
|
266
54
|
|
267
|
-
[1]: https://
|
55
|
+
[1]: https://jobly.dannyb.co
|
56
|
+
[2]: https://github.com/dannyben/docker-jobly
|
data/lib/jobly.rb
CHANGED
@@ -0,0 +1,21 @@
|
|
1
|
+
class Integer
|
2
|
+
def seconds
|
3
|
+
self
|
4
|
+
end
|
5
|
+
alias_method :second, :seconds
|
6
|
+
|
7
|
+
def minutes
|
8
|
+
60 * seconds
|
9
|
+
end
|
10
|
+
alias_method :minute, :minutes
|
11
|
+
|
12
|
+
def hours
|
13
|
+
60 * minutes
|
14
|
+
end
|
15
|
+
alias_method :hour, :hours
|
16
|
+
|
17
|
+
def days
|
18
|
+
24 * hours
|
19
|
+
end
|
20
|
+
alias_method :day, :days
|
21
|
+
end
|
data/lib/jobly/job.rb
CHANGED
@@ -4,6 +4,7 @@ module Jobly
|
|
4
4
|
include Sidekiq::Status::Worker
|
5
5
|
include JobExtensions::OptionAccessors
|
6
6
|
include JobExtensions::Actions
|
7
|
+
include JobExtensions::Solo
|
7
8
|
using KeywordArgs
|
8
9
|
|
9
10
|
sidekiq_options retry: 5, backtrace: 5
|
@@ -34,20 +35,7 @@ module Jobly
|
|
34
35
|
# implement keyword args.
|
35
36
|
def perform(params={})
|
36
37
|
@params = params
|
37
|
-
|
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
|
38
|
+
run_to_completion if run_before_filter
|
51
39
|
end
|
52
40
|
|
53
41
|
# Inheriting classes must implement this method only.
|
@@ -55,5 +43,29 @@ module Jobly
|
|
55
43
|
raise NotImplementedError
|
56
44
|
end
|
57
45
|
|
46
|
+
private
|
47
|
+
|
48
|
+
def run_before_filter
|
49
|
+
run_actions :before
|
50
|
+
if skipped?
|
51
|
+
run_actions :skip
|
52
|
+
run_actions :after
|
53
|
+
return false
|
54
|
+
end
|
55
|
+
return true
|
56
|
+
end
|
57
|
+
|
58
|
+
def run_to_completion
|
59
|
+
params.empty? ? execute : execute(params.to_kwargs)
|
60
|
+
run_actions :success
|
61
|
+
|
62
|
+
rescue
|
63
|
+
run_actions :failure
|
64
|
+
raise
|
65
|
+
|
66
|
+
ensure
|
67
|
+
run_actions :after
|
68
|
+
|
69
|
+
end
|
58
70
|
end
|
59
71
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
module Jobly
|
2
2
|
module JobExtensions
|
3
3
|
module Actions
|
4
|
-
|
5
4
|
def self.included(base)
|
6
5
|
base.extend ClassMethods
|
7
6
|
end
|
@@ -27,11 +26,24 @@ module Jobly
|
|
27
26
|
actions[:failure] << (sym || block)
|
28
27
|
end
|
29
28
|
|
29
|
+
def on_skip(sym = nil, &block)
|
30
|
+
actions[:skip] ||= []
|
31
|
+
actions[:skip] << (sym || block)
|
32
|
+
end
|
33
|
+
|
30
34
|
def actions
|
31
35
|
@actions ||= {}
|
32
36
|
end
|
33
37
|
end
|
34
38
|
|
39
|
+
def skip_job
|
40
|
+
@skipped = true
|
41
|
+
end
|
42
|
+
|
43
|
+
def skipped?
|
44
|
+
@skipped
|
45
|
+
end
|
46
|
+
|
35
47
|
protected
|
36
48
|
|
37
49
|
def actions
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'jobly/job_extensions/actions'
|
2
|
+
|
3
|
+
module Jobly
|
4
|
+
module JobExtensions
|
5
|
+
module Solo
|
6
|
+
include Actions
|
7
|
+
|
8
|
+
def self.included(base)
|
9
|
+
base.extend ClassMethods
|
10
|
+
end
|
11
|
+
|
12
|
+
module ClassMethods
|
13
|
+
attr_reader :solo_key
|
14
|
+
|
15
|
+
def solo(expire: 1.hour, key: nil)
|
16
|
+
@solo_key = key if key
|
17
|
+
before { solo_locked? ? skip_job : solo_lock(expire) }
|
18
|
+
after { solo_unlock }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def solo_key
|
23
|
+
@solo_key ||= (self.class.solo_key || solo_key!)
|
24
|
+
end
|
25
|
+
|
26
|
+
def solo_key!
|
27
|
+
Digest::MD5.hexdigest "#{self.class.name}:#{params}"
|
28
|
+
end
|
29
|
+
|
30
|
+
def solo_full_key
|
31
|
+
"jobly:solo:#{solo_key}"
|
32
|
+
end
|
33
|
+
|
34
|
+
def solo_locked?
|
35
|
+
Sidekiq.redis do |redis|
|
36
|
+
redis.keys(solo_full_key).count >= 1
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def solo_lock(expire = 1.hour)
|
41
|
+
Sidekiq.redis do |redis|
|
42
|
+
redis.setex(solo_full_key, expire, "1")
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def solo_unlock
|
47
|
+
Sidekiq.redis do |redis|
|
48
|
+
redis.del solo_full_key
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -15,8 +15,8 @@ module Jobly
|
|
15
15
|
jobs_path: ENV['JOBLY_JOBS_PATH'] || "jobs",
|
16
16
|
config_path: ENV['JOBLY_CONFIG_PATH'] || "config",
|
17
17
|
redis_url: ENV['JOBLY_REDIS_URL'] || "redis://localhost:6379/0",
|
18
|
-
status_expiration: 30,
|
19
|
-
jobs_namespace:
|
18
|
+
status_expiration: ENV['JOBLY_STATUS_EXPIRATION']&.to_i || 30,
|
19
|
+
jobs_namespace: ENV['JOBLY_JOBS_NAMESPACE'],
|
20
20
|
logger: nil,
|
21
21
|
}
|
22
22
|
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.
|
4
|
+
version: 0.2.0
|
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-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mister_bin
|
@@ -184,9 +184,11 @@ files:
|
|
184
184
|
- lib/jobly/commands/worker.rb
|
185
185
|
- lib/jobly/config.ru
|
186
186
|
- lib/jobly/exceptions.rb
|
187
|
+
- lib/jobly/extensions/integer.rb
|
187
188
|
- lib/jobly/job.rb
|
188
189
|
- lib/jobly/job_extensions/actions.rb
|
189
190
|
- lib/jobly/job_extensions/option_accessors.rb
|
191
|
+
- lib/jobly/job_extensions/solo.rb
|
190
192
|
- lib/jobly/jobs.rb
|
191
193
|
- lib/jobly/module_functions.rb
|
192
194
|
- lib/jobly/refinements/argument_converters.rb
|