disc 0.1.0 → 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 +36 -7
- data/examples/echoer.rb +1 -1
- data/examples/failer.rb +1 -1
- data/examples/greeter.rb +1 -1
- data/examples/identifier.rb +10 -0
- data/examples/returner.rb +1 -1
- data/lib/disc.rb +9 -2
- data/lib/disc/errors.rb +3 -2
- data/lib/disc/job.rb +5 -0
- data/lib/disc/version.rb +1 -1
- data/lib/disc/worker.rb +4 -4
- data/test/disc_test.rb +2 -2
- data/test/process_test.rb +14 -5
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 233a653ff0bf84c468fda3cbeb939259209eae64
|
4
|
+
data.tar.gz: c9f14c60f0d2dfa165eb56421d3e1f2ed0eb3c6c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 49b4e538464fddd391724150b4403bb4be4f00adddfe4a374e3e0a30c664e759615cc10ef8385f5d26592e5e0323f0d77e0e9a29f1aa8bddccddd6a321d874a8
|
7
|
+
data.tar.gz: 8e6caa1a5e2532ee85f40d97e849415cc402127e6258c83e999148c5edc673da1bb6565fa5bb5a7582f8283084dbd11d73d135e76aac14469c7b722d4df4d136
|
data/README.md
CHANGED
@@ -23,7 +23,7 @@ Disc fills the gap between your Ruby service objects and [antirez](http://antire
|
|
23
23
|
include Disc::Job
|
24
24
|
disc queue: 'urgent'
|
25
25
|
|
26
|
-
def
|
26
|
+
def perform(type)
|
27
27
|
# perform rather lengthy operations here.
|
28
28
|
end
|
29
29
|
end
|
@@ -94,7 +94,7 @@ Signature documentation follows:
|
|
94
94
|
## Parameters:
|
95
95
|
#
|
96
96
|
## `arguments` - an optional array of arguments with which to execute
|
97
|
-
# the job's `
|
97
|
+
# the job's `perform` method.
|
98
98
|
#
|
99
99
|
# `at` - an optional named parameter specifying a moment in the
|
100
100
|
# future in which to run the job, must respond to
|
@@ -142,7 +142,7 @@ Signature documentation follows:
|
|
142
142
|
|
143
143
|
You can see [Disque's ADDJOB documentation](https://github.com/antirez/disque#addjob-queue_name-job-ms-timeout-replicate-count-delay-sec-retry-sec-ttl-sec-maxlen-count-async) for more details
|
144
144
|
|
145
|
-
When a Disc worker process is assigned a job, it will create a new intance of the job's class and execute the `
|
145
|
+
When a Disc worker process is assigned a job, it will create a new intance of the job's class and execute the `perform` method with whatever arguments were previously passed to `#enqueue`.
|
146
146
|
|
147
147
|
Example:
|
148
148
|
|
@@ -151,7 +151,7 @@ class ComplexJob
|
|
151
151
|
include Disc::Job
|
152
152
|
disc queue: 'urgent'
|
153
153
|
|
154
|
-
def
|
154
|
+
def perform(first_parameter, second_parameter)
|
155
155
|
# do things...
|
156
156
|
end
|
157
157
|
end
|
@@ -160,7 +160,32 @@ end
|
|
160
160
|
ComplexJob.enqueue(['first argument', { second: 'argument' }])
|
161
161
|
```
|
162
162
|
|
163
|
-
###
|
163
|
+
### Managing Jobs
|
164
|
+
|
165
|
+
Disc jobs can be managed by knowing their disque ID, this id is returned by the `#enqueue` method so you can control the job or query it's state from your application code.
|
166
|
+
|
167
|
+
```ruby
|
168
|
+
Echoer.enqueue('test')
|
169
|
+
#=> "DIa18101491133639148a574eb30cd2e12f25dcf8805a0SQ"
|
170
|
+
```
|
171
|
+
|
172
|
+
The disque ID is also available from within the context of an executing job, you can access it via `self.disque_id` if you wish to do things like notify Disque that a long-running job is still being executed.
|
173
|
+
|
174
|
+
```ruby
|
175
|
+
class LongJob
|
176
|
+
include Disc::Job
|
177
|
+
|
178
|
+
def perform(first_parameter, second_parameter)
|
179
|
+
# Do things that take a while.
|
180
|
+
|
181
|
+
Disc.disque.call('WORKING', self.disque_id)
|
182
|
+
|
183
|
+
# Do more things that take a while.
|
184
|
+
end
|
185
|
+
end
|
186
|
+
```
|
187
|
+
|
188
|
+
#### Job Status
|
164
189
|
|
165
190
|
After a job is enqueued, you can check it's current status like so:
|
166
191
|
|
@@ -192,12 +217,16 @@ Disc["DIa18101491133639148a574eb30cd2e12f25dcf8805a0SQ"]
|
|
192
217
|
|
193
218
|
This information might vary, as it's retreived from Disque via the [`SHOW`](https://github.com/antirez/disque#show-job-id) command, only `arguments` and `class` are filled in by Disc, which are added by using `Disc.deserialize` on the `body` value.
|
194
219
|
|
220
|
+
#### Do everything Disque can
|
221
|
+
|
222
|
+
Access to the disque ID allows us to leverage the Disque API to manage the job, you can execute Disque commands via the `Disc.disque.call()` method, see [the Disque API](https://github.com/antirez/disque#main-api) to see all the commands available.
|
223
|
+
|
195
224
|
### Job Serialization
|
196
225
|
|
197
226
|
Job information (their arguments, and class) need to be serialized in order to be stored
|
198
227
|
in Disque, to this end Disc uses the `Disc.serialize` and `Disc.deserialize` methods.
|
199
228
|
|
200
|
-
By default, these methods use
|
229
|
+
By default, these methods use the Ruby standard library json implementation in order to serialize and deserialize job data, this has a few implications:
|
201
230
|
|
202
231
|
1. Arguments passed to a job's `#enqueue` method need to be serializable by `Disc.serialize` and parsed back by `Disc.deserialize`, so by default you can't pass complex Ruby objects like a `user` model, instead, pass `user.id`, and use that from your job code.
|
203
232
|
|
@@ -317,7 +346,7 @@ end
|
|
317
346
|
class CluJob < ActiveJob::Base
|
318
347
|
queue_as :urgent
|
319
348
|
|
320
|
-
def
|
349
|
+
def perform(*args)
|
321
350
|
# Try to take over The Grid here...
|
322
351
|
end
|
323
352
|
end
|
data/examples/echoer.rb
CHANGED
data/examples/failer.rb
CHANGED
data/examples/greeter.rb
CHANGED
data/examples/returner.rb
CHANGED
data/lib/disc.rb
CHANGED
@@ -73,7 +73,7 @@ class Disc
|
|
73
73
|
# * An instance of the given job class
|
74
74
|
# * An array of arguments to pass to the job's `#perorm` class.
|
75
75
|
#
|
76
|
-
def self.load_job(serialized_job)
|
76
|
+
def self.load_job(serialized_job, disque_id = nil)
|
77
77
|
begin
|
78
78
|
job_data = Disc.deserialize(serialized_job)
|
79
79
|
rescue => err
|
@@ -86,7 +86,14 @@ class Disc
|
|
86
86
|
raise Disc::UnknownJobClassError.new(err)
|
87
87
|
end
|
88
88
|
|
89
|
-
|
89
|
+
begin
|
90
|
+
job_instance = job_class.new
|
91
|
+
job_instance.disque_id = disque_id
|
92
|
+
rescue => err
|
93
|
+
raise Disc::NonJobClassError.new(err)
|
94
|
+
end
|
95
|
+
|
96
|
+
return [job_instance, job_data['arguments']]
|
90
97
|
end
|
91
98
|
end
|
92
99
|
|
data/lib/disc/errors.rb
CHANGED
data/lib/disc/job.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
module Disc::Job
|
2
|
+
attr_accessor :disque_id
|
2
3
|
|
3
4
|
def self.included(base)
|
4
5
|
base.extend(ClassMethods)
|
@@ -26,6 +27,10 @@ module Disc::Job
|
|
26
27
|
@queue || Disc.default_queue
|
27
28
|
end
|
28
29
|
|
30
|
+
def perform(arguments)
|
31
|
+
self.new.perform(*arguments)
|
32
|
+
end
|
33
|
+
|
29
34
|
## Disc's `#enqueue` is the main user-facing method of a Disc job, it
|
30
35
|
# enqueues a job with a given set of arguments in Disque, so it can be
|
31
36
|
# picked up by a Disc worker process.
|
data/lib/disc/version.rb
CHANGED
data/lib/disc/worker.rb
CHANGED
@@ -52,15 +52,15 @@ class Disc::Worker
|
|
52
52
|
jobs = disque.fetch(from: queues, timeout: timeout, count: count)
|
53
53
|
Array(jobs).each do |queue, msgid, serialized_job|
|
54
54
|
begin
|
55
|
-
|
56
|
-
|
55
|
+
job_instance, arguments = Disc.load_job(serialized_job, msgid)
|
56
|
+
job_instance.perform(*arguments)
|
57
57
|
disque.call('ACKJOB', msgid)
|
58
|
-
$stdout.puts("Completed #{
|
58
|
+
$stdout.puts("Completed #{ job_instance.class.name } id #{ msgid }")
|
59
59
|
rescue => err
|
60
60
|
Disc.on_error(err, {
|
61
61
|
disque_id: msgid,
|
62
62
|
queue: queue,
|
63
|
-
class: defined?(
|
63
|
+
class: defined?(job_instance) ? job_instance.class.name : '',
|
64
64
|
arguments: defined?(arguments) ? arguments : []
|
65
65
|
})
|
66
66
|
end
|
data/test/disc_test.rb
CHANGED
@@ -44,9 +44,9 @@ scope do
|
|
44
44
|
{ class: 'Echoer', arguments: ['one argument', { random: 'data' }, 3] }
|
45
45
|
)
|
46
46
|
|
47
|
-
|
47
|
+
job_instance, arguments = Disc.load_job(serialized_job)
|
48
48
|
|
49
|
-
assert_equal Echoer,
|
49
|
+
assert_equal Echoer, job_instance.class
|
50
50
|
assert arguments.is_a?(Array)
|
51
51
|
assert_equal 3, arguments.count
|
52
52
|
assert_equal 'one argument', arguments.first
|
data/test/process_test.rb
CHANGED
@@ -5,6 +5,7 @@ require 'timeout'
|
|
5
5
|
|
6
6
|
require_relative '../examples/echoer'
|
7
7
|
require_relative '../examples/failer'
|
8
|
+
require_relative '../examples/identifier'
|
8
9
|
|
9
10
|
prepare do
|
10
11
|
Disc.disque_timeout = 1 # 1ms so we don't wait at all.
|
@@ -35,14 +36,12 @@ scope do
|
|
35
36
|
|
36
37
|
run('QUEUES=test ruby -Ilib bin/disc -r ./examples/failer') do |cout, pid|
|
37
38
|
output = Timeout.timeout(1) { cout.take(5) }
|
38
|
-
jobs = Disc.disque.fetch(from: ['test'], timeout: Disc.disque_timeout, count: 1)
|
39
|
-
assert jobs.nil?
|
40
|
-
|
41
39
|
assert output.grep(/<insert error reporting here>/).any?
|
42
40
|
assert output.grep(/this can only end positively/).any?
|
43
41
|
assert output.grep(/Failer/).any?
|
44
42
|
|
45
43
|
assert is_running?(pid)
|
44
|
+
assert_equal 0, Disc.qlen(Failer.queue)
|
46
45
|
end
|
47
46
|
end
|
48
47
|
|
@@ -51,9 +50,19 @@ scope do
|
|
51
50
|
|
52
51
|
run('QUEUES=test ruby -Ilib bin/disc -r ./examples/echoer') do |cout, pid|
|
53
52
|
output = Timeout.timeout(1) { cout.take(3) }
|
54
|
-
jobs = Disc.disque.fetch(from: ['test'], timeout: Disc.disque_timeout, count: 1)
|
55
|
-
assert jobs.nil?
|
56
53
|
assert output.grep(/First: one argument, Second: {"random"=>"data"}, Third: 3/).any?
|
54
|
+
assert_equal 0, Disc.qlen(Echoer.queue)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
test 'running jobs have access to their Disque job ID' do
|
59
|
+
disque_id = Identifier.enqueue
|
60
|
+
|
61
|
+
run('QUEUES=test ruby -Ilib bin/disc -r ./examples/identifier') do |cout, pid|
|
62
|
+
output = Timeout.timeout(1) { cout.take(3) }
|
63
|
+
assert output.grep(/Working with Disque ID: #{ disque_id }/).any?
|
64
|
+
|
65
|
+
assert_equal 0, Disc.qlen(Identifier.queue)
|
57
66
|
end
|
58
67
|
end
|
59
68
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: disc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- pote
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-05-
|
11
|
+
date: 2016-05-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: disque
|
@@ -61,6 +61,7 @@ files:
|
|
61
61
|
- examples/echoer.rb
|
62
62
|
- examples/failer.rb
|
63
63
|
- examples/greeter.rb
|
64
|
+
- examples/identifier.rb
|
64
65
|
- examples/returner.rb
|
65
66
|
- lib/active_job/queue_adapters/disc_adapter.rb
|
66
67
|
- lib/disc.rb
|