iron_mq 4.0.3 → 4.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/Gemfile.lock +23 -15
- data/README.md +20 -7
- data/iron_mq.gemspec +2 -2
- data/lib/iron_mq.rb +1 -0
- data/lib/iron_mq/alert.rb +53 -0
- data/lib/iron_mq/client.rb +2 -2
- data/lib/iron_mq/messages.rb +21 -1
- data/lib/iron_mq/queues.rb +85 -37
- data/lib/iron_mq/response.rb +26 -9
- data/lib/iron_mq/subscribers.rb +1 -1
- data/lib/iron_mq/version.rb +1 -2
- data/test/quick_run.rb +22 -39
- data/test/quick_run2.rb +114 -0
- data/test/test_alerts.rb +142 -0
- data/test/test_base.rb +13 -11
- data/test/test_beanstalkd.rb +1 -1
- data/test/test_iron_mq.rb +175 -141
- data/test/test_mq_worker_subscribers.rb +71 -0
- data/test/test_push_queues.rb +123 -3
- data/test/tmp.rb +14 -0
- metadata +29 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 59de953d559a2e493b72d7d9f5d588fb45b09522
|
4
|
+
data.tar.gz: ff331240b424418b610a83bb37f4091d5ac6f8af
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 24378f0dcf15c8f5c54759dfe6bac0e556ffa05905e9fb26597c28bfd63b23b3146a5a8dff5285cf9b0668e6b9036ac023b9df2ebd6caa795f2954fc9136aad6
|
7
|
+
data.tar.gz: 3ffaa342f10a49f5cd638b75e7440b4d2d36cc709f186866740cbd1013aa57e672f1e4db1302dcc38a05a5c116e82a633c4a72a055b5ee4e1f92d7dd2e506bd2
|
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
@@ -8,26 +8,33 @@ GEM
|
|
8
8
|
remote: https://rubygems.org/
|
9
9
|
specs:
|
10
10
|
beanstalk-client (1.1.1)
|
11
|
-
concur (2.
|
12
|
-
ethon (0.
|
13
|
-
ffi (
|
11
|
+
concur (2.1.1)
|
12
|
+
ethon (0.6.1)
|
13
|
+
ffi (>= 1.3.0)
|
14
14
|
mime-types (~> 1.18)
|
15
|
-
ffi (1.
|
16
|
-
|
15
|
+
ffi (1.9.0)
|
16
|
+
go (1.1.0)
|
17
|
+
concur
|
18
|
+
iron_core (1.0.1)
|
17
19
|
rest (>= 2.2.0)
|
18
|
-
|
19
|
-
|
20
|
-
|
20
|
+
iron_worker_ng (1.0.2)
|
21
|
+
bundler (>= 1.2.0)
|
22
|
+
iron_core (>= 1.0.0)
|
23
|
+
rubyzip (= 0.9.9)
|
24
|
+
mime-types (1.25)
|
25
|
+
minitest (5.0.8)
|
26
|
+
net-http-persistent (2.9)
|
21
27
|
quicky (0.4.0)
|
22
|
-
rake (10.0
|
23
|
-
rest (2.
|
28
|
+
rake (10.1.0)
|
29
|
+
rest (2.6.3)
|
30
|
+
net-http-persistent
|
24
31
|
rest-client (>= 0.3.0)
|
25
|
-
typhoeus (>= 0.5.4)
|
26
32
|
rest-client (1.6.7)
|
27
33
|
mime-types (>= 1.16)
|
28
|
-
|
29
|
-
|
30
|
-
|
34
|
+
rubyzip (0.9.9)
|
35
|
+
test-unit (2.5.5)
|
36
|
+
typhoeus (0.6.5)
|
37
|
+
ethon (~> 0.6.1)
|
31
38
|
uber_config (1.0.5)
|
32
39
|
|
33
40
|
PLATFORMS
|
@@ -35,8 +42,9 @@ PLATFORMS
|
|
35
42
|
|
36
43
|
DEPENDENCIES
|
37
44
|
beanstalk-client
|
38
|
-
|
45
|
+
go
|
39
46
|
iron_mq!
|
47
|
+
iron_worker_ng
|
40
48
|
minitest
|
41
49
|
net-http-persistent
|
42
50
|
quicky
|
data/README.md
CHANGED
@@ -21,12 +21,17 @@ gem install iron_mq
|
|
21
21
|
ironmq = IronMQ::Client.new
|
22
22
|
```
|
23
23
|
|
24
|
-
Or pass in credentials:
|
24
|
+
Or pass in credentials if you don't want to use an iron.json file or set ENV variables:
|
25
25
|
|
26
26
|
```ruby
|
27
27
|
ironmq = IronMQ::Client.new(:token => "MY_TOKEN", :project_id => "MY_PROJECT_ID")
|
28
28
|
```
|
29
|
+
You can also change the host if you want to use a different cloud or region, for example, to use Rackspace ORD:
|
29
30
|
|
31
|
+
```ruby
|
32
|
+
ironmq = IronMQ::Client.new(:host => "mq-rackspace-ord.iron.io", :token => "MY_TOKEN", :project_id => "MY_PROJECT_ID")
|
33
|
+
```
|
34
|
+
The default host is AWS us-east-1 zone (mq-aws-us-east-1.iron.io). [See all available hosts/clouds/regions](http://dev.iron.io/mq/reference/clouds/).
|
30
35
|
|
31
36
|
## The Basics
|
32
37
|
|
@@ -147,8 +152,6 @@ Shortcuts for `queue.info[key]`:
|
|
147
152
|
|
148
153
|
```ruby
|
149
154
|
id = queue.id # => "5127bf043264140e863e2283"
|
150
|
-
# Does queue exists on server? Alias for `queue.id.nil?`
|
151
|
-
is_new = queue.new? # => false
|
152
155
|
|
153
156
|
size = queue.size # => 7
|
154
157
|
name = queue.name # => "my_queue"
|
@@ -233,8 +236,8 @@ You must delete the message from the queue to ensure it does not go back onto th
|
|
233
236
|
If not set, value from POST is used. Default is 60 seconds. Minimum is 30 seconds.
|
234
237
|
Maximum is 86,400 seconds (24 hours).
|
235
238
|
|
236
|
-
When `n` parameter is specified and greater than 1 method returns `Array` of `
|
237
|
-
Otherwise, `
|
239
|
+
When `n` parameter is specified and greater than 1 method returns `Array` of `Message`s.
|
240
|
+
Otherwise, `Message` object would be returned.
|
238
241
|
|
239
242
|
--
|
240
243
|
|
@@ -330,7 +333,7 @@ This set of subscribers will replace the existing subscribers.
|
|
330
333
|
To add or remove subscribers, see the add subscribers endpoint or the remove subscribers endpoint.
|
331
334
|
See below for example json.
|
332
335
|
* `push_type`: Either `multicast` to push to all subscribers or `unicast` to push to one and only one subscriber. Default is `multicast`.
|
333
|
-
* `retries`: How many times to retry on failure. Default is 3.
|
336
|
+
* `retries`: How many times to retry on failure. Default is 3. Maximum is 100.
|
334
337
|
* `retries_delay`: Delay between each retry in seconds. Default is 60.
|
335
338
|
|
336
339
|
--
|
@@ -345,7 +348,7 @@ Subscribers can be any HTTP endpoint. `push_type` is one of:
|
|
345
348
|
```ruby
|
346
349
|
ptype = :multicast
|
347
350
|
subscribers = [
|
348
|
-
{:url => "http://rest-test.iron.io/code/200?store=key1"}
|
351
|
+
{:url => "http://rest-test.iron.io/code/200?store=key1"},
|
349
352
|
{:url => "http://rest-test.iron.io/code/200?store=key2"}
|
350
353
|
]
|
351
354
|
|
@@ -421,6 +424,16 @@ end
|
|
421
424
|
|
422
425
|
--
|
423
426
|
|
427
|
+
### Revert Queue Back to Pull Queue
|
428
|
+
|
429
|
+
If you want to revert you queue just update `push_type` to `'pull'`.
|
430
|
+
|
431
|
+
```ruby
|
432
|
+
queue.update(:push_type => 'pull');
|
433
|
+
```
|
434
|
+
|
435
|
+
--
|
436
|
+
|
424
437
|
|
425
438
|
## Further Links
|
426
439
|
|
data/iron_mq.gemspec
CHANGED
@@ -24,9 +24,9 @@ Gem::Specification.new do |gem|
|
|
24
24
|
gem.add_development_dependency "beanstalk-client"
|
25
25
|
gem.add_development_dependency "uber_config"
|
26
26
|
gem.add_development_dependency "typhoeus", ">= 0.5.4"
|
27
|
-
gem.add_development_dependency "concur"
|
28
27
|
gem.add_development_dependency "net-http-persistent"
|
29
28
|
gem.add_development_dependency "quicky"
|
30
|
-
|
29
|
+
gem.add_development_dependency "iron_worker_ng"
|
30
|
+
gem.add_development_dependency "go"
|
31
31
|
end
|
32
32
|
|
data/lib/iron_mq.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require File.expand_path('iron_mq/response', File.dirname(__FILE__))
|
2
2
|
require File.expand_path('iron_mq/subscribers', File.dirname(__FILE__))
|
3
|
+
require File.expand_path('iron_mq/alert', File.dirname(__FILE__))
|
3
4
|
require File.expand_path('iron_mq/queues', File.dirname(__FILE__))
|
4
5
|
require File.expand_path('iron_mq/messages', File.dirname(__FILE__))
|
5
6
|
require File.expand_path('iron_mq/client', File.dirname(__FILE__))
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module IronMQ
|
2
|
+
|
3
|
+
class Alert
|
4
|
+
# `options` was kept for backward compatibility
|
5
|
+
attr_accessor :options
|
6
|
+
|
7
|
+
def initialize(queue, alert_hash, options = {})
|
8
|
+
@queue = queue
|
9
|
+
@raw = alert_hash
|
10
|
+
@options = options
|
11
|
+
end
|
12
|
+
|
13
|
+
def id
|
14
|
+
@raw["id"]
|
15
|
+
end
|
16
|
+
|
17
|
+
# alert type
|
18
|
+
def type
|
19
|
+
@raw["type"]
|
20
|
+
end
|
21
|
+
|
22
|
+
# target queue
|
23
|
+
def queue
|
24
|
+
@raw["queue"]
|
25
|
+
end
|
26
|
+
|
27
|
+
def trigger
|
28
|
+
@raw["trigger"]
|
29
|
+
end
|
30
|
+
|
31
|
+
# `options` was kept for backward compatibility
|
32
|
+
def delete(options = {})
|
33
|
+
@message.call_api_and_parse_response(:delete, path)
|
34
|
+
rescue Rest::HttpError => ex
|
35
|
+
if ex.code == 404
|
36
|
+
IronCore::Logger.info("IronMQ", "Delete got 404, safe to ignore.")
|
37
|
+
# return ResponseBase as normal
|
38
|
+
ResponseBase.new({"msg" => "Deleted"}, 404)
|
39
|
+
else
|
40
|
+
raise ex
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
alias_method :acknowledge, :delete
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def path
|
49
|
+
"/alerts/#{id}"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
data/lib/iron_mq/client.rb
CHANGED
@@ -15,7 +15,7 @@ module IronMQ
|
|
15
15
|
:host => IronMQ::Client::AWS_US_EAST_HOST,
|
16
16
|
:port => 443,
|
17
17
|
:api_version => 1,
|
18
|
-
:user_agent => 'iron_mq_ruby-' +
|
18
|
+
:user_agent => 'iron_mq_ruby-' + IronMQ::VERSION + ' (iron_core_ruby-' + IronCore.version + ')'
|
19
19
|
}
|
20
20
|
|
21
21
|
super('iron', 'mq', options, default_options, [:project_id, :token, :api_version])
|
@@ -52,7 +52,7 @@ module IronMQ
|
|
52
52
|
alias_method :all, :queues_list
|
53
53
|
|
54
54
|
def queues_get(name)
|
55
|
-
Queue.new(self, name)
|
55
|
+
IronMQ::Queue.new(self, name)
|
56
56
|
end
|
57
57
|
|
58
58
|
alias_method :queue, :queues_get
|
data/lib/iron_mq/messages.rb
CHANGED
@@ -10,6 +10,26 @@ module IronMQ
|
|
10
10
|
super(data, 200)
|
11
11
|
end
|
12
12
|
|
13
|
+
def body
|
14
|
+
@raw['body']
|
15
|
+
end
|
16
|
+
|
17
|
+
def timeout
|
18
|
+
@raw['timeout']
|
19
|
+
end
|
20
|
+
|
21
|
+
def expires_in
|
22
|
+
@raw['expires_in']
|
23
|
+
end
|
24
|
+
|
25
|
+
def delay
|
26
|
+
@raw['delay']
|
27
|
+
end
|
28
|
+
|
29
|
+
def reserved_count
|
30
|
+
@raw['reserved_count']
|
31
|
+
end
|
32
|
+
|
13
33
|
def touch
|
14
34
|
call_api_and_parse_response(:post, "/touch")
|
15
35
|
end
|
@@ -31,7 +51,7 @@ module IronMQ
|
|
31
51
|
if ex.code == 404
|
32
52
|
Rest.logger.info("Delete got 404, safe to ignore.")
|
33
53
|
# return ResponseBase as normal
|
34
|
-
ResponseBase.new({"msg" => "Deleted"})
|
54
|
+
ResponseBase.new({"msg" => "Deleted"}, 404)
|
35
55
|
else
|
36
56
|
raise ex
|
37
57
|
end
|
data/lib/iron_mq/queues.rb
CHANGED
@@ -3,36 +3,49 @@ require 'cgi'
|
|
3
3
|
module IronMQ
|
4
4
|
|
5
5
|
class Queue < ResponseBase
|
6
|
-
attr_reader :name
|
6
|
+
attr_reader :name, :raw
|
7
7
|
|
8
8
|
def initialize(client, queue_name)
|
9
9
|
@client = client
|
10
10
|
@name = queue_name
|
11
|
-
|
11
|
+
|
12
12
|
end
|
13
13
|
|
14
14
|
def info
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
raise ex
|
15
|
+
load
|
16
|
+
end
|
17
|
+
|
18
|
+
# this is only run once if it hasn't been called before unless force is true, then it will force reload.
|
19
|
+
def load
|
20
|
+
if @raw.nil?
|
21
|
+
reload
|
23
22
|
end
|
23
|
+
@raw
|
24
|
+
end
|
25
|
+
|
26
|
+
def reload
|
27
|
+
@raw = call_api_and_parse_response(:get, "", {}, false, true)
|
28
|
+
self
|
29
|
+
end
|
30
|
+
|
31
|
+
def id
|
32
|
+
load
|
33
|
+
@raw['id']
|
24
34
|
end
|
25
35
|
|
26
36
|
def size
|
27
|
-
|
37
|
+
load
|
38
|
+
@raw['size'].to_i
|
28
39
|
end
|
29
40
|
|
30
41
|
def total_messages
|
31
|
-
|
42
|
+
load
|
43
|
+
@raw['total_messages'].to_i
|
32
44
|
end
|
33
45
|
|
34
|
-
def
|
35
|
-
|
46
|
+
def push_type
|
47
|
+
load
|
48
|
+
@raw['push_type']
|
36
49
|
end
|
37
50
|
|
38
51
|
def push_queue?
|
@@ -49,19 +62,21 @@ module IronMQ
|
|
49
62
|
alias_method :update_queue, :update
|
50
63
|
|
51
64
|
def clear
|
52
|
-
call_api_and_parse_response(:post, "/clear")
|
65
|
+
call_api_and_parse_response(:post, "/clear", {}, false, true)
|
53
66
|
end
|
54
67
|
|
55
68
|
alias_method :clear_queue, :clear
|
56
69
|
|
57
70
|
# Backward compatibility, better name is `delete`
|
58
71
|
def delete_queue
|
59
|
-
call_api_and_parse_response(:delete)
|
72
|
+
r = call_api_and_parse_response(:delete)
|
73
|
+
@raw = nil
|
74
|
+
return r
|
60
75
|
rescue Rest::HttpError => ex
|
61
76
|
if ex.code == 404
|
62
77
|
Rest.logger.info("Delete got 404, safe to ignore.")
|
63
78
|
# return ResponseBase as normal
|
64
|
-
ResponseBase.new({"msg" => "Deleted"})
|
79
|
+
ResponseBase.new({"msg" => "Deleted"}, 404)
|
65
80
|
else
|
66
81
|
raise ex
|
67
82
|
end
|
@@ -73,6 +88,11 @@ module IronMQ
|
|
73
88
|
Message.new(self, {"id" => message_id}).delete
|
74
89
|
end
|
75
90
|
|
91
|
+
# Accepts an array of message ids
|
92
|
+
def delete_messages(ids)
|
93
|
+
call_api_and_parse_response(:delete, "/messages", :ids => ids)
|
94
|
+
end
|
95
|
+
|
76
96
|
def add_subscribers(subscribers)
|
77
97
|
call_api_and_parse_response(:post, "/subscribers", :subscribers => subscribers)
|
78
98
|
end
|
@@ -86,8 +106,8 @@ module IronMQ
|
|
86
106
|
call_api_and_parse_response(:delete,
|
87
107
|
"/subscribers",
|
88
108
|
{
|
89
|
-
|
90
|
-
|
109
|
+
:subscribers => subscribers,
|
110
|
+
:headers => {"Content-Type" => @client.content_type}
|
91
111
|
})
|
92
112
|
end
|
93
113
|
|
@@ -95,6 +115,29 @@ module IronMQ
|
|
95
115
|
remove_subscribers([subscriber])
|
96
116
|
end
|
97
117
|
|
118
|
+
# `options` was kept for backward compatibility
|
119
|
+
def subscribers(options = {})
|
120
|
+
load
|
121
|
+
if @raw['subscribers']
|
122
|
+
return @raw['subscribers'].map { |s| Subscriber.new(s, self, options) }
|
123
|
+
end
|
124
|
+
[]
|
125
|
+
end
|
126
|
+
|
127
|
+
def add_alert(alert = {})
|
128
|
+
add_alerts([alert])
|
129
|
+
end
|
130
|
+
|
131
|
+
def add_alerts(alerts)
|
132
|
+
call_api_and_parse_response(:post, "/alerts", :alerts => alerts)
|
133
|
+
end
|
134
|
+
|
135
|
+
def alerts
|
136
|
+
load
|
137
|
+
return nil unless @raw["alerts"]
|
138
|
+
to_alerts(@raw["alerts"])
|
139
|
+
end
|
140
|
+
|
98
141
|
def post_messages(payload, options = {})
|
99
142
|
batch = false
|
100
143
|
|
@@ -110,7 +153,7 @@ module IronMQ
|
|
110
153
|
# For now user must pass objects like `[{:body => msg1}, {:body => msg2}]`
|
111
154
|
payload.map { |msg| msg.merge(options) }
|
112
155
|
else
|
113
|
-
[
|
156
|
+
[options.merge(:body => payload)]
|
114
157
|
end
|
115
158
|
|
116
159
|
# Do not instantiate response
|
@@ -123,7 +166,7 @@ module IronMQ
|
|
123
166
|
process_messages(msg_ids, {:n => n})
|
124
167
|
else
|
125
168
|
if batch
|
126
|
-
# FIXME: Return Array of
|
169
|
+
# FIXME: Return Array of ResponseBase instead, it seems more clear than raw response
|
127
170
|
#
|
128
171
|
# res["ids"].map { |id| ResponseBase.new({"id" => id, "msg" => res["msg"]}) }
|
129
172
|
#
|
@@ -142,7 +185,7 @@ module IronMQ
|
|
142
185
|
return Message.new(self, {"id" => options})
|
143
186
|
end
|
144
187
|
|
145
|
-
resp = call_api_and_parse_response(:get, "/messages", options)
|
188
|
+
resp = call_api_and_parse_response(:get, "/messages", options, false)
|
146
189
|
|
147
190
|
process_messages(resp["messages"], options)
|
148
191
|
end
|
@@ -150,7 +193,14 @@ module IronMQ
|
|
150
193
|
alias_method :get, :get_messages
|
151
194
|
|
152
195
|
# Backward compatibility
|
153
|
-
def messages
|
196
|
+
def messages
|
197
|
+
self
|
198
|
+
end
|
199
|
+
|
200
|
+
def get_message(id)
|
201
|
+
resp = call_api_and_parse_response(:get, "/messages/#{id}", {}, false)
|
202
|
+
Message.new(self, resp)
|
203
|
+
end
|
154
204
|
|
155
205
|
def peek_messages(options = {})
|
156
206
|
resp = call_api_and_parse_response(:get, "/messages/peek", options)
|
@@ -162,7 +212,7 @@ module IronMQ
|
|
162
212
|
|
163
213
|
def poll_messages(options = {}, &block)
|
164
214
|
sleep_duration = options[:sleep_duration] || 1
|
165
|
-
|
215
|
+
|
166
216
|
while true
|
167
217
|
msg = get_messages(options.merge(:n => 1))
|
168
218
|
if msg.nil?
|
@@ -177,7 +227,8 @@ module IronMQ
|
|
177
227
|
|
178
228
|
alias_method :poll, :poll_messages
|
179
229
|
|
180
|
-
def call_api_and_parse_response(meth, ext_path = "", options = {}, instantiate = true)
|
230
|
+
def call_api_and_parse_response(meth, ext_path = "", options = {}, instantiate = true, ignore404 = false)
|
231
|
+
r = nil
|
181
232
|
response = if meth.to_s == "delete"
|
182
233
|
headers = options.delete(:headers) || options.delete("headers") || {}
|
183
234
|
|
@@ -185,23 +236,20 @@ module IronMQ
|
|
185
236
|
else
|
186
237
|
@client.parse_response(@client.send(meth, "#{path(ext_path)}", options))
|
187
238
|
end
|
188
|
-
instantiate ? ResponseBase.new(response) : response
|
239
|
+
r = instantiate ? ResponseBase.new(response) : response
|
240
|
+
r
|
189
241
|
end
|
190
242
|
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
self.info[meth.to_s]
|
198
|
-
else
|
199
|
-
super
|
243
|
+
private
|
244
|
+
|
245
|
+
def to_alerts(alert_array)
|
246
|
+
r = []
|
247
|
+
alert_array.each do |a|
|
248
|
+
r << Alert.new(self, a)
|
200
249
|
end
|
250
|
+
r
|
201
251
|
end
|
202
252
|
|
203
|
-
private
|
204
|
-
|
205
253
|
def path(ext_path)
|
206
254
|
"/#{CGI::escape(@name).gsub('+', '%20')}#{ext_path}"
|
207
255
|
end
|