activemessaging-kestrel-adapter 0.0.2 → 0.0.3

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.
@@ -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
@@ -19,6 +19,7 @@ Examples
19
19
  # development:
20
20
  # adapter: kestrel
21
21
  # servers: localhost:22133
22
+ # empty_queues_delay: 0.1
22
23
  # retry_policy:
23
24
  # strategy: SimpleRetry
24
25
  # config:
data/Rakefile CHANGED
@@ -16,7 +16,7 @@ Bones {
16
16
  readme_file 'README.md'
17
17
 
18
18
  depend_on 'memcache-client'
19
- depend_on 'activemessaging'
19
+ depend_on 'activemessaging', '>= 0.7.1'
20
20
 
21
21
  rdoc.include << 'README.md'
22
22
 
@@ -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, :command)
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
- def initialize(cfg)
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
- # TODO: when getting a retry policy strategy from the config file, it will be a string. Convert it to a class
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
- # instantiate a class for doing the retries
111
- retrier = @retry_policy[:strategy].new
118
+ if @subscriptions.size > 0
119
+ # instantiate a class for doing the retries
120
+ retrier = @retry_policy[:strategy].new
112
121
 
113
- retrier.do_work(@retry_policy[:config]) do
114
- queues_to_check = @subscriptions.size > 1 ? @subscriptions.keys.sort_by{rand} : @subscriptions.keys
115
- queues_to_check.each do |queue|
116
- if item = @kestrel.get(normalize(queue))
117
- # TODO: ActiveMessaging ought to provide a way to do messaging
118
- # without having to wrap the messages in another object
119
- return Message.new({'destination' => queue}, item, 'MESSAGE')
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)
@@ -1,4 +1,5 @@
1
1
  require 'test/unit'
2
+ require 'active_support' # Annoying that I have to do this for the ActiveMessaging framework ...
2
3
  require 'activemessaging'
3
4
  require 'activemessaging-kestrel-adapter'
4
5
 
@@ -1 +1 @@
1
- 0.0.2
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: 27
4
+ hash: 25
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 2
10
- version: 0.0.2
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-04 00:00:00 -08:00
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: 61
29
+ hash: 49
30
30
  segments:
31
31
  - 1
32
32
  - 8
33
- - 5
34
- version: 1.8.5
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: