droid 1.0.2pre → 1.0.2
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/Rakefile +22 -22
- data/VERSION +1 -1
- data/bin/bleedq +1 -1
- data/droid.gemspec +2 -2
- data/examples/async_reply.rb +15 -15
- data/examples/heroku_async_reply.rb +12 -12
- data/examples/sync.rb +13 -13
- data/examples/worker.rb +46 -46
- data/lib/droid.rb +122 -122
- data/lib/droid/em.rb +53 -53
- data/lib/droid/heroku.rb +83 -83
- data/lib/droid/json_server.rb +104 -104
- data/lib/droid/monkey.rb +6 -6
- data/lib/droid/publish.rb +22 -25
- data/lib/droid/queue.rb +194 -194
- data/lib/droid/request.rb +106 -106
- data/lib/droid/sync.rb +74 -74
- data/lib/droid/utilization.rb +96 -96
- data/lib/droid/utils.rb +107 -107
- data/spec/publish_spec.rb +20 -20
- data/spec/response_spec.rb +43 -43
- data/spec/utils_spec.rb +39 -39
- data/spec/wait_for_port_spec.rb +9 -9
- metadata +5 -24
data/lib/droid/monkey.rb
CHANGED
data/lib/droid/publish.rb
CHANGED
@@ -1,31 +1,28 @@
|
|
1
1
|
require 'droid/utils'
|
2
2
|
|
3
3
|
class Droid
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
4
|
+
# publish to queue directly
|
5
|
+
def self.publish_to_q(queue_name, data, opts={}, popts={})
|
6
|
+
json, popts = Droid::Utils.format_publish(data, opts, popts)
|
7
|
+
# specifying passive on the queue does not declare the queue
|
8
|
+
# but will throw an error if the queue does not already exist
|
9
|
+
# this is ok for our purposes since if no one is listening
|
10
|
+
# nothing would really happen anyways.
|
11
|
+
q = ::MQ.queue(queue_name, :passive => true)
|
12
|
+
q.publish(json, popts)
|
13
|
+
log.info "amqp_publish queue=#{queue_name} #{Droid::Utils.format_data_summary(data, popts[:headers])}" unless opts[:log] == false
|
14
|
+
end
|
11
15
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
16
|
+
# publish to exchange directly
|
17
|
+
def self.publish_to_ex(ex_name, data, opts={}, popts={})
|
18
|
+
ex = ::MQ.direct(ex_name)
|
19
|
+
json, popts = Droid::Utils.format_publish(data, opts, popts)
|
20
|
+
ex.publish(json, popts)
|
21
|
+
log.info "amqp_publish exchange=#{ex_name} #{Droid::Utils.format_data_summary(data, popts[:headers])}" unless opts[:log] == false
|
22
|
+
end
|
18
23
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
ex.publish(json, popts)
|
24
|
-
log.info "amqp_publish exchange=#{ex_name} #{Droid::Utils.format_data_summary(data, popts[:headers])}" unless opts[:log] == false
|
25
|
-
end
|
26
|
-
|
27
|
-
# default is publish to exchange
|
28
|
-
def self.publish(ex_name, data, opts={}, popts={})
|
29
|
-
publish_to_ex(ex_name, data, opts, popts)
|
30
|
-
end
|
24
|
+
# default is publish to exchange
|
25
|
+
def self.publish(ex_name, data, opts={}, popts={})
|
26
|
+
publish_to_ex(ex_name, data, opts, popts)
|
27
|
+
end
|
31
28
|
end
|
data/lib/droid/queue.rb
CHANGED
@@ -1,196 +1,196 @@
|
|
1
1
|
class Droid
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
2
|
+
class ExpiredMessage < RuntimeError; end
|
3
|
+
|
4
|
+
class BaseQueue
|
5
|
+
attr_reader :queue_name, :opts
|
6
|
+
attr_reader :q, :ex, :mq
|
7
|
+
|
8
|
+
def initialize(queue_name, opts={})
|
9
|
+
opts[:auto_delete] = true unless opts.has_key?(:auto_delete) and opts[:auto_delete] === false
|
10
|
+
|
11
|
+
@queue_name, @opts = queue_name, opts
|
12
|
+
end
|
13
|
+
|
14
|
+
def setup
|
15
|
+
@mq = MQ.new
|
16
|
+
@q = @mq.queue(queue_name, opts)
|
17
|
+
# if we don't specify an exchange name it defaults to the queue_name
|
18
|
+
@ex = @mq.direct(opts[:exchange_name] || queue_name)
|
19
|
+
end
|
20
|
+
|
21
|
+
def temp?
|
22
|
+
false
|
23
|
+
end
|
24
|
+
|
25
|
+
def log
|
26
|
+
Droid.log
|
27
|
+
end
|
28
|
+
|
29
|
+
def tag
|
30
|
+
s = "queue=#{q.name}"
|
31
|
+
s += " exchange=#{ex.name}" if ex
|
32
|
+
end
|
33
|
+
|
34
|
+
def subscribe(amqp_opts={}, opts={})
|
35
|
+
setup
|
36
|
+
|
37
|
+
q.bind(ex) if ex
|
38
|
+
q.subscribe(amqp_opts) do |header, message|
|
39
|
+
Droid::Utilization.monitor(q.name, :temp => temp?) do
|
40
|
+
request = Droid::Request.new(self, header, message)
|
41
|
+
log.info "amqp_message #{tag} action=received ttl=#{request.ttl} age=#{request.age} #{request.data_summary}"
|
42
|
+
begin
|
43
|
+
raise Droid::ExpiredMessage if request.expired?
|
44
|
+
yield request if block_given?
|
45
|
+
finished = Time.now.getgm.to_i
|
46
|
+
log.info "amqp_message action=processed #{tag} elapsed=#{finished-request.start} ttl=#{request.ttl} age=#{request.age} #{request.data_summary}"
|
47
|
+
rescue Droid::ExpiredMessage
|
48
|
+
log.info "amqp_message action=timeout #{tag} ttl=#{request.ttl} age=#{request.age} #{request.data_summary}"
|
49
|
+
request.ack if amqp_opts[:ack]
|
50
|
+
rescue => e
|
51
|
+
request.ack if amqp_opts[:ack]
|
52
|
+
Droid.handle_error(e)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
log.info "amqp_subscribe #{tag}"
|
57
|
+
self
|
58
|
+
end
|
59
|
+
|
60
|
+
def teardown
|
61
|
+
@q.unsubscribe
|
62
|
+
@mq.close
|
63
|
+
log.info "amqp_unsubscribe #{tag}"
|
64
|
+
end
|
65
|
+
|
66
|
+
def destroy
|
67
|
+
teardown
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
class WorkerQueue < BaseQueue
|
72
|
+
attr_reader :prefetch
|
73
|
+
|
74
|
+
def initialize(queue_name, opts={})
|
75
|
+
@prefetch = opts.delete(:prefetch) || 1
|
76
|
+
opts[:auto_delete] = false
|
77
|
+
|
78
|
+
super(queue_name, opts)
|
79
|
+
end
|
80
|
+
|
81
|
+
def setup
|
82
|
+
super
|
83
|
+
@mq.prefetch(self.prefetch)
|
84
|
+
end
|
85
|
+
|
86
|
+
def subscribe(amqp_opts={}, opts={})
|
87
|
+
amqp_opts[:ack] = true
|
88
|
+
super(amqp_opts, opts) do |request|
|
89
|
+
begin
|
90
|
+
yield request if block_given?
|
91
|
+
ensure
|
92
|
+
request.ack unless amqp_opts[:auto_ack] == false
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
class ListenQueue < BaseQueue
|
99
|
+
def initialize(exchange_name, opts={})
|
100
|
+
opts[:exchange_name] = exchange_name
|
101
|
+
queue_name = opts.delete(:queue) || Droid::Utils.generate_queue(exchange_name)
|
102
|
+
super(queue_name, opts)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
class ReplyQueue < BaseQueue
|
107
|
+
def initialize(queue_name, opts={})
|
108
|
+
opts[:auto_delete] = true
|
109
|
+
super
|
110
|
+
end
|
111
|
+
|
112
|
+
def setup
|
113
|
+
@mq = MQ.new
|
114
|
+
@q = @mq.queue(queue_name, opts)
|
115
|
+
@ex = nil
|
116
|
+
end
|
117
|
+
|
118
|
+
def temp?
|
119
|
+
true
|
120
|
+
end
|
121
|
+
|
122
|
+
def subscribe(amqp_opts={}, opts={})
|
123
|
+
super(amqp_opts, opts) do |request|
|
124
|
+
yield request if block_given?
|
125
|
+
self.destroy
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def teardown
|
130
|
+
@q.delete
|
131
|
+
super
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
module QueueMethods
|
136
|
+
def worker(queue_name, opts={})
|
137
|
+
WorkerQueue.new(queue_name, opts)
|
138
|
+
end
|
139
|
+
|
140
|
+
def listener(exchange_name, opts={})
|
141
|
+
ListenQueue.new(exchange_name, opts)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
class BackwardsCompatibleQueue < BaseQueue
|
146
|
+
def initialize(exchange_name, opts={})
|
147
|
+
opts[:auto_delete] = true unless opts.has_key?(:auto_delete) and opts[:auto_delete] === false
|
148
|
+
opts[:exchange_name] = exchange_name
|
149
|
+
queue_name = opts.delete(:queue) || Droid::Utils.generate_queue(exchange_name)
|
150
|
+
@queue_name, @opts = queue_name, opts
|
151
|
+
end
|
152
|
+
|
153
|
+
def setup
|
154
|
+
@mq = MQ.new
|
155
|
+
@q = @mq.queue(queue_name, opts)
|
156
|
+
@ex = @mq.direct(opts[:exchange_name])
|
157
|
+
|
158
|
+
@mq.prefetch(opts[:prefetch]) if opts[:prefetch]
|
159
|
+
end
|
160
|
+
|
161
|
+
def subscribe(amqp_opts={}, opts={})
|
162
|
+
super(amqp_opts, opts) do |request|
|
163
|
+
if block_given?
|
164
|
+
if opts[:detail]
|
165
|
+
yield request, request.header, request.raw_message if block_given?
|
166
|
+
else
|
167
|
+
yield request if block_given?
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
self
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
module BackwardsCompatibleMethods
|
177
|
+
def listen4(key, orig_opts={}, &block)
|
178
|
+
opts = {}
|
179
|
+
amqp_opts = {}
|
180
|
+
subscribe_opts = {}
|
181
|
+
|
182
|
+
if orig_opts[:prefetch] || orig_opts[:ack]
|
183
|
+
opts[:prefetch] = orig_opts[:prefetch] || 1
|
184
|
+
opts[:ack] = true
|
185
|
+
end
|
186
|
+
if orig_opts[:queue]
|
187
|
+
opts[:queue] = orig_opts[:queue]
|
188
|
+
end
|
189
|
+
if orig_opts[:detail]
|
190
|
+
subscribe_opts[:detail] = true
|
191
|
+
end
|
192
|
+
|
193
|
+
BackwardsCompatibleQueue.new(key, opts).subscribe(amqp_opts, subscribe_opts, &block)
|
194
|
+
end
|
195
|
+
end
|
196
196
|
end
|