stalking 0.1.0 → 0.1.1
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/.travis.yml +10 -0
- data/Gemfile +6 -0
- data/README.md +11 -4
- data/lib/stalking/consumer.rb +25 -23
- data/lib/stalking/null_logger.rb +11 -0
- data/lib/stalking/producer.rb +4 -4
- data/lib/stalking/version.rb +1 -1
- data/lib/stalking.rb +1 -1
- data/stalking.gemspec +3 -1
- data/test/stalking/consumer_test.rb +2 -9
- data/test/stalking/null_logger_test.rb +29 -0
- data/test/stalking/producer_test.rb +14 -13
- data/test/stalking/test_logger.rb +12 -0
- data/test/test_helper.rb +22 -0
- metadata +42 -6
data/.travis.yml
ADDED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
|
2
|
+
[](http://travis-ci.org/mrkamel/stalking)
|
2
3
|
[](https://codeclimate.com/github/mrkamel/stalking)
|
4
|
+
[](http://badge.fury.io/rb/stalking)
|
3
5
|
[](http://stillmaintained.com/mrkamel/stalking)
|
6
|
+
[](https://gemnasium.com/mrkamel/stalking)
|
4
7
|
|
5
8
|
# Stalking
|
6
9
|
|
@@ -21,12 +24,16 @@ minimal changes driven by design decisions and its additional feature set.
|
|
21
24
|
|
22
25
|
Add this line to your application's Gemfile:
|
23
26
|
|
24
|
-
gem 'stalking'
|
27
|
+
gem 'stalking'
|
25
28
|
|
26
29
|
And then execute:
|
27
30
|
|
28
31
|
$ bundle
|
29
32
|
|
33
|
+
Or install it yourself as:
|
34
|
+
|
35
|
+
$ gem install stalking
|
36
|
+
|
30
37
|
## Usage
|
31
38
|
|
32
39
|
Stalking provides two modes of operation, a producer and a consumer mode.
|
@@ -154,11 +161,11 @@ when a single server is down, of course require some time for the error
|
|
154
161
|
detection and processing. This usually should not be a big issue, except there
|
155
162
|
is some temporary lag between the producer and the beanstalkd server. The
|
156
163
|
producer then has to wait for a timeout and while the producer is waiting for
|
157
|
-
the timeout it will block your application. The default timeout is
|
158
|
-
|
164
|
+
the timeout it will block your application. The default timeout is 1 second,
|
165
|
+
but you can change the timeout via:
|
159
166
|
|
160
167
|
```ruby
|
161
|
-
Stalking::Producer.new :timeout => 0.
|
168
|
+
Stalking::Producer.new :timeout => 0.5 # Set timeout to 500 milliseconds
|
162
169
|
```
|
163
170
|
|
164
171
|
The optimal timeout for your setup depends on your network connection, the
|
data/lib/stalking/consumer.rb
CHANGED
@@ -3,9 +3,7 @@ module Stalking
|
|
3
3
|
class Consumer
|
4
4
|
def initialize(options = {}, &block)
|
5
5
|
@servers = options[:servers] || ["localhost:11300"]
|
6
|
-
|
7
|
-
@logger = options[:logger]
|
8
|
-
|
6
|
+
@logger = options[:logger] || Stalking::NullLogger.new
|
9
7
|
@handlers = Handlers.new
|
10
8
|
|
11
9
|
if block_given?
|
@@ -34,29 +32,13 @@ module Stalking
|
|
34
32
|
job = connection.reserve
|
35
33
|
|
36
34
|
lock do
|
37
|
-
|
38
|
-
|
39
|
-
if handler = @handlers.job_handlers[name]
|
40
|
-
begin
|
41
|
-
Timeout::timeout(job.ttr - 1) do
|
42
|
-
handle @handlers.before_handlers, name, args
|
43
|
-
|
44
|
-
handler.call args
|
45
|
-
|
46
|
-
handle @handlers.after_handlers, name, args
|
47
|
-
end
|
48
|
-
rescue Beanstalk::NotConnected => e
|
49
|
-
raise e # Re-raise
|
50
|
-
rescue Timeout::Error, StandardError => e
|
51
|
-
handle_error e, name, args
|
52
|
-
end
|
53
|
-
end
|
35
|
+
perform job
|
54
36
|
|
55
37
|
job.delete
|
56
38
|
end
|
57
39
|
end
|
58
40
|
rescue EOFError, Beanstalk::NotConnected => e
|
59
|
-
@logger.
|
41
|
+
@logger.fatal e
|
60
42
|
|
61
43
|
sleep 1
|
62
44
|
|
@@ -64,11 +46,31 @@ module Stalking
|
|
64
46
|
|
65
47
|
retry
|
66
48
|
rescue => e
|
67
|
-
@logger.
|
49
|
+
@logger.fatal e
|
68
50
|
|
69
51
|
raise e
|
70
52
|
end
|
71
53
|
|
54
|
+
def perform(job)
|
55
|
+
name, args = JSON.parse(job.body)
|
56
|
+
|
57
|
+
if handler = @handlers.job_handlers[name]
|
58
|
+
begin
|
59
|
+
Timeout::timeout(job.ttr - 1) do
|
60
|
+
handle @handlers.before_handlers, name, args
|
61
|
+
|
62
|
+
handler.call args
|
63
|
+
|
64
|
+
handle @handlers.after_handlers, name, args
|
65
|
+
end
|
66
|
+
rescue Beanstalk::NotConnected => e
|
67
|
+
raise e # Re-raise
|
68
|
+
rescue Timeout::Error, StandardError => e
|
69
|
+
handle_error e, name, args
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
72
74
|
def looping
|
73
75
|
continue = true
|
74
76
|
|
@@ -98,7 +100,7 @@ module Stalking
|
|
98
100
|
|
99
101
|
@connection
|
100
102
|
rescue Beanstalk::NotConnected => e
|
101
|
-
@logger.
|
103
|
+
@logger.fatal e
|
102
104
|
|
103
105
|
sleep 1
|
104
106
|
|
data/lib/stalking/producer.rb
CHANGED
@@ -6,7 +6,7 @@ module Stalking
|
|
6
6
|
@pri = options[:pri] || 65536
|
7
7
|
@delay = options[:delay] || 0
|
8
8
|
@ttr = options[:ttr] || 120
|
9
|
-
@logger = options[:logger]
|
9
|
+
@logger = options[:logger] || Stalking::NullLogger.new
|
10
10
|
@servers = options[:servers] || ["localhost:11300"]
|
11
11
|
@tries = options[:tries] || [@servers.size, 2].max
|
12
12
|
|
@@ -14,7 +14,7 @@ module Stalking
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def enqueue(name, args = {}, options = {})
|
17
|
-
@logger.
|
17
|
+
@logger.info "Enqueue #{name.inspect} with #{args.inspect} and #{options.inspect}"
|
18
18
|
|
19
19
|
# Send the job to a random server.
|
20
20
|
|
@@ -22,7 +22,7 @@ module Stalking
|
|
22
22
|
return true if enqueue_at(server, name, args, options)
|
23
23
|
end
|
24
24
|
|
25
|
-
@logger.
|
25
|
+
@logger.error "Enqueue #{name.inspect} with #{args.inspect} and #{options.inspect} failed"
|
26
26
|
|
27
27
|
# All servers are currently unavailable.
|
28
28
|
# Enqueuing the job has failed.
|
@@ -43,7 +43,7 @@ module Stalking
|
|
43
43
|
rescue Beanstalk::NotConnected, Timeout::Error, StandardError => e
|
44
44
|
@connections[server] = nil # Reset the connection.
|
45
45
|
|
46
|
-
@logger.
|
46
|
+
@logger.fatal e
|
47
47
|
|
48
48
|
false
|
49
49
|
end
|
data/lib/stalking/version.rb
CHANGED
data/lib/stalking.rb
CHANGED
data/stalking.gemspec
CHANGED
@@ -18,9 +18,11 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.require_paths = ["lib"]
|
19
19
|
|
20
20
|
s.add_development_dependency "rake"
|
21
|
+
s.add_development_dependency "minitest"
|
22
|
+
s.add_development_dependency "bundler"
|
23
|
+
s.add_development_dependency "mocha"
|
21
24
|
|
22
25
|
s.add_dependency "beanstalk-client"
|
23
26
|
s.add_dependency "json_pure"
|
24
|
-
s.add_dependency "andand"
|
25
27
|
end
|
26
28
|
|
@@ -1,14 +1,7 @@
|
|
1
1
|
|
2
|
-
|
2
|
+
require File.expand_path("../../test_helper", __FILE__)
|
3
3
|
|
4
|
-
|
5
|
-
require "test/unit"
|
6
|
-
require "timeout"
|
7
|
-
|
8
|
-
require File.expand_path("../beanstalk", __FILE__)
|
9
|
-
require File.expand_path("../test_logger", __FILE__)
|
10
|
-
|
11
|
-
class Stalking::ConsumerTest < Test::Unit::TestCase
|
4
|
+
class Stalking::ConsumerTest < Minitest::Test
|
12
5
|
def setup
|
13
6
|
Beanstalk::Pool.clear!
|
14
7
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
|
2
|
+
require File.expand_path("../../test_helper", __FILE__)
|
3
|
+
|
4
|
+
class Stalking::NullLoggerTest < Minitest::Test
|
5
|
+
def setup
|
6
|
+
@null_logger = Stalking::NullLogger.new
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_debug
|
10
|
+
assert_nothing_raised { @null_logger.debug "Message" }
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_info
|
14
|
+
assert_nothing_raised { @null_logger.info "Message" }
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_warn
|
18
|
+
assert_nothing_raised { @null_logger.warn "Message" }
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_error
|
22
|
+
assert_nothing_raised { @null_logger.error "Message" }
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_fatal
|
26
|
+
assert_nothing_raised { @null_logger.fatal "Message" }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
@@ -1,12 +1,7 @@
|
|
1
1
|
|
2
|
-
|
2
|
+
require File.expand_path("../../test_helper", __FILE__)
|
3
3
|
|
4
|
-
|
5
|
-
require "test/unit"
|
6
|
-
|
7
|
-
require File.expand_path("../test_logger", __FILE__)
|
8
|
-
|
9
|
-
class Stalking::ProducerTest < Test::Unit::TestCase
|
4
|
+
class Stalking::ProducerTest < Minitest::Test
|
10
5
|
def setup
|
11
6
|
Beanstalk::Pool.clear!
|
12
7
|
end
|
@@ -24,37 +19,43 @@ class Stalking::ProducerTest < Test::Unit::TestCase
|
|
24
19
|
end
|
25
20
|
|
26
21
|
def test_reconnect
|
27
|
-
|
22
|
+
servers = ["server1", "server2"]
|
23
|
+
|
24
|
+
producer = Stalking::Producer.new(:servers => servers)
|
28
25
|
|
29
26
|
server1 = Beanstalk::Pool.new(["server1"])
|
30
27
|
server2 = Beanstalk::Pool.new(["server2"])
|
31
28
|
|
32
|
-
|
29
|
+
servers.expects(:shuffle).returns(["server1", "server2"]).once
|
33
30
|
|
34
31
|
producer.enqueue "test", "up" => "true"
|
35
32
|
assert_equal ['["test",{"up":"true"}]', 65536, 0, 120], server1.queues["test"].last
|
36
33
|
|
37
34
|
server1.down!
|
38
35
|
|
36
|
+
servers.expects(:shuffle).returns(["server1", "server2"]).once
|
37
|
+
|
39
38
|
producer.enqueue "test", "down" => "permanent"
|
40
39
|
assert_equal ['["test",{"down":"permanent"}]', 65536, 0, 120], server2.queues["test"].last
|
41
40
|
end
|
42
41
|
|
43
42
|
def test_timeout
|
44
|
-
|
43
|
+
servers = ["server1", "server2"]
|
44
|
+
|
45
|
+
producer = Stalking::Producer.new(:servers => servers)
|
45
46
|
|
46
47
|
server1 = Beanstalk::Pool.new(["server1"])
|
47
48
|
server2 = Beanstalk::Pool.new(["server2"])
|
48
49
|
|
49
|
-
|
50
|
+
servers.expects(:shuffle).returns(["server1", "server2"]).once
|
50
51
|
|
51
52
|
producer.enqueue "test", "up" => "true"
|
52
53
|
assert_equal ['["test",{"up":"true"}]', 65536, 0, 120], server1.queues["test"].last
|
53
54
|
|
54
|
-
srand 0
|
55
|
-
|
56
55
|
server1.delay = 5
|
57
56
|
|
57
|
+
servers.expects(:shuffle).returns(["server1", "server2"]).once
|
58
|
+
|
58
59
|
producer.enqueue "test", "down" => "delayed"
|
59
60
|
assert_equal ['["test",{"down":"delayed"}]', 65536, 0, 120], server2.queues["test"].last
|
60
61
|
end
|
@@ -6,12 +6,24 @@ class TestLogger
|
|
6
6
|
@entries = []
|
7
7
|
end
|
8
8
|
|
9
|
+
def debug(entry)
|
10
|
+
@entries.push entry
|
11
|
+
end
|
12
|
+
|
9
13
|
def info(entry)
|
10
14
|
@entries.push entry
|
11
15
|
end
|
12
16
|
|
17
|
+
def warn(entry)
|
18
|
+
@entries.push entry
|
19
|
+
end
|
20
|
+
|
13
21
|
def error(entry)
|
14
22
|
@entries.push entry
|
15
23
|
end
|
24
|
+
|
25
|
+
def fatal(entry)
|
26
|
+
@entries.push entry
|
27
|
+
end
|
16
28
|
end
|
17
29
|
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
|
2
|
+
$:.unshift File.expand_path("../lib", __FILE__)
|
3
|
+
|
4
|
+
require "stalking"
|
5
|
+
require "timeout"
|
6
|
+
require "minitest"
|
7
|
+
require "minitest/autorun"
|
8
|
+
require "mocha/mini_test"
|
9
|
+
|
10
|
+
require File.expand_path("../stalking/beanstalk", __FILE__)
|
11
|
+
require File.expand_path("../stalking/test_logger", __FILE__)
|
12
|
+
|
13
|
+
module TestHelpers
|
14
|
+
def assert_nothing_raised
|
15
|
+
yield
|
16
|
+
rescue => e
|
17
|
+
raise "Exception #{e.message} should be raised"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
Minitest::Test.send :include, TestHelpers
|
22
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stalking
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-
|
12
|
+
date: 2014-08-06 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -28,14 +28,14 @@ dependencies:
|
|
28
28
|
- !ruby/object:Gem::Version
|
29
29
|
version: '0'
|
30
30
|
- !ruby/object:Gem::Dependency
|
31
|
-
name:
|
31
|
+
name: minitest
|
32
32
|
requirement: !ruby/object:Gem::Requirement
|
33
33
|
none: false
|
34
34
|
requirements:
|
35
35
|
- - ! '>='
|
36
36
|
- !ruby/object:Gem::Version
|
37
37
|
version: '0'
|
38
|
-
type: :
|
38
|
+
type: :development
|
39
39
|
prerelease: false
|
40
40
|
version_requirements: !ruby/object:Gem::Requirement
|
41
41
|
none: false
|
@@ -44,7 +44,39 @@ dependencies:
|
|
44
44
|
- !ruby/object:Gem::Version
|
45
45
|
version: '0'
|
46
46
|
- !ruby/object:Gem::Dependency
|
47
|
-
name:
|
47
|
+
name: bundler
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: mocha
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: beanstalk-client
|
48
80
|
requirement: !ruby/object:Gem::Requirement
|
49
81
|
none: false
|
50
82
|
requirements:
|
@@ -60,7 +92,7 @@ dependencies:
|
|
60
92
|
- !ruby/object:Gem::Version
|
61
93
|
version: '0'
|
62
94
|
- !ruby/object:Gem::Dependency
|
63
|
-
name:
|
95
|
+
name: json_pure
|
64
96
|
requirement: !ruby/object:Gem::Requirement
|
65
97
|
none: false
|
66
98
|
requirements:
|
@@ -85,6 +117,7 @@ extensions: []
|
|
85
117
|
extra_rdoc_files: []
|
86
118
|
files:
|
87
119
|
- .gitignore
|
120
|
+
- .travis.yml
|
88
121
|
- Gemfile
|
89
122
|
- LICENSE.txt
|
90
123
|
- README.md
|
@@ -93,13 +126,16 @@ files:
|
|
93
126
|
- lib/stalking.rb
|
94
127
|
- lib/stalking/consumer.rb
|
95
128
|
- lib/stalking/handlers.rb
|
129
|
+
- lib/stalking/null_logger.rb
|
96
130
|
- lib/stalking/producer.rb
|
97
131
|
- lib/stalking/version.rb
|
98
132
|
- stalking.gemspec
|
99
133
|
- test/stalking/beanstalk.rb
|
100
134
|
- test/stalking/consumer_test.rb
|
135
|
+
- test/stalking/null_logger_test.rb
|
101
136
|
- test/stalking/producer_test.rb
|
102
137
|
- test/stalking/test_logger.rb
|
138
|
+
- test/test_helper.rb
|
103
139
|
homepage: https://github.com/mrkamel/stalking
|
104
140
|
licenses:
|
105
141
|
- MIT
|