queuel 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.cane +3 -0
- data/.gitignore +1 -1
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile.lock +112 -0
- data/Guardfile +22 -0
- data/README.md +17 -11
- data/Rakefile +7 -0
- data/lib/queuel.rb +50 -27
- data/lib/queuel/base/engine.rb +35 -0
- data/lib/queuel/base/message.rb +32 -0
- data/lib/queuel/base/poller.rb +161 -0
- data/lib/queuel/base/queue.rb +59 -0
- data/lib/queuel/client.rb +15 -3
- data/lib/queuel/configurator.rb +65 -0
- data/lib/queuel/introspect.rb +11 -0
- data/lib/queuel/iron_mq/engine.rb +11 -17
- data/lib/queuel/iron_mq/message.rb +5 -26
- data/lib/queuel/iron_mq/poller.rb +8 -111
- data/lib/queuel/iron_mq/queue.rb +13 -24
- data/lib/queuel/null/engine.rb +3 -7
- data/lib/queuel/null/message.rb +1 -16
- data/lib/queuel/null/poller.rb +2 -114
- data/lib/queuel/null/queue.rb +6 -9
- data/lib/queuel/version.rb +1 -1
- data/queuel.gemspec +10 -0
- data/spec/lib/queuel/base/queue_spec.rb +23 -0
- data/spec/lib/queuel/client_spec.rb +30 -0
- data/spec/lib/queuel/configurator_spec.rb +32 -0
- data/spec/lib/queuel/iron_mq/engine_spec.rb +28 -0
- data/spec/lib/queuel/iron_mq/message_spec.rb +2 -2
- data/spec/lib/queuel/iron_mq/poller_spec.rb +15 -1
- data/spec/lib/queuel/iron_mq/queue_spec.rb +2 -2
- data/spec/lib/queuel_spec.rb +12 -7
- data/spec/spec_helper.rb +4 -0
- data/spec/support/engine_shared_example.rb +4 -2
- data/spec/support/message_shared_example.rb +2 -11
- data/spec/support/poller_shared_example.rb +23 -57
- data/spec/support/queue_shared_example.rb +14 -1
- metadata +163 -4
data/.cane
ADDED
data/.gitignore
CHANGED
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
queuel
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.9.3
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
queuel (0.1.0)
|
5
|
+
mono_logger
|
6
|
+
thread
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: https://rubygems.org/
|
10
|
+
specs:
|
11
|
+
cane (2.5.2)
|
12
|
+
parallel
|
13
|
+
coderay (1.0.9)
|
14
|
+
diff-lcs (1.2.4)
|
15
|
+
ethon (0.5.12)
|
16
|
+
ffi (>= 1.3.0)
|
17
|
+
mime-types (~> 1.18)
|
18
|
+
ffi (1.8.1)
|
19
|
+
ffi (1.8.1-java)
|
20
|
+
formatador (0.2.4)
|
21
|
+
guard (1.8.0)
|
22
|
+
formatador (>= 0.2.4)
|
23
|
+
listen (>= 1.0.0)
|
24
|
+
lumberjack (>= 1.0.2)
|
25
|
+
pry (>= 0.9.10)
|
26
|
+
thor (>= 0.14.6)
|
27
|
+
guard-bundler (1.0.0)
|
28
|
+
bundler (~> 1.0)
|
29
|
+
guard (~> 1.1)
|
30
|
+
guard-cane (0.1.2)
|
31
|
+
cane
|
32
|
+
guard
|
33
|
+
guard-rspec (3.0.0)
|
34
|
+
guard (>= 1.8)
|
35
|
+
rspec (~> 2.13)
|
36
|
+
iron_core (0.6.2)
|
37
|
+
rest (>= 2.2.0)
|
38
|
+
iron_mq (4.0.3)
|
39
|
+
iron_core (>= 0.5.1)
|
40
|
+
json (1.7.7)
|
41
|
+
json (1.7.7-java)
|
42
|
+
listen (1.1.1)
|
43
|
+
rb-fsevent (>= 0.9.3)
|
44
|
+
rb-inotify (>= 0.9)
|
45
|
+
rb-kqueue (>= 0.2)
|
46
|
+
lumberjack (1.0.3)
|
47
|
+
method_source (0.8.1)
|
48
|
+
mime-types (1.23)
|
49
|
+
mono_logger (1.0.1)
|
50
|
+
multi_json (1.7.3)
|
51
|
+
parallel (0.6.5)
|
52
|
+
pry (0.9.12.2)
|
53
|
+
coderay (~> 1.0.5)
|
54
|
+
method_source (~> 0.8)
|
55
|
+
slop (~> 3.4)
|
56
|
+
pry (0.9.12.2-java)
|
57
|
+
coderay (~> 1.0.5)
|
58
|
+
method_source (~> 0.8)
|
59
|
+
slop (~> 3.4)
|
60
|
+
spoon (~> 0.0)
|
61
|
+
rake (10.0.4)
|
62
|
+
rb-fchange (0.0.6)
|
63
|
+
ffi
|
64
|
+
rb-fsevent (0.9.3)
|
65
|
+
rb-inotify (0.9.0)
|
66
|
+
ffi (>= 0.5.0)
|
67
|
+
rb-kqueue (0.2.0)
|
68
|
+
ffi (>= 0.5.0)
|
69
|
+
rest (2.6.0)
|
70
|
+
rest-client (>= 0.3.0)
|
71
|
+
rest-client (1.6.7)
|
72
|
+
mime-types (>= 1.16)
|
73
|
+
rspec (2.13.0)
|
74
|
+
rspec-core (~> 2.13.0)
|
75
|
+
rspec-expectations (~> 2.13.0)
|
76
|
+
rspec-mocks (~> 2.13.0)
|
77
|
+
rspec-core (2.13.1)
|
78
|
+
rspec-expectations (2.13.0)
|
79
|
+
diff-lcs (>= 1.1.3, < 2.0)
|
80
|
+
rspec-mocks (2.13.1)
|
81
|
+
simplecov (0.7.1)
|
82
|
+
multi_json (~> 1.0)
|
83
|
+
simplecov-html (~> 0.7.1)
|
84
|
+
simplecov-html (0.7.1)
|
85
|
+
slop (3.4.5)
|
86
|
+
spoon (0.0.4)
|
87
|
+
ffi
|
88
|
+
thor (0.18.1)
|
89
|
+
thread (0.0.8)
|
90
|
+
typhoeus (0.6.3)
|
91
|
+
ethon (~> 0.5.11)
|
92
|
+
|
93
|
+
PLATFORMS
|
94
|
+
java
|
95
|
+
ruby
|
96
|
+
|
97
|
+
DEPENDENCIES
|
98
|
+
bundler (~> 1.3)
|
99
|
+
cane
|
100
|
+
guard-bundler
|
101
|
+
guard-cane
|
102
|
+
guard-rspec
|
103
|
+
iron_mq
|
104
|
+
json (~> 1.7.7)
|
105
|
+
queuel!
|
106
|
+
rake
|
107
|
+
rb-fchange
|
108
|
+
rb-fsevent
|
109
|
+
rb-inotify
|
110
|
+
rspec
|
111
|
+
simplecov
|
112
|
+
typhoeus
|
data/Guardfile
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
guard 'bundler' do
|
5
|
+
watch('Gemfile')
|
6
|
+
watch(/^.+\.gemspec/)
|
7
|
+
end
|
8
|
+
|
9
|
+
guard :cane do
|
10
|
+
watch(%r{^lib/.+\.rb$})
|
11
|
+
end
|
12
|
+
|
13
|
+
guard 'rspec',
|
14
|
+
all_on_start: true,
|
15
|
+
keep_failed: true,
|
16
|
+
rvm: ["1.9.3-p392@queuel"] do
|
17
|
+
# would like to add "jruby-1.7.3@queuel", "rbx-head@queuel"
|
18
|
+
watch(%r{^spec/.+\.rb$}) { "spec" }
|
19
|
+
watch(%r{^lib/queuel/base/(.+)\.rb$}) { |m| ["spec/lib/queuel/iron_mq/#{m[1]}_spec.rb", "spec/lib/queuel/null/#{m[1]}_spec.rb"] }
|
20
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
21
|
+
watch('spec/spec_helper.rb') { "spec" }
|
22
|
+
end
|
data/README.md
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# Queuel
|
2
|
+
[![Gem Version](https://badge.fury.io/rb/queuel.png)](http://badge.fury.io/rb/queuel)
|
2
3
|
[![Build Status](https://travis-ci.org/sportngin/queuel.png?branch=master)](https://travis-ci.org/sportngin/queuel)
|
3
4
|
|
4
5
|
Queuel is a kewl, lite wrapper around Queue interfaces. Currently it implements:
|
@@ -41,6 +42,16 @@ Queuel.configure do
|
|
41
42
|
|
42
43
|
# currently only [:iron_mq, :null] available
|
43
44
|
engine :iron_mq
|
45
|
+
|
46
|
+
# For Queuel.recevier {} you can configure more than one thread to
|
47
|
+
# handle incoming messages
|
48
|
+
receiver_threads 3 # default: 1
|
49
|
+
|
50
|
+
# Logging: Default is MonoLogger, because its a non-blocking log-extension
|
51
|
+
# To the standard lib Logger. Any Log4r solution should work.
|
52
|
+
logger Logger # default: MonoLogger.new(STDOUT)
|
53
|
+
|
54
|
+
log_level MonoLogger::DEBUG # default: MonoLogger::ERROR # => 3
|
44
55
|
end
|
45
56
|
```
|
46
57
|
|
@@ -49,7 +60,7 @@ end
|
|
49
60
|
### General Queue API
|
50
61
|
|
51
62
|
```ruby
|
52
|
-
# Using default Queue
|
63
|
+
# Using default Queue from config
|
53
64
|
Queuel.pop
|
54
65
|
Queuel.push "My message to you"
|
55
66
|
Queuel.receive do |message|
|
@@ -63,22 +74,16 @@ Queuel.with("officials").receive do |message|
|
|
63
74
|
puts "I received #{message.body}" # NOTE the message interface may change, this is currently not wrapped by the gem
|
64
75
|
end
|
65
76
|
|
66
|
-
# Timeout the receiving
|
67
|
-
Queuel.receive poll_timeout: 60 do |message|
|
68
|
-
puts "I received #{message.body}" # NOTE the message interface may change, this is currently not wrapped by the gem
|
69
|
-
end
|
70
|
-
|
71
|
-
# Don't receive more than 10 nil messages
|
72
|
-
Queuel.receive max_consecutive_fails: 10 do |message|
|
73
|
-
puts "I received #{message.body}" # NOTE the message interface may change, this is currently not wrapped by the gem
|
74
|
-
end
|
75
|
-
|
76
77
|
# Break on nil
|
77
78
|
Queuel.receive break_if_nil: true do |message|
|
78
79
|
puts "I received #{message.body}" # NOTE the message interface may change, this is currently not wrapped by the gem
|
79
80
|
end
|
80
81
|
```
|
81
82
|
|
83
|
+
#### Caveats of the receiver
|
84
|
+
|
85
|
+
* Your block must return true in order to not replace the message to the Queue
|
86
|
+
|
82
87
|
### The message
|
83
88
|
|
84
89
|
```ruby
|
@@ -91,6 +96,7 @@ message.delete # => Delete the message
|
|
91
96
|
|
92
97
|
* Implement AMQP
|
93
98
|
* Configureable exponential back-off on `receive`
|
99
|
+
* Provide a Daemon
|
94
100
|
|
95
101
|
## Contributing
|
96
102
|
|
data/Rakefile
CHANGED
@@ -4,3 +4,10 @@ require 'rspec/core/rake_task'
|
|
4
4
|
RSpec::Core::RakeTask.new(:spec)
|
5
5
|
|
6
6
|
task :default => :spec
|
7
|
+
|
8
|
+
namespace :spec do
|
9
|
+
desc "run just tasks flagged for perf checks"
|
10
|
+
RSpec::Core::RakeTask.new(:perf) do |t|
|
11
|
+
t.rspec_opts = ['--tag perf', '--profile']
|
12
|
+
end
|
13
|
+
end
|
data/lib/queuel.rb
CHANGED
@@ -1,26 +1,38 @@
|
|
1
1
|
require "queuel/version"
|
2
2
|
require "forwardable"
|
3
|
-
require "queuel/
|
3
|
+
require "queuel/configurator"
|
4
|
+
require "queuel/introspect"
|
5
|
+
|
6
|
+
require "queuel/base/engine"
|
7
|
+
require "queuel/base/queue"
|
8
|
+
require "queuel/base/message"
|
9
|
+
require "queuel/base/poller"
|
10
|
+
|
4
11
|
require "queuel/null/engine"
|
5
|
-
require "queuel/null/poller"
|
6
12
|
require "queuel/null/queue"
|
7
|
-
require "queuel/
|
13
|
+
require "queuel/null/message"
|
14
|
+
require "queuel/null/poller"
|
15
|
+
|
8
16
|
require "queuel/iron_mq/engine"
|
9
|
-
require "queuel/iron_mq/poller"
|
10
17
|
require "queuel/iron_mq/queue"
|
18
|
+
require "queuel/iron_mq/message"
|
19
|
+
require "queuel/iron_mq/poller"
|
20
|
+
|
11
21
|
require "queuel/client"
|
12
22
|
|
13
23
|
module Queuel
|
24
|
+
extend Introspect
|
14
25
|
class << self
|
15
26
|
extend Forwardable
|
16
27
|
def_delegators :client, :push, :pop, :receive, :with
|
17
|
-
def_delegators :config, :credentials, :default_queue
|
28
|
+
def_delegators :config, :credentials, :default_queue, :receiver_threads
|
18
29
|
alias << pop
|
19
30
|
end
|
20
31
|
|
21
32
|
def self.engine
|
22
33
|
requires
|
23
|
-
|
34
|
+
warn_engine_selection
|
35
|
+
const_with_nesting engine_const_name
|
24
36
|
end
|
25
37
|
|
26
38
|
def self.configure(&block)
|
@@ -35,34 +47,45 @@ module Queuel
|
|
35
47
|
Client.new engine, credentials
|
36
48
|
end
|
37
49
|
|
50
|
+
def self.logger
|
51
|
+
config.logger.tap { |log|
|
52
|
+
log.level = config.log_level
|
53
|
+
}
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def self.warn_engine_selection
|
59
|
+
@warned_null_engine ||= logger.warn(engine_config[:message])
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.engine_config
|
63
|
+
engines.fetch(config.engine) { engines[:null] }
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.configured_engine_name
|
67
|
+
engine_config[:const]
|
68
|
+
end
|
69
|
+
|
38
70
|
def self.engines
|
39
71
|
{
|
40
|
-
iron_mq: {
|
41
|
-
|
72
|
+
iron_mq: {
|
73
|
+
require: 'iron_mq',
|
74
|
+
const: "IronMq",
|
75
|
+
message: "Using IronMQ"
|
76
|
+
},
|
77
|
+
null: {
|
78
|
+
const: "Null",
|
79
|
+
message: "Using Null Engine, for compatability."
|
80
|
+
}
|
42
81
|
}
|
43
82
|
end
|
44
83
|
|
45
84
|
def self.requires
|
46
|
-
require
|
47
|
-
end
|
48
|
-
|
49
|
-
def self.const_name
|
50
|
-
"Queuel::#{engines.fetch(config.engine, {}).fetch(:const, nil) || engines[:null][:const]}::Engine"
|
85
|
+
require engine_config[:require] if engine_config[:require]
|
51
86
|
end
|
52
87
|
|
53
|
-
|
54
|
-
|
55
|
-
params.each do |name|
|
56
|
-
attr_accessor name
|
57
|
-
define_method name do |*values|
|
58
|
-
value = values.first
|
59
|
-
value ? self.send("#{name}=", value) : instance_variable_get("@#{name}")
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
param :credentials
|
65
|
-
param :engine
|
66
|
-
param :default_queue
|
88
|
+
def self.engine_const_name
|
89
|
+
"Queuel::#{configured_engine_name}::Engine"
|
67
90
|
end
|
68
91
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Queuel
|
2
|
+
module Base
|
3
|
+
class Engine
|
4
|
+
extend Introspect
|
5
|
+
def self.inherited(klass)
|
6
|
+
klass.class_eval do
|
7
|
+
def queue_klass
|
8
|
+
self.class.const_with_nesting "Queue"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(credentials = {})
|
14
|
+
self.credentials = credentials
|
15
|
+
self.memoized_queues = {}
|
16
|
+
end
|
17
|
+
|
18
|
+
def queue(which_queue)
|
19
|
+
memoized_queues[which_queue.to_s] ||= queue_klass.new(client, which_queue)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
attr_accessor :credentials
|
24
|
+
attr_accessor :memoized_queues
|
25
|
+
|
26
|
+
def client
|
27
|
+
@client ||= client_klass.new credentials
|
28
|
+
end
|
29
|
+
|
30
|
+
def client_klass
|
31
|
+
raise NotImplementedError, "Must define a Queue class"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Queuel
|
2
|
+
module Base
|
3
|
+
class Message
|
4
|
+
def initialize(message_object)
|
5
|
+
self.message_object = message_object
|
6
|
+
end
|
7
|
+
|
8
|
+
def delete
|
9
|
+
raise NotImplementedError, "must define method #delete"
|
10
|
+
end
|
11
|
+
|
12
|
+
def empty?
|
13
|
+
body.to_s.empty?
|
14
|
+
end
|
15
|
+
alias blank? empty?
|
16
|
+
|
17
|
+
def present?
|
18
|
+
!empty?
|
19
|
+
end
|
20
|
+
|
21
|
+
attr_reader :id
|
22
|
+
attr_reader :body
|
23
|
+
attr_reader :queue
|
24
|
+
|
25
|
+
private
|
26
|
+
attr_accessor :message_object
|
27
|
+
attr_writer :id
|
28
|
+
attr_writer :body
|
29
|
+
attr_writer :queue
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,161 @@
|
|
1
|
+
require 'thread'
|
2
|
+
require "thread/pool"
|
3
|
+
require "forwardable"
|
4
|
+
module Queuel
|
5
|
+
module Base
|
6
|
+
class Poller
|
7
|
+
extend Forwardable
|
8
|
+
def_delegators :Queuel, :logger
|
9
|
+
|
10
|
+
def initialize(queue, param_block, options = {}, workers = 1)
|
11
|
+
self.workers = workers
|
12
|
+
self.queue = queue
|
13
|
+
self.options = options || {}
|
14
|
+
self.inst_block = param_block
|
15
|
+
self.tries = 0
|
16
|
+
self.continue_looping = true
|
17
|
+
end
|
18
|
+
|
19
|
+
def poll
|
20
|
+
register_trappers
|
21
|
+
logger.debug("Beginning Poll...")
|
22
|
+
self.master = master_thread
|
23
|
+
log_action(:joining, :master) { master.join }
|
24
|
+
rescue SignalException => e
|
25
|
+
logger.warn "Caught (#{e}), shutting Poller down"
|
26
|
+
log_action(:killing, :poller, :warn) { shutdown }
|
27
|
+
end
|
28
|
+
|
29
|
+
protected
|
30
|
+
attr_accessor :tries
|
31
|
+
attr_accessor :workers
|
32
|
+
attr_accessor :inst_block
|
33
|
+
|
34
|
+
private
|
35
|
+
attr_accessor :master
|
36
|
+
attr_accessor :queue
|
37
|
+
attr_accessor :args
|
38
|
+
attr_accessor :options
|
39
|
+
attr_accessor :continue_looping
|
40
|
+
|
41
|
+
def register_trappers
|
42
|
+
trap(:SIGINT) { shutdown }
|
43
|
+
trap(:INT) { shutdown }
|
44
|
+
end
|
45
|
+
|
46
|
+
def log_action(verb, subject, level = :debug)
|
47
|
+
verb = verb.to_s.upcase.gsub(/\_/, " ")
|
48
|
+
subject = subject.to_s.upcase.gsub(/\_/, " ")
|
49
|
+
logger.public_send level, "#{verb} #{subject} START"
|
50
|
+
yield
|
51
|
+
logger.public_send level, "#{verb} #{subject} COMPLETE"
|
52
|
+
end
|
53
|
+
|
54
|
+
def shutdown
|
55
|
+
log_action(:shutting_down, :thread_pool) { pool.shutdown }
|
56
|
+
log_action(:killing, :master_thread) { master.kill }
|
57
|
+
log_action(:killing, :loop) { quit_looping! }
|
58
|
+
end
|
59
|
+
|
60
|
+
def pool
|
61
|
+
@pool ||= Thread.pool workers
|
62
|
+
end
|
63
|
+
|
64
|
+
def master_thread
|
65
|
+
Thread.new do
|
66
|
+
master_looper
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def peek_options
|
71
|
+
{}
|
72
|
+
end
|
73
|
+
|
74
|
+
def peek
|
75
|
+
queue.peek peek_options
|
76
|
+
end
|
77
|
+
|
78
|
+
def queue_size # TODO optionize the peek options
|
79
|
+
Array(peek).size
|
80
|
+
end
|
81
|
+
|
82
|
+
def process_off_peek
|
83
|
+
mem_queue_size = queue_size
|
84
|
+
if mem_queue_size > 0
|
85
|
+
reset_tries
|
86
|
+
mem_queue_size.times do
|
87
|
+
process_on_thread
|
88
|
+
end
|
89
|
+
else
|
90
|
+
tried
|
91
|
+
quit_looping! if quit_on_empty?
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def process_on_thread
|
96
|
+
pool.process do
|
97
|
+
process_message
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def process_message
|
102
|
+
register_trappers
|
103
|
+
message = pop_new_message
|
104
|
+
message.delete if self.inst_block.call message
|
105
|
+
rescue => e
|
106
|
+
logger.warn "Received #{e} when processing #{message}"
|
107
|
+
logger.warn "Backtrace:"
|
108
|
+
logger.warn e.backtrace
|
109
|
+
end
|
110
|
+
|
111
|
+
def master_looper
|
112
|
+
loop do
|
113
|
+
break unless continue_looping?
|
114
|
+
process_off_peek
|
115
|
+
sleep sleep_time
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def built_options
|
120
|
+
raise NotImplementedError
|
121
|
+
end
|
122
|
+
|
123
|
+
def continue_looping?
|
124
|
+
!!continue_looping
|
125
|
+
end
|
126
|
+
|
127
|
+
def break_if_nil?
|
128
|
+
!!options[:break_if_nil]
|
129
|
+
end
|
130
|
+
alias quit_on_empty? break_if_nil?
|
131
|
+
|
132
|
+
def quit_looping!
|
133
|
+
self.continue_looping = false
|
134
|
+
end
|
135
|
+
|
136
|
+
def pop_new_message
|
137
|
+
queue.pop built_options
|
138
|
+
end
|
139
|
+
|
140
|
+
def start_sleep_time
|
141
|
+
0
|
142
|
+
end
|
143
|
+
|
144
|
+
def increment_sleep_time
|
145
|
+
0.1
|
146
|
+
end
|
147
|
+
|
148
|
+
def sleep_time
|
149
|
+
tries < 30 ? ((start_sleep_time + increment_sleep_time) * tries) : 3
|
150
|
+
end
|
151
|
+
|
152
|
+
def reset_tries
|
153
|
+
self.tries = 0
|
154
|
+
end
|
155
|
+
|
156
|
+
def tried
|
157
|
+
self.tries += 1
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|