queuel 0.0.1 → 0.1.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.
- 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
|
+
[](http://badge.fury.io/rb/queuel)
|
2
3
|
[](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
|