disc 0.0.21 → 0.0.22

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b6ebc5318a06c998692fa8d5ce44f942f76aa552
4
- data.tar.gz: c8010f716c1b36209c6bdc9327dd62732be6c5cd
3
+ metadata.gz: c6bf616dea2ead6c544788565f1b487ddaedeffa
4
+ data.tar.gz: 191da0a289ac1ec6b1b60d76d547e996b7e56083
5
5
  SHA512:
6
- metadata.gz: fd66d5822dc049f1947a2d57a3159928aab59559f34d566584b43a754a2bb1ca10111022d49697e05c2999928f3a04438779c30e4c65440b70688cb543d0508e
7
- data.tar.gz: a91114eb1133456546a223a254aa0bacf1f754c7c581340a25232ca328d9319d77bc0fd10df89d44cc0ec40e4525ef463bd5a1c23fd48c51738c50e788fafe56
6
+ metadata.gz: 83c6e1a7cf0aaba55e156097a8f02f772227854fb93fcca59d10acd15df8dff8b1d4dc1582af091b1e926f2d5b011f2d122a64eb53223f2d841fbe87ea45485f
7
+ data.tar.gz: 212a4df34ad33ad7865e934e46964517aa77a6127d9545653ee148f9cdfcbfa3bebad9903577e35163939d9888df6e6a1cf2428022224b38319923ea1858dddf
data/.travis.yml ADDED
@@ -0,0 +1,21 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2
4
+ sudo: false
5
+ cache:
6
+ bundler: false
7
+ directories:
8
+ - disque
9
+ - gems
10
+ before_install:
11
+ - test -d disque/.git || git clone -n https://github.com/antirez/disque.git
12
+ - cd disque && git fetch origin && git checkout -f master && make && cd ..
13
+ install:
14
+ - export GEM_HOME=$PWD/gems/$RUBY_VERSION
15
+ - export GEM_PATH=$GEM_HOME:$GEM_PATH
16
+ - export PATH=$GEM_HOME/bin:$PWD/disque/src:$PATH
17
+ - mkdir -p $GEM_HOME
18
+ - which dep || gem install dep
19
+ - dep install
20
+ before_script: disque-server --daemonize yes
21
+ script: make test
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Disc
1
+ # Disc [![Build Status](https://travis-ci.org/pote/disc.svg?branch=master)](https://travis-ci.org/pote/disc)
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
 
@@ -58,10 +58,10 @@ Disc fills the gap between your Ruby service objects and [antirez](http://antire
58
58
  ```bash
59
59
  $ QUEUES=urgent,default disc -r ./disc_init.rb
60
60
  ```
61
-
61
+
62
62
  ## Notes about Jobs
63
63
 
64
- Jobs are fairly straighforward Ruby classes, internally Disc serializes them to MessagePack so they can be stored in Disque, this has a few implications:
64
+ Jobs are fairly straightforward Ruby classes, internally Disc serializes them to MessagePack so they can be stored in Disque, this has a few implications:
65
65
 
66
66
  * Don't enqueue complex objects! Instead of `user`, enqueue `user.id`!
67
67
  * If your job takes multiple arguments, you'll want to pass all those arguments in the first parameter of `#enqueue` as an array.
@@ -72,7 +72,7 @@ Example:
72
72
  class ComplexJob
73
73
  include Disc::Job
74
74
  disc queue: 'urgent'
75
-
75
+
76
76
  def perform(first_parameter, second_parameter)
77
77
  # do things...
78
78
  end
@@ -191,7 +191,7 @@ more information.
191
191
  ## Acknowledgements
192
192
 
193
193
  * To [@foca](https://github.com/foca) for helping me ship a quality thing and putting up with my constant whining.
194
- * To [@antirez](https://github,com/antirez) for Redis, Disque, and his refreshing way of programming wonderful tools.
194
+ * To [@antirez](https://github.com/antirez) for Redis, Disque, and his refreshing way of programming wonderful tools.
195
195
  * To [@soveran](https://github.com/soveran) for pushing me to work on this and publishing gems that keep me enjoying ruby.
196
196
  * To [all contributors](https://github.com/pote/disc/graphs/contributors)
197
197
 
data/lib/disc/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  class Disc
2
- VERSION = "0.0.21"
2
+ VERSION = "0.0.22"
3
3
  end
data/lib/disc.rb CHANGED
@@ -28,6 +28,14 @@ class Disc
28
28
  @disque_timeout = timeout
29
29
  end
30
30
 
31
+ def self.default_queue
32
+ @default_queue ||= 'default'
33
+ end
34
+
35
+ def self.default_queue=(queue)
36
+ @default_queue = queue
37
+ end
38
+
31
39
  def self.on_error(exception, job)
32
40
  $stderr.puts exception
33
41
  end
@@ -101,7 +109,8 @@ class Disc
101
109
  @disque = disque
102
110
  end
103
111
 
104
- def disc(options = {})
112
+ def disc(queue: nil, **options)
113
+ @queue = queue
105
114
  @disc_options = options
106
115
  end
107
116
 
@@ -110,10 +119,14 @@ class Disc
110
119
  end
111
120
 
112
121
  def queue
113
- disc_options.fetch(:queue, 'default')
122
+ @queue || Disc.default_queue
114
123
  end
115
124
 
116
- def enqueue(args = [], at: nil, queue: nil)
125
+ def enqueue(args = [], at: nil, queue: nil, **options)
126
+ options = disc_options.merge(options).tap do |opt|
127
+ opt[:delay] = at.to_time.to_i - DateTime.now.to_time.to_i unless at.nil?
128
+ end
129
+
117
130
  disque.push(
118
131
  queue || self.queue,
119
132
  {
@@ -121,7 +134,7 @@ class Disc
121
134
  arguments: Array(args)
122
135
  }.to_msgpack,
123
136
  Disc.disque_timeout,
124
- delay: at.nil? ? nil : (at.to_time.to_i - DateTime.now.to_time.to_i)
137
+ options
125
138
  )
126
139
  end
127
140
  end
data/test/disc_test.rb CHANGED
@@ -2,6 +2,7 @@ require 'cutest'
2
2
  require 'disc'
3
3
  require 'msgpack'
4
4
  require 'pty'
5
+ require 'timeout'
5
6
 
6
7
  require_relative '../examples/echoer'
7
8
  # class Echoer
@@ -30,10 +31,29 @@ require_relative '../examples/failer'
30
31
  # end
31
32
 
32
33
  prepare do
34
+ Disc.disque_timeout = 1 # 1ms so we don't wait at all.
33
35
  Disc.disque.call('DEBUG', 'FLUSHALL')
34
36
  end
35
37
 
36
38
  scope do
39
+ # Runs a given command, yielding the stdout (as an IO) and the PID (a String).
40
+ # Makes sure the process finishes after the block runs.
41
+ def run(command)
42
+ out, _, pid = PTY.spawn(command)
43
+ yield out, pid
44
+ ensure
45
+ Process.kill("KILL", pid)
46
+ sleep 0.1 # Make sure we give it time to finish.
47
+ end
48
+
49
+ # Checks whether a process is running.
50
+ def is_running?(pid)
51
+ Process.getpgid(pid)
52
+ true
53
+ rescue Errno::ESRCH
54
+ false
55
+ end
56
+
37
57
  test 'jobs are enqueued to the correct Disque queue with appropriate parameters and class' do
38
58
  jobid = Echoer.enqueue(['one argument', { random: 'data' }, 3])
39
59
 
@@ -59,16 +79,16 @@ scope do
59
79
  end
60
80
 
61
81
  test 'enqueue at timestamp behaves properly' do
62
- jobid = Echoer.enqueue(['one argument', { random: 'data' }, 3], at: Time.now + 3)
82
+ jobid = Echoer.enqueue(['one argument', { random: 'data' }, 3], at: Time.now + 1)
63
83
 
64
84
  jobs = Array(Disc.disque.fetch(from: ['test'], timeout: Disc.disque_timeout, count: 1))
65
85
  assert jobs.empty?
66
86
 
67
- sleep 1
87
+ sleep 0.5
68
88
  jobs = Array(Disc.disque.fetch(from: ['test'], timeout: Disc.disque_timeout, count: 1))
69
89
  assert jobs.empty?
70
90
 
71
- sleep 2
91
+ sleep 0.5
72
92
  jobs = Array(Disc.disque.fetch(from: ['test'], timeout: Disc.disque_timeout, count: 1))
73
93
  assert jobs.any?
74
94
  assert_equal 1, jobs.size
@@ -85,68 +105,92 @@ scope do
85
105
  end
86
106
 
87
107
  test 'jobs are executed' do
88
- begin
89
- Echoer.enqueue(['one argument', { random: 'data' }, 3])
90
-
91
- cout, _, pid = PTY.spawn(
92
- 'QUEUES=test,default ruby -Ilib bin/disc -r ./examples/echoer'
93
- )
94
- sleep 0.5
108
+ Echoer.enqueue(['one argument', { random: 'data' }, 3])
95
109
 
110
+ run('QUEUES=test ruby -Ilib bin/disc -r ./examples/echoer') do |cout, pid|
111
+ output = Timeout.timeout(1) { cout.take(3) }
96
112
  jobs = Disc.disque.fetch(from: ['test'], timeout: Disc.disque_timeout, count: 1)
97
113
  assert jobs.nil?
98
-
99
- matched = false
100
- counter = 0
101
- while !matched && counter < 3
102
- counter += 1
103
- matched = cout.gets.match(/First: one argument, Second: {"random"=>"data"}, Third: 3/)
104
- end
105
-
106
- assert matched
107
- ensure
108
- Process.kill("KILL", pid)
114
+ assert output.grep(/First: one argument, Second: {"random"=>"data"}, Third: 3/).any?
109
115
  end
110
116
  end
111
117
 
112
118
  test 'Disc.on_error will catch unhandled exceptions and keep disc alive' do
113
- begin
114
- Failer.enqueue('this can only end positively')
115
-
116
- cout, _, pid = PTY.spawn(
117
- 'QUEUES=test ruby -Ilib bin/disc -r ./examples/failer'
118
- )
119
- sleep 0.5
119
+ Failer.enqueue('this can only end positively')
120
120
 
121
+ run('QUEUES=test ruby -Ilib bin/disc -r ./examples/failer') do |cout, pid|
122
+ output = Timeout.timeout(1) { cout.take(5) }
121
123
  jobs = Disc.disque.fetch(from: ['test'], timeout: Disc.disque_timeout, count: 1)
122
124
  assert jobs.nil?
123
125
 
124
- counter = 0
125
- tasks = {
126
- reported_error: false,
127
- printed_message: false,
128
- printed_job: false
129
- }
130
-
131
- while tasks.values.include?(false) && counter < 5
132
- counter += 1
133
- output = cout.gets
134
-
135
- tasks[:reported_error] = true if output.match(/<insert error reporting here>/)
136
- tasks[:printed_message] = true if output.match(/this can only end positively/)
137
- tasks[:printed_job] = true if output.match(/Failer/)
138
- end
139
-
140
- assert !tasks.values.include?(false)
141
-
142
- begin
143
- Process.getpgid(pid)
144
- assert true
145
- rescue Errno::ESRCH
146
- assert false
147
- end
148
- ensure
149
- Process.kill("KILL", pid)
126
+ assert output.grep(/<insert error reporting here>/).any?
127
+ assert output.grep(/this can only end positively/).any?
128
+ assert output.grep(/Failer/).any?
129
+
130
+ assert is_running?(pid)
150
131
  end
151
132
  end
133
+
134
+ test 'enqueue supports replicate' do
135
+ error = Echoer.enqueue(['one argument', { random: 'data' }, 3], replicate: 100) rescue $!
136
+
137
+ assert_equal RuntimeError, error.class
138
+ assert_equal "NOREPL Not enough reachable nodes for the requested replication level", error.message
139
+ end
140
+
141
+ test 'enqueue supports delay' do
142
+ jobid = Echoer.enqueue(['one argument', { random: 'data' }, 3], delay: 2)
143
+
144
+ jobs = Array(Disc.disque.fetch(from: ['test'], timeout: Disc.disque_timeout, count: 1))
145
+ assert jobs.empty?
146
+
147
+ sleep 1
148
+ jobs = Array(Disc.disque.fetch(from: ['test'], timeout: Disc.disque_timeout, count: 1))
149
+ assert jobs.empty?
150
+
151
+ sleep 2
152
+ jobs = Array(Disc.disque.fetch(from: ['test'], timeout: Disc.disque_timeout, count: 1))
153
+ assert jobs.any?
154
+ assert_equal 1, jobs.size
155
+ end
156
+
157
+ test 'enqueue supports retry' do
158
+ jobid = Echoer.enqueue(['one argument', { random: 'data' }, 3], retry: 1)
159
+
160
+ jobs = Array(Disc.disque.fetch(from: ['test'], timeout: Disc.disque_timeout, count: 1))
161
+ assert jobs.any?
162
+ assert_equal 1, jobs.size
163
+
164
+ sleep 1.5
165
+ jobs = Array(Disc.disque.fetch(from: ['test'], timeout: Disc.disque_timeout, count: 1))
166
+ assert jobs.any?
167
+ assert_equal 1, jobs.size
168
+ end
169
+
170
+ test 'enqueue supports ttl' do
171
+ jobid = Echoer.enqueue(['one argument', { random: 'data' }, 3], ttl: 1)
172
+
173
+ sleep 1.5
174
+ jobs = Array(Disc.disque.fetch(from: ['test'], timeout: Disc.disque_timeout, count: 1))
175
+ assert jobs.empty?
176
+ end
177
+
178
+ test 'enqueue supports maxlen' do
179
+ Echoer.enqueue(['one argument', { random: 'data' }, 3], maxlen: 1)
180
+ # disque off by-one bug? see: https://github.com/antirez/disque/issues/109
181
+ Echoer.enqueue(['one argument', { random: 'data' }, 3], maxlen: 1)
182
+ error = Echoer.enqueue(['one argument', { random: 'data' }, 3], maxlen: 1) rescue $!
183
+
184
+ assert_equal RuntimeError, error.class
185
+ assert_equal "MAXLEN Queue is already longer than the specified MAXLEN count", error.message
186
+ end
187
+
188
+ test 'enqueue supports async' do
189
+ jobid = Echoer.enqueue(['one argument', { random: 'data' }, 3], async: true)
190
+
191
+ sleep 1 # async is too fast to reliably assert an empty queue, let's wait instead
192
+ jobs = Array(Disc.disque.fetch(from: ['test'], timeout: Disc.disque_timeout, count: 1))
193
+ assert jobs.any?
194
+ assert_equal 1, jobs.size
195
+ end
152
196
  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.0.21
4
+ version: 0.0.22
5
5
  platform: ruby
6
6
  authors:
7
7
  - pote
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-08-05 00:00:00.000000000 Z
11
+ date: 2015-08-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: disque
@@ -63,6 +63,7 @@ files:
63
63
  - ".env.sample"
64
64
  - ".gems"
65
65
  - ".gitignore"
66
+ - ".travis.yml"
66
67
  - 13Floor-circulo-1.png
67
68
  - CONTRIBUTING.md
68
69
  - LICENSE