activemessaging-kestrel-adapter 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +6 -0
- data/README.md +1 -0
- data/Rakefile +1 -1
- data/lib/active_messaging/adapters/kestrel.rb +35 -15
- data/test/test_activemessaging-kestrel-adapter.rb +1 -0
- data/version.txt +1 -1
- metadata +8 -8
data/History.txt
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
== 0.0.3 / 2011-02-05
|
2
|
+
* Introduce a 0.1 second sleep in #receive if no subscribed queues have a message
|
3
|
+
to avoid spin loops in the ActiveMessaging Gateway. This is a bug, IMHO, in
|
4
|
+
ActiveMessaging.
|
5
|
+
* Fix bugs in receive loop to match new ActiveMessaging 0.7.1 API
|
6
|
+
|
1
7
|
== 0.0.2 / 2011-02-03
|
2
8
|
* Implement simple retry in the face of receive errors to avoid log spew
|
3
9
|
by the ActiveMessaging Gateway as it retries over and over. Extensible
|
data/README.md
CHANGED
data/Rakefile
CHANGED
@@ -7,7 +7,11 @@ module ActiveMessaging
|
|
7
7
|
# kestrel message queue server.
|
8
8
|
module Kestrel
|
9
9
|
# Simple struct for wrapping received messages
|
10
|
-
Message = Struct.new(:headers, :body, :
|
10
|
+
Message = Struct.new(:headers, :body, :destination) do
|
11
|
+
def matches_subscription?(subscription)
|
12
|
+
destination.to_s == subscription.destination.value.to_s
|
13
|
+
end
|
14
|
+
end
|
11
15
|
|
12
16
|
# Resolve the provided string into a class object
|
13
17
|
def to_class(class_name, initial_scope = Kernel)
|
@@ -49,16 +53,20 @@ module ActiveMessaging
|
|
49
53
|
class Connection < ActiveMessaging::Adapters::BaseConnection
|
50
54
|
include ActiveMessaging::Adapter
|
51
55
|
register :kestrel
|
52
|
-
attr_accessor :reliable
|
53
56
|
# Reconnect on error
|
54
57
|
attr_accessor :retry_policy
|
58
|
+
# Logging
|
59
|
+
attr_accessor :logger
|
55
60
|
|
56
|
-
|
61
|
+
# Create a new Kestrel adapter using the provided config
|
62
|
+
def initialize(cfg = {})
|
57
63
|
cfg = symbolize_keys(cfg)
|
64
|
+
# TODO: Decide on fallback logging ...
|
65
|
+
@logger = cfg.delete(:logger) || (defined?(::Rails) && ::Rails.logger ? ::Rails.logger : nil) || default_logger
|
58
66
|
@retry_policy = cfg.delete(:retry_policy) || {:strategy => SimpleRetry, :config => {:tries => 1, :delay => 5}}
|
67
|
+
@empty_queues_delay = cfg.delete(:empty_queues_delay) || 0.1
|
59
68
|
if @retry_policy[:strategy].is_a?(String)
|
60
|
-
#
|
61
|
-
# using the Kestrel module as a context, then Kernel.
|
69
|
+
# Convert strategy from string to class
|
62
70
|
@retry_policy[:strategy] = Kestrel.const_get(retry_policy[:strategy]) rescue Kestrel.to_class(@retry_policy[:strategy])
|
63
71
|
end
|
64
72
|
@config = cfg
|
@@ -69,6 +77,7 @@ module ActiveMessaging
|
|
69
77
|
|
70
78
|
# Connect to the kestrel server using a Memcached client
|
71
79
|
def connect
|
80
|
+
logger.debug("Creating connection to Kestrel using config #{@config.inspect}") if logger.level <= Logger::DEBUG
|
72
81
|
@kestrel = MemCache.new(@config)
|
73
82
|
@kestrel.servers = @config[:servers]
|
74
83
|
end
|
@@ -105,25 +114,36 @@ module ActiveMessaging
|
|
105
114
|
# Gets a message from any subscribed destination and returns it as a
|
106
115
|
# ActiveMessaging::Adaptors::Kestrel::Message object
|
107
116
|
def receive
|
108
|
-
return nil if @subscriptions.size < 1
|
109
117
|
|
110
|
-
|
111
|
-
|
118
|
+
if @subscriptions.size > 0
|
119
|
+
# instantiate a class for doing the retries
|
120
|
+
retrier = @retry_policy[:strategy].new
|
112
121
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
122
|
+
retrier.do_work(@retry_policy[:config]) do
|
123
|
+
queues_to_check = @subscriptions.size > 1 ? @subscriptions.keys.sort_by{rand} : @subscriptions.keys
|
124
|
+
queues_to_check.each do |queue|
|
125
|
+
if item = @kestrel.get(normalize(queue))
|
126
|
+
# TODO: ActiveMessaging ought to provide a way to do messaging
|
127
|
+
# without having to wrap the messages in another object
|
128
|
+
#logger.debug("Got message from queue #{queue}: #{item}") if logger.level <= Logger::DEBUG
|
129
|
+
return Message.new({'destination' => queue}, item, queue)
|
130
|
+
end
|
120
131
|
end
|
121
132
|
end
|
122
133
|
end
|
134
|
+
# Sleep a little to avoid a spin loop (ActiveMessaging Gateway ought to do this)
|
135
|
+
sleep(@empty_queues_delay)
|
123
136
|
return nil
|
124
137
|
end
|
125
138
|
|
126
139
|
private
|
140
|
+
def default_logger
|
141
|
+
# Create a logger on STDOUT at debug level
|
142
|
+
logger = Logger.new(STDOUT)
|
143
|
+
logger.level = Logger::DEBUG
|
144
|
+
logger
|
145
|
+
end
|
146
|
+
|
127
147
|
def normalize(name)
|
128
148
|
# Kestrel doesn't like '/' chars in queue names, so get rid of them
|
129
149
|
# (and memoize the calculation)
|
data/version.txt
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.3
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activemessaging-kestrel-adapter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 25
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 3
|
10
|
+
version: 0.0.3
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Douglas A. Seifert
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-02-
|
18
|
+
date: 2011-02-06 00:00:00 -08:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -26,12 +26,12 @@ dependencies:
|
|
26
26
|
requirements:
|
27
27
|
- - "="
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
hash:
|
29
|
+
hash: 49
|
30
30
|
segments:
|
31
31
|
- 1
|
32
32
|
- 8
|
33
|
-
-
|
34
|
-
version: 1.8.
|
33
|
+
- 3
|
34
|
+
version: 1.8.3
|
35
35
|
type: :runtime
|
36
36
|
version_requirements: *id001
|
37
37
|
- !ruby/object:Gem::Dependency
|
@@ -40,7 +40,7 @@ dependencies:
|
|
40
40
|
requirement: &id002 !ruby/object:Gem::Requirement
|
41
41
|
none: false
|
42
42
|
requirements:
|
43
|
-
- - "
|
43
|
+
- - ">="
|
44
44
|
- !ruby/object:Gem::Version
|
45
45
|
hash: 1
|
46
46
|
segments:
|