disc 0.0.26 → 0.0.27
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/.gems +0 -1
- data/README.md +80 -17
- data/disc.gemspec +0 -1
- data/lib/active_job/queue_adapters/disc_adapter.rb +3 -2
- data/lib/disc.rb +14 -119
- data/lib/disc/job.rb +127 -0
- data/lib/disc/version.rb +1 -1
- data/lib/disc/worker.rb +70 -0
- data/test/disc_test.rb +34 -14
- metadata +5 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 176f77e62f7e6d5d3fb12160f104e6f9920829f4
|
4
|
+
data.tar.gz: 3f081fa1f1835c21d92c6b52d20650d09b697e5a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 285379b94730d7a5e1eec6a5d551dfd42403452f91289a1fbce88c49d7f26457b59d9e32be25eb16c8a137888756f6ed851666ff64fc07532e0494e8deee8ef2
|
7
|
+
data.tar.gz: ad8a5da1ea7ce655c093796186abd7eb292fd22b2f68e0e7f13c9473643e93c28345893283966196578058fa121bbce70a8971df7f57d2e20b0cb298eeff41f8
|
data/.gems
CHANGED
data/README.md
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
Disc fills the gap between your Ruby service objects and [antirez](http://antirez.com/)'s wonderful [Disque](https://github.com/antirez/disque) backend.
|
4
4
|
|
5
|
-
<a href=https://www.flickr.com/photos/noodlefish/5321412234" target="blank_">
|
5
|
+
<a href="https://www.flickr.com/photos/noodlefish/5321412234" target="blank_">
|
6
6
|

|
7
7
|
</a>
|
8
8
|
|
9
|
-
## Usage
|
9
|
+
## Basic Usage
|
10
10
|
|
11
11
|
1. Install the gem
|
12
12
|
|
@@ -35,36 +35,99 @@ Disc fills the gap between your Ruby service objects and [antirez](http://antire
|
|
35
35
|
CreateGameGrid.enqueue('light_cycle')
|
36
36
|
```
|
37
37
|
|
38
|
+
|
39
|
+
4. Create a file that requires anything needed for your jobs to run
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
# disc_init.rb
|
43
|
+
require 'disc/worker'
|
44
|
+
Dir['./jobs/**/*.rb'].each { |job| require job }
|
45
|
+
```
|
46
|
+
|
47
|
+
5. Run as many Disc Worker processes as you wish, requiring your `disc_init.rb` file
|
48
|
+
|
49
|
+
```bash
|
50
|
+
$ QUEUES=urgent,default disc -r ./disc_init.rb
|
51
|
+
```
|
52
|
+
|
38
53
|
4. Or enqueue them to be performed at some time in the future, or on a queue other than it's default.
|
39
54
|
|
40
55
|
```ruby
|
41
56
|
CreateGameGrid.enqueue(
|
42
57
|
'disc_arena',
|
43
|
-
at: DateTime.new(
|
58
|
+
at: DateTime.new(2020, 12, 31),
|
44
59
|
queue: 'not_so_important'
|
45
60
|
)
|
46
61
|
```
|
47
62
|
|
48
|
-
|
63
|
+
## Disc Jobs
|
49
64
|
|
50
|
-
|
51
|
-
# disc_init.rb
|
52
|
-
require 'ohm'
|
53
|
-
Dir['./jobs/**/*.rb'].each { |job| require job }
|
54
|
-
```
|
65
|
+
`Disc::Job` is a module you can include in your Ruby classes, this allows a Disc worker process to execute the code in them by adding a class method (`#enqueue`) with the following signature:
|
55
66
|
|
56
|
-
|
67
|
+
```Ruby
|
68
|
+
def enqueue(arguments, at: nil, queue: nil, **options)
|
69
|
+
end
|
70
|
+
```
|
57
71
|
|
58
|
-
|
59
|
-
$ QUEUES=urgent,default disc -r ./disc_init.rb
|
60
|
-
```
|
72
|
+
Signature documentation follows:
|
61
73
|
|
62
|
-
|
74
|
+
```ruby
|
75
|
+
## Disc's `#enqueue` is the main user-facing method of a Disc job, it
|
76
|
+
# enqueues a job with a given set of arguments in Disque, so it can be
|
77
|
+
# picked up by a Disc worker process.
|
78
|
+
#
|
79
|
+
## Parameters:
|
80
|
+
#
|
81
|
+
## `arguments` - an optional array of arguments with which to execute
|
82
|
+
# the job's #perform method.
|
83
|
+
#
|
84
|
+
# `at` - an optional named parameter specifying a moment in the
|
85
|
+
# future in which to run the job, must respond to
|
86
|
+
# `#to_time`.
|
87
|
+
#
|
88
|
+
## `queue` - an optional named parameter specifying the name of the
|
89
|
+
# queue in which to store the job, defaults to the class
|
90
|
+
# Disc queue or to 'default' if no Disc queue is specified
|
91
|
+
# in the class.
|
92
|
+
#
|
93
|
+
## `**options` - an optional hash of options to forward internally to
|
94
|
+
# [disque-rb](https://github.com/soveran/disque-rb)'s
|
95
|
+
# `#push` method, valid options are:
|
96
|
+
#
|
97
|
+
## `replicate: <count>` - specifies the number of nodes the job should
|
98
|
+
# be replicated to.
|
99
|
+
#
|
100
|
+
### `delay: <sec>` - specifies a delay time in seconds for the job
|
101
|
+
# to be delivered to a Disc worker, it is ignored
|
102
|
+
# if using the `at` parameter.
|
103
|
+
#
|
104
|
+
### `ttl: <sec>` - specifies the job's time to live in seconds:
|
105
|
+
# after this time, the job is deleted even if
|
106
|
+
# it was not successfully delivered. If not
|
107
|
+
# specified, the default TTL is one day.
|
108
|
+
#
|
109
|
+
### `maxlen: <count>` - specifies that if there are already <count>
|
110
|
+
# messages queued for the specified queue name,
|
111
|
+
# the message is refused.
|
112
|
+
#
|
113
|
+
### `async: true` - asks the server to let the command return ASAP
|
114
|
+
# and replicate the job to other nodes in the background.
|
115
|
+
#
|
116
|
+
#
|
117
|
+
### CAVEATS
|
118
|
+
#
|
119
|
+
## For convenience, any object can be passed as the `arguments` parameter,
|
120
|
+
# `Array.wrap` will be used internally to preserve the array structure.
|
121
|
+
#
|
122
|
+
## The `arguments` parameter is serialized for storage using `Disc.serialize`
|
123
|
+
# and Disc workers picking it up use `Disc.deserialize` on it, both methods
|
124
|
+
# use standard library json but can be overriden by the user
|
125
|
+
#
|
126
|
+
```
|
63
127
|
|
64
|
-
|
128
|
+
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
|
65
129
|
|
66
|
-
|
67
|
-
* If your job takes multiple arguments, you'll want to pass all those arguments in the first parameter of `#enqueue` as an array.
|
130
|
+
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`.
|
68
131
|
|
69
132
|
Example:
|
70
133
|
|
data/disc.gemspec
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'date'
|
2
2
|
require 'msgpack'
|
3
|
+
require 'disc/worker'
|
3
4
|
|
4
5
|
module ActiveJob
|
5
6
|
module QueueAdapters
|
@@ -11,10 +12,10 @@ module ActiveJob
|
|
11
12
|
def self.enqueue_at(job, timestamp)
|
12
13
|
Disc.disque.push(
|
13
14
|
job.queue_name,
|
14
|
-
{
|
15
|
+
Disc.serialize({
|
15
16
|
class: job.class.name,
|
16
17
|
arguments: job.arguments
|
17
|
-
}
|
18
|
+
}),
|
18
19
|
Disc.disque_timeout,
|
19
20
|
delay: timestamp.nil? ? nil : (timestamp.to_time.to_i - DateTime.now.to_time.to_i)
|
20
21
|
)
|
data/lib/disc.rb
CHANGED
@@ -1,13 +1,8 @@
|
|
1
1
|
require 'date'
|
2
2
|
require 'disque'
|
3
|
-
require '
|
4
|
-
|
5
|
-
require_relative 'disc/version'
|
3
|
+
require 'json'
|
6
4
|
|
7
5
|
class Disc
|
8
|
-
attr_reader :disque,
|
9
|
-
:disque_timeout
|
10
|
-
|
11
6
|
def self.disque
|
12
7
|
@disque ||= Disque.new(
|
13
8
|
ENV.fetch('DISQUE_NODES', 'localhost:7711'),
|
@@ -21,7 +16,7 @@ class Disc
|
|
21
16
|
end
|
22
17
|
|
23
18
|
def self.disque_timeout
|
24
|
-
@disque_timeout ||= 100
|
19
|
+
@disque_timeout ||= ENV.fetch('DISQUE_TIMEOUT', 100)
|
25
20
|
end
|
26
21
|
|
27
22
|
def self.disque_timeout=(timeout)
|
@@ -36,6 +31,10 @@ class Disc
|
|
36
31
|
@default_queue = queue
|
37
32
|
end
|
38
33
|
|
34
|
+
def self.qlen(queue)
|
35
|
+
disque.call('QLEN', queue)
|
36
|
+
end
|
37
|
+
|
39
38
|
def self.flush
|
40
39
|
Disc.disque.call('DEBUG', 'FLUSHALL')
|
41
40
|
end
|
@@ -44,119 +43,15 @@ class Disc
|
|
44
43
|
$stderr.puts exception
|
45
44
|
end
|
46
45
|
|
47
|
-
|
48
|
-
|
49
|
-
:queues,
|
50
|
-
:timeout,
|
51
|
-
:count
|
52
|
-
|
53
|
-
def self.current
|
54
|
-
@current ||= new
|
55
|
-
end
|
56
|
-
|
57
|
-
def self.run
|
58
|
-
current.run
|
59
|
-
end
|
60
|
-
|
61
|
-
def self.stop
|
62
|
-
current.stop
|
63
|
-
end
|
64
|
-
|
65
|
-
def initialize(options = {})
|
66
|
-
@disque = options.fetch(:disque, Disc.disque)
|
67
|
-
@queues = options.fetch(
|
68
|
-
:queues,
|
69
|
-
ENV.fetch('QUEUES', Disc.default_queue)
|
70
|
-
).split(',')
|
71
|
-
@count = Integer(
|
72
|
-
options.fetch(
|
73
|
-
:count,
|
74
|
-
ENV.fetch('DISQUE_COUNT', '1')
|
75
|
-
)
|
76
|
-
)
|
77
|
-
@timeout = Integer(
|
78
|
-
options.fetch(
|
79
|
-
:timeout,
|
80
|
-
ENV.fetch('DISQUE_TIMEOUT', '2000')
|
81
|
-
)
|
82
|
-
)
|
83
|
-
|
84
|
-
self.run if options[:run]
|
85
|
-
self
|
86
|
-
end
|
87
|
-
|
88
|
-
def stop
|
89
|
-
@stop = true
|
90
|
-
end
|
91
|
-
|
92
|
-
def run
|
93
|
-
$stdout.puts("Disc::Worker listening in #{queues}")
|
94
|
-
loop do
|
95
|
-
jobs = disque.fetch(from: queues, timeout: timeout, count: count)
|
96
|
-
Array(jobs).each do |queue, msgid, serialized_job|
|
97
|
-
begin
|
98
|
-
job = MessagePack.unpack(serialized_job)
|
99
|
-
instance = Object.const_get(job['class']).new
|
100
|
-
instance.perform(*job['arguments'])
|
101
|
-
disque.call('ACKJOB', msgid)
|
102
|
-
rescue => err
|
103
|
-
Disc.on_error(err, job.update('id' => msgid, 'queue' => queue))
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
break if @stop
|
108
|
-
end
|
109
|
-
ensure
|
110
|
-
disque.quit
|
111
|
-
end
|
46
|
+
def self.serialize(args)
|
47
|
+
JSON.dump(args)
|
112
48
|
end
|
113
49
|
|
114
|
-
|
115
|
-
|
116
|
-
:disque,
|
117
|
-
:disc_options
|
118
|
-
|
119
|
-
def self.included(base)
|
120
|
-
base.extend(ClassMethods)
|
121
|
-
end
|
122
|
-
|
123
|
-
module ClassMethods
|
124
|
-
def disque
|
125
|
-
defined?(@disque) ? @disque : Disc.disque
|
126
|
-
end
|
127
|
-
|
128
|
-
def disque=(disque)
|
129
|
-
@disque = disque
|
130
|
-
end
|
131
|
-
|
132
|
-
def disc(queue: nil, **options)
|
133
|
-
@queue = queue
|
134
|
-
@disc_options = options
|
135
|
-
end
|
136
|
-
|
137
|
-
def disc_options
|
138
|
-
@disc_options ||= {}
|
139
|
-
end
|
140
|
-
|
141
|
-
def queue
|
142
|
-
@queue || Disc.default_queue
|
143
|
-
end
|
144
|
-
|
145
|
-
def enqueue(args = [], at: nil, queue: nil, **options)
|
146
|
-
options = disc_options.merge(options).tap do |opt|
|
147
|
-
opt[:delay] = at.to_time.to_i - DateTime.now.to_time.to_i unless at.nil?
|
148
|
-
end
|
149
|
-
|
150
|
-
disque.push(
|
151
|
-
queue || self.queue,
|
152
|
-
{
|
153
|
-
class: self.name,
|
154
|
-
arguments: Array(args)
|
155
|
-
}.to_msgpack,
|
156
|
-
Disc.disque_timeout,
|
157
|
-
options
|
158
|
-
)
|
159
|
-
end
|
160
|
-
end
|
50
|
+
def self.deserialize(data)
|
51
|
+
JSON.parse(data)
|
161
52
|
end
|
162
53
|
end
|
54
|
+
|
55
|
+
require_relative 'disc/job'
|
56
|
+
require_relative 'disc/version'
|
57
|
+
|
data/lib/disc/job.rb
ADDED
@@ -0,0 +1,127 @@
|
|
1
|
+
module Disc::Job
|
2
|
+
attr_accessor :disque_id,
|
3
|
+
:arguments
|
4
|
+
|
5
|
+
def self.included(base)
|
6
|
+
base.extend(ClassMethods)
|
7
|
+
end
|
8
|
+
|
9
|
+
def info
|
10
|
+
return nil if disque_id.nil?
|
11
|
+
|
12
|
+
Hash[*self.class.disque.call("SHOW", disque_id)]
|
13
|
+
end
|
14
|
+
|
15
|
+
def state
|
16
|
+
info.fetch('state')
|
17
|
+
end
|
18
|
+
|
19
|
+
module ClassMethods
|
20
|
+
def [](disque_id)
|
21
|
+
job_data = disque.call("SHOW", disque_id)
|
22
|
+
return nil if job_data.nil?
|
23
|
+
|
24
|
+
job = self.new
|
25
|
+
job_data = Hash[*job_data]
|
26
|
+
|
27
|
+
job.disque_id = disque_id
|
28
|
+
job.arguments = Disc.deserialize(job_data.fetch('body')).fetch('arguments')
|
29
|
+
|
30
|
+
return job
|
31
|
+
end
|
32
|
+
|
33
|
+
def disque
|
34
|
+
defined?(@disque) ? @disque : Disc.disque
|
35
|
+
end
|
36
|
+
|
37
|
+
def disque=(disque)
|
38
|
+
@disque = disque
|
39
|
+
end
|
40
|
+
|
41
|
+
def disc(queue: nil, **options)
|
42
|
+
@queue = queue
|
43
|
+
@disc_options = options
|
44
|
+
end
|
45
|
+
|
46
|
+
def disc_options
|
47
|
+
@disc_options ||= {}
|
48
|
+
end
|
49
|
+
|
50
|
+
def queue
|
51
|
+
@queue || Disc.default_queue
|
52
|
+
end
|
53
|
+
|
54
|
+
def perform(arguments)
|
55
|
+
self.new.perform(*arguments)
|
56
|
+
end
|
57
|
+
|
58
|
+
## Disc's `#enqueue` is the main user-facing method of a Disc job, it
|
59
|
+
# enqueues a job with a given set of arguments in Disque, so it can be
|
60
|
+
# picked up by a Disc worker process.
|
61
|
+
#
|
62
|
+
## Parameters:
|
63
|
+
#
|
64
|
+
## `arguments` - an optional array of arguments with which to execute
|
65
|
+
# the job's #perform method.
|
66
|
+
#
|
67
|
+
## `at` - an optional named parameter specifying a moment in the
|
68
|
+
# future in which to run the job, must respond to
|
69
|
+
# `#to_time`.
|
70
|
+
#
|
71
|
+
## `queue` - an optional named parameter specifying the name of the
|
72
|
+
# queue in which to store the job, defaults to the class
|
73
|
+
# Disc queue or to 'default' if no Disc queue is specified
|
74
|
+
# in the class.
|
75
|
+
#
|
76
|
+
## `**options` - an optional hash of options to forward internally to
|
77
|
+
# [disque-rb](https://github.com/soveran/disque-rb)'s
|
78
|
+
# `#push` method, valid options are:
|
79
|
+
#
|
80
|
+
## `replicate: <count>` - specifies the number of nodes the job should
|
81
|
+
# be replicated to.
|
82
|
+
#
|
83
|
+
### `delay: <sec>` - specifies a delay time in seconds for the job
|
84
|
+
# to be delivered to a Disc worker, it is ignored
|
85
|
+
# if using the `at` parameter.
|
86
|
+
#
|
87
|
+
### `ttl: <sec>` - specifies the job's time to live in seconds:
|
88
|
+
# after this time, the job is deleted even if
|
89
|
+
# it was not successfully delivered. If not
|
90
|
+
# specified, the default TTL is one day.
|
91
|
+
#
|
92
|
+
### `maxlen: <count>` - specifies that if there are already <count>
|
93
|
+
# messages queued for the specified queue name,
|
94
|
+
# the message is refused.
|
95
|
+
#
|
96
|
+
### `async: true` - asks the server to let the command return ASAP
|
97
|
+
# and replicate the job to other nodes in the background.
|
98
|
+
#
|
99
|
+
#
|
100
|
+
### CAVEATS
|
101
|
+
#
|
102
|
+
## For convenience, any object can be passed as the `arguments` parameter,
|
103
|
+
# `Array.wrap` will be used internally to preserve the array structure.
|
104
|
+
#
|
105
|
+
## The `arguments` parameter is serialized for storage using `Disc.serialize`
|
106
|
+
# and Disc workers picking it up use `Disc.deserialize` on it, both methods
|
107
|
+
# use standard library json but can be overriden by the user
|
108
|
+
#
|
109
|
+
def enqueue(args = [], at: nil, queue: nil, **options)
|
110
|
+
options = disc_options.merge(options).tap do |opt|
|
111
|
+
opt[:delay] = at.to_time.to_i - DateTime.now.to_time.to_i unless at.nil?
|
112
|
+
end
|
113
|
+
|
114
|
+
disque_id = disque.push(
|
115
|
+
queue || self.queue,
|
116
|
+
Disc.serialize({
|
117
|
+
class: self.name,
|
118
|
+
arguments: Array(args)
|
119
|
+
}),
|
120
|
+
Disc.disque_timeout,
|
121
|
+
options
|
122
|
+
)
|
123
|
+
|
124
|
+
return self[disque_id]
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
data/lib/disc/version.rb
CHANGED
data/lib/disc/worker.rb
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'disc'
|
2
|
+
|
3
|
+
|
4
|
+
class Disc::Worker
|
5
|
+
attr_reader :disque,
|
6
|
+
:queues,
|
7
|
+
:timeout,
|
8
|
+
:count
|
9
|
+
|
10
|
+
def self.current
|
11
|
+
@current ||= new
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.run
|
15
|
+
current.run
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.stop
|
19
|
+
current.stop
|
20
|
+
end
|
21
|
+
|
22
|
+
def initialize(options = {})
|
23
|
+
@disque = options.fetch(:disque, Disc.disque)
|
24
|
+
@queues = options.fetch(
|
25
|
+
:queues,
|
26
|
+
ENV.fetch('QUEUES', Disc.default_queue)
|
27
|
+
).split(',')
|
28
|
+
@count = Integer(
|
29
|
+
options.fetch(
|
30
|
+
:count,
|
31
|
+
ENV.fetch('DISQUE_COUNT', '1')
|
32
|
+
)
|
33
|
+
)
|
34
|
+
@timeout = Integer(
|
35
|
+
options.fetch(
|
36
|
+
:timeout,
|
37
|
+
ENV.fetch('DISQUE_TIMEOUT', '2000')
|
38
|
+
)
|
39
|
+
)
|
40
|
+
|
41
|
+
self.run if options[:run]
|
42
|
+
self
|
43
|
+
end
|
44
|
+
|
45
|
+
def stop
|
46
|
+
@stop = true
|
47
|
+
end
|
48
|
+
|
49
|
+
def run
|
50
|
+
$stdout.puts("Disc::Worker listening in #{queues}")
|
51
|
+
loop do
|
52
|
+
jobs = disque.fetch(from: queues, timeout: timeout, count: count)
|
53
|
+
Array(jobs).each do |queue, msgid, serialized_job|
|
54
|
+
begin
|
55
|
+
job = Disc.deserialize(serialized_job)
|
56
|
+
instance = Object.const_get(job['class']).new
|
57
|
+
instance.perform(*job['arguments'])
|
58
|
+
disque.call('ACKJOB', msgid)
|
59
|
+
$stdout.puts("Completed #{job['class']} id #{msgid}")
|
60
|
+
rescue => err
|
61
|
+
Disc.on_error(err, job.update('id' => msgid, 'queue' => queue))
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
break if @stop
|
66
|
+
end
|
67
|
+
ensure
|
68
|
+
disque.quit
|
69
|
+
end
|
70
|
+
end
|
data/test/disc_test.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
require 'cutest'
|
2
2
|
require 'disc'
|
3
|
-
require 'msgpack'
|
4
3
|
require 'pty'
|
5
4
|
require 'timeout'
|
6
5
|
|
@@ -55,20 +54,20 @@ scope do
|
|
55
54
|
end
|
56
55
|
|
57
56
|
test 'jobs are enqueued to the correct Disque queue with appropriate parameters and class' do
|
58
|
-
|
57
|
+
job_instance = Echoer.enqueue(['one argument', { random: 'data' }, 3])
|
59
58
|
|
60
59
|
jobs = Array(Disc.disque.fetch(from: ['test'], timeout: Disc.disque_timeout, count: 1))
|
61
60
|
assert jobs.any?
|
62
61
|
assert_equal 1, jobs.count
|
63
62
|
|
64
63
|
jobs.first.tap do |queue, id, serialized_job|
|
65
|
-
job =
|
64
|
+
job = Disc.deserialize(serialized_job)
|
66
65
|
|
67
66
|
assert job.has_key?('class')
|
68
67
|
assert job.has_key?('arguments')
|
69
68
|
|
70
69
|
assert_equal 'Echoer', job['class']
|
71
|
-
assert_equal
|
70
|
+
assert_equal job_instance.disque_id, id
|
72
71
|
|
73
72
|
args = job['arguments']
|
74
73
|
assert_equal 3, args.size
|
@@ -78,8 +77,29 @@ scope do
|
|
78
77
|
end
|
79
78
|
end
|
80
79
|
|
80
|
+
test 'we get easy access to the job via the job id' do
|
81
|
+
job_instance = Echoer.enqueue(['one argument', { random: 'data' }, 3])
|
82
|
+
|
83
|
+
assert job_instance.is_a?(Echoer)
|
84
|
+
assert !job_instance.disque_id.nil?
|
85
|
+
assert !job_instance.info.nil?
|
86
|
+
|
87
|
+
job = Echoer[job_instance.disque_id]
|
88
|
+
|
89
|
+
assert job.is_a?(Echoer)
|
90
|
+
assert_equal 'queued', job.state
|
91
|
+
assert_equal 3, job.arguments.count
|
92
|
+
assert_equal 'one argument', job.arguments.first
|
93
|
+
end
|
94
|
+
|
95
|
+
test 'we can query the lenght of a given queue' do
|
96
|
+
job_instance = Echoer.enqueue(['one argument', { random: 'data' }, 3])
|
97
|
+
|
98
|
+
assert_equal 1, Disc.qlen(Echoer.queue)
|
99
|
+
end
|
100
|
+
|
81
101
|
test 'enqueue at timestamp behaves properly' do
|
82
|
-
|
102
|
+
job_instance = Echoer.enqueue(['one argument', { random: 'data' }, 3], at: Time.now + 1)
|
83
103
|
|
84
104
|
jobs = Array(Disc.disque.fetch(from: ['test'], timeout: Disc.disque_timeout, count: 1))
|
85
105
|
assert jobs.empty?
|
@@ -95,8 +115,8 @@ scope do
|
|
95
115
|
|
96
116
|
jobs.first.tap do |queue, id, serialized_job|
|
97
117
|
assert_equal 'test', queue
|
98
|
-
assert_equal
|
99
|
-
job =
|
118
|
+
assert_equal job_instance.disque_id, id
|
119
|
+
job = Disc.deserialize(serialized_job)
|
100
120
|
assert job.has_key?('class')
|
101
121
|
assert job.has_key?('arguments')
|
102
122
|
assert_equal 'Echoer', job['class']
|
@@ -107,7 +127,7 @@ scope do
|
|
107
127
|
test 'jobs are executed' do
|
108
128
|
Echoer.enqueue(['one argument', { random: 'data' }, 3])
|
109
129
|
|
110
|
-
run('QUEUES=test ruby -Ilib bin/disc -r ./examples/echoer') do |cout, pid|
|
130
|
+
run('QUEUES=test ruby -Ilib bin/disc -r disc/worker -r ./examples/echoer') do |cout, pid|
|
111
131
|
output = Timeout.timeout(1) { cout.take(3) }
|
112
132
|
jobs = Disc.disque.fetch(from: ['test'], timeout: Disc.disque_timeout, count: 1)
|
113
133
|
assert jobs.nil?
|
@@ -116,9 +136,9 @@ scope do
|
|
116
136
|
end
|
117
137
|
|
118
138
|
test 'Disc.on_error will catch unhandled exceptions and keep disc alive' do
|
119
|
-
Failer.enqueue('this can only end positively')
|
139
|
+
failer = Failer.enqueue('this can only end positively')
|
120
140
|
|
121
|
-
run('QUEUES=test ruby -Ilib bin/disc -r ./examples/failer') do |cout, pid|
|
141
|
+
run('QUEUES=test ruby -Ilib bin/disc -r disc/worker -r ./examples/failer') do |cout, pid|
|
122
142
|
output = Timeout.timeout(1) { cout.take(5) }
|
123
143
|
jobs = Disc.disque.fetch(from: ['test'], timeout: Disc.disque_timeout, count: 1)
|
124
144
|
assert jobs.nil?
|
@@ -139,7 +159,7 @@ scope do
|
|
139
159
|
end
|
140
160
|
|
141
161
|
test 'enqueue supports delay' do
|
142
|
-
|
162
|
+
job_instance = Echoer.enqueue(['one argument', { random: 'data' }, 3], delay: 2)
|
143
163
|
|
144
164
|
jobs = Array(Disc.disque.fetch(from: ['test'], timeout: Disc.disque_timeout, count: 1))
|
145
165
|
assert jobs.empty?
|
@@ -155,7 +175,7 @@ scope do
|
|
155
175
|
end
|
156
176
|
|
157
177
|
test 'enqueue supports retry' do
|
158
|
-
|
178
|
+
job_instance = Echoer.enqueue(['one argument', { random: 'data' }, 3], retry: 1)
|
159
179
|
|
160
180
|
jobs = Array(Disc.disque.fetch(from: ['test'], timeout: Disc.disque_timeout, count: 1))
|
161
181
|
assert jobs.any?
|
@@ -168,7 +188,7 @@ scope do
|
|
168
188
|
end
|
169
189
|
|
170
190
|
test 'enqueue supports ttl' do
|
171
|
-
|
191
|
+
job_instance = Echoer.enqueue(['one argument', { random: 'data' }, 3], ttl: 1)
|
172
192
|
|
173
193
|
sleep 1.5
|
174
194
|
jobs = Array(Disc.disque.fetch(from: ['test'], timeout: Disc.disque_timeout, count: 1))
|
@@ -184,7 +204,7 @@ scope do
|
|
184
204
|
end
|
185
205
|
|
186
206
|
test 'enqueue supports async' do
|
187
|
-
|
207
|
+
job_instance = Echoer.enqueue(['one argument', { random: 'data' }, 3], async: true)
|
188
208
|
|
189
209
|
sleep 1 # async is too fast to reliably assert an empty queue, let's wait instead
|
190
210
|
jobs = Array(Disc.disque.fetch(from: ['test'], timeout: Disc.disque_timeout, count: 1))
|
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.0.
|
4
|
+
version: 0.0.27
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- pote
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-05-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: disque
|
@@ -24,26 +24,6 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 0.0.6
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: msgpack
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ">="
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: 0.5.6
|
34
|
-
- - "<"
|
35
|
-
- !ruby/object:Gem::Version
|
36
|
-
version: 0.6.3
|
37
|
-
type: :runtime
|
38
|
-
prerelease: false
|
39
|
-
version_requirements: !ruby/object:Gem::Requirement
|
40
|
-
requirements:
|
41
|
-
- - ">="
|
42
|
-
- !ruby/object:Gem::Version
|
43
|
-
version: 0.5.6
|
44
|
-
- - "<"
|
45
|
-
- !ruby/object:Gem::Version
|
46
|
-
version: 0.6.3
|
47
27
|
- !ruby/object:Gem::Dependency
|
48
28
|
name: clap
|
49
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -83,8 +63,10 @@ files:
|
|
83
63
|
- examples/greeter.rb
|
84
64
|
- lib/active_job/queue_adapters/disc_adapter.rb
|
85
65
|
- lib/disc.rb
|
66
|
+
- lib/disc/job.rb
|
86
67
|
- lib/disc/testing.rb
|
87
68
|
- lib/disc/version.rb
|
69
|
+
- lib/disc/worker.rb
|
88
70
|
- test/disc_test.rb
|
89
71
|
homepage: https://github.com/pote/disc
|
90
72
|
licenses:
|
@@ -106,7 +88,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
106
88
|
version: '0'
|
107
89
|
requirements: []
|
108
90
|
rubyforge_project:
|
109
|
-
rubygems_version: 2.
|
91
|
+
rubygems_version: 2.5.1
|
110
92
|
signing_key:
|
111
93
|
specification_version: 4
|
112
94
|
summary: A simple and powerful Disque job implementation
|