iron_mq 2.1.3 → 3.0.0

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/Gemfile.lock CHANGED
@@ -1,35 +1,33 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- iron_mq (2.1.2)
5
- iron_core (>= 0.4.2)
4
+ iron_mq (2.1.3)
5
+ iron_core (>= 0.4.4)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
10
  beanstalk-client (1.1.1)
11
- concur (1.0.0)
12
- faraday
13
- faraday
14
- faraday (0.8.4)
15
- multipart-post (~> 1.1)
16
- ffi (1.1.5)
17
- iron_core (0.4.2)
18
- rest (>= 2.0.2)
11
+ concur (1.0.2)
12
+ ethon (0.5.3)
13
+ ffi (~> 1.0.11)
14
+ mime-types (~> 1.18)
15
+ ffi (1.0.11)
16
+ iron_core (0.4.4)
17
+ rest (>= 2.1.1)
19
18
  mime-types (1.19)
20
- multipart-post (1.1.5)
21
- net-http-persistent (2.7)
22
- rake (0.9.2.2)
23
- rest (2.0.2)
19
+ minitest (4.2.0)
20
+ net-http-persistent (2.8)
21
+ rake (10.0.0)
22
+ rest (2.1.1)
24
23
  net-http-persistent
25
24
  rest-client (>= 0.3.0)
26
25
  rest-client (1.6.7)
27
26
  mime-types (>= 1.16)
28
- test-unit (2.5.1)
29
- typhoeus (0.4.2)
30
- ffi (~> 1.0)
31
- mime-types (~> 1.18)
32
- uber_config (0.0.6)
27
+ test-unit (2.5.2)
28
+ typhoeus (0.5.1)
29
+ ethon (= 0.5.3)
30
+ uber_config (1.0.5)
33
31
 
34
32
  PLATFORMS
35
33
  ruby
@@ -38,6 +36,7 @@ DEPENDENCIES
38
36
  beanstalk-client
39
37
  concur
40
38
  iron_mq!
39
+ minitest
41
40
  net-http-persistent
42
41
  rake
43
42
  test-unit
data/README.md CHANGED
@@ -1,6 +1,11 @@
1
1
  IronMQ Ruby Client
2
2
  -------------
3
3
 
4
+ The [full API documentation is here](http://dev.iron.io/mq/reference/api/) and this client tries to stick to the API as
5
+ much as possible so if you see an option in the API docs, you can use it in the methods below.
6
+
7
+ http://dev.iron.io/mq/reference/api/
8
+
4
9
  Getting Started
5
10
  ==============
6
11
 
@@ -26,29 +31,39 @@ You can have as many queues as you want, each with their own unique set of messa
26
31
 
27
32
  Now you can use it:
28
33
 
29
- **Push** a message on the queue:
34
+ ### Post a message on the queue:
30
35
 
31
36
  @queue.post("hello world!")
32
37
 
33
- **Pop** a message off the queue:
38
+ Post a message with options:
39
+
40
+ @queue.post("hello world!", delay: 3600)
41
+
42
+ ### Get a message off the queue:
34
43
 
35
44
  msg = @queue.get()
36
45
  puts msg.body
37
46
 
38
- **Poll** for messages:
47
+ Get a message with options:
39
48
 
40
- @queue.poll do |msg|
41
- puts msg.body
42
- end
49
+ msg = @queue.get(timeout: 300)
43
50
 
44
51
  When you pop/get a message from the queue, it will NOT be deleted. It will eventually go back onto the queue after
45
- a timeout if you don't delete it (default timeout is 10 minutes).
52
+ a timeout if you don't delete it (default timeout is 60 seconds).
46
53
 
47
- **Delete** a message from the queue:
54
+ ### Delete a message from the queue:
48
55
 
49
56
  msg.delete # or @queue.delete(msg.id)
50
57
 
51
- Delete a message from the queue when you're done with it.
58
+ Be sure to delete a message from the queue when you're done with it.
59
+
60
+ ### Poll for messages:
61
+
62
+ @queue.poll do |msg|
63
+ puts msg.body
64
+ end
65
+
66
+ Polling will automatically delete the message at the end of the block.
52
67
 
53
68
  Queue Information
54
69
  =================
@@ -56,3 +71,44 @@ Queue Information
56
71
  queue = @client.queue("my_queue")
57
72
  puts "size: #{queue.size}"
58
73
 
74
+
75
+ Push Queues
76
+ ===========
77
+
78
+ IronMQ push queues allow you to setup a queue that will push to an endpoint, rather than having to poll the endpoint.
79
+
80
+ LINK TO BLOG POST
81
+
82
+ ### Set subscribers on a queue:
83
+
84
+ Subscribers can be any http endpoint. push_type is one of:
85
+
86
+ - multicast - will push to all endpoints/subscribers
87
+ - unicast - will push to one and only one endpoint/subscriber
88
+
89
+
90
+ ```ruby
91
+ subscribers = []
92
+ subscribers << {url: "http://rest-test.iron.io/code/200?store=key1"}
93
+ subscribers << {url: "http://rest-test.iron.io/code/200?store=key2"}
94
+ res = @queue.update_queue(:subscribers => subscribers,
95
+ :push_type => t)
96
+ ```
97
+
98
+ ### Add/remove subscribers on a queue
99
+
100
+ ```ruby
101
+ @queue.add_subscriber({url: "http://nowhere.com"})
102
+ # Or to remove a subscriber:
103
+ @queue.remove_subscriber({url: "http://nowhere.com"})
104
+ ```
105
+
106
+ ### Get message push status
107
+
108
+ After pushing a message:
109
+
110
+ ```ruby
111
+ queue.messages.get(m.id).subscribers
112
+ ```
113
+
114
+ Returns an array of subscribers with status.
data/iron_mq.gemspec CHANGED
@@ -2,7 +2,7 @@ require File.expand_path('../lib/iron_mq/version', __FILE__)
2
2
 
3
3
  Gem::Specification.new do |gem|
4
4
  gem.authors = ["Travis Reeder"]
5
- gem.email = ["treeder@gmail.com"]
5
+ gem.email = ["travis@iron.io"]
6
6
  gem.description = "Ruby client for IronMQ by www.iron.io"
7
7
  gem.summary = "Ruby client for IronMQ by www.iron.io"
8
8
  gem.homepage = "https://github.com/iron-io/iron_mq_ruby"
@@ -16,9 +16,10 @@ Gem::Specification.new do |gem|
16
16
 
17
17
  gem.required_rubygems_version = ">= 1.3.6"
18
18
  gem.required_ruby_version = Gem::Requirement.new(">= 1.9")
19
- gem.add_runtime_dependency "iron_core", ">= 0.4.2"
19
+ gem.add_runtime_dependency "iron_core", ">= 0.4.4"
20
20
 
21
21
  gem.add_development_dependency "test-unit"
22
+ gem.add_development_dependency "minitest"
22
23
  gem.add_development_dependency "rake"
23
24
  gem.add_development_dependency "beanstalk-client"
24
25
  gem.add_development_dependency "uber_config"
@@ -1,6 +1,7 @@
1
1
  require 'yaml'
2
2
 
3
3
  require 'iron_core'
4
+ require_relative 'queues'
4
5
 
5
6
  module IronMQ
6
7
 
@@ -1,20 +1,42 @@
1
+ require 'cgi'
2
+
1
3
  module IronMQ
2
4
  class Messages
3
5
 
4
- attr_accessor :client
6
+ attr_reader :client, :queue
5
7
 
6
- def initialize(client)
8
+ def initialize(client, queue=nil)
7
9
  @client = client
10
+ @queue = queue
8
11
  end
9
12
 
13
+
10
14
  def path(options={})
11
- path = "projects/#{@client.project_id}/queues/#{options[:queue_name] || options['queue_name'] || @client.queue_name}/messages"
15
+ options[:queue_name] ||= ((@queue ? @queue.name : nil) || @client.queue_name)
16
+ options[:project_id] = @client.project_id
17
+ Messages.path(options)
18
+ end
19
+
20
+ def self.path(options)
21
+ path = "#{Queues.path(options)}/messages"
22
+ if options[:msg_id]
23
+ path << "/#{options[:msg_id]}"
24
+ end
25
+ path
12
26
  end
13
27
 
14
28
  # options:
15
29
  # :queue_name => can specify an alternative queue name
16
30
  # :timeout => amount of time before message goes back on the queue
17
31
  def get(options={})
32
+ if options.is_a?(String)
33
+ # assume it's an id
34
+ puts 'get_by_id'
35
+ return Message.new(self, {'id'=>options}, options)
36
+ #r = @client.get(path(:msg_id=>options))
37
+ #p r
38
+ #return r
39
+ end
18
40
  res = @client.parse_response(@client.get(path(options), options))
19
41
  ret = []
20
42
  res["messages"].each do |m|
@@ -70,31 +92,8 @@ module IronMQ
70
92
 
71
93
  end
72
94
 
73
- class ResponseBase
74
-
75
- def initialize(res)
76
- @data = res
77
- end
78
-
79
- def raw
80
- @data
81
- end
82
-
83
- def [](key)
84
- raw[key]
85
- end
86
-
87
- def id
88
- raw["id"]
89
- end
90
-
91
- def msg
92
- raw["msg"]
93
- end
94
-
95
- end
96
-
97
95
  class Message < ResponseBase
96
+ attr_reader :messages
98
97
 
99
98
  def initialize(messages, res, options={})
100
99
  super(res)
@@ -102,7 +101,6 @@ module IronMQ
102
101
  @options = options
103
102
  end
104
103
 
105
-
106
104
  def body
107
105
  raw["body"]
108
106
  end
@@ -116,6 +114,15 @@ module IronMQ
116
114
  options2 = options.merge(@options) if @options
117
115
  @messages.release(self.id, options2)
118
116
  end
119
- end
120
117
 
118
+ def subscribers(options={})
119
+ res = @messages.client.get(@messages.path(options.merge(msg_id: id)) + "/subscribers", options)
120
+ res = @messages.client.parse_response(res)
121
+ ret = []
122
+ res['subscribers'].each do |m|
123
+ ret << Subscriber.new(m, self, options)
124
+ end
125
+ ret
126
+ end
127
+ end
121
128
  end
@@ -1,3 +1,6 @@
1
+ require 'cgi'
2
+ require_relative 'subscribers'
3
+
1
4
  module IronMQ
2
5
  class Queues
3
6
 
@@ -7,14 +10,20 @@ module IronMQ
7
10
  @client = client
8
11
  end
9
12
 
10
- def path(options={})
11
- path = "projects/#{@client.project_id}/queues"
12
- if options[:name]
13
- path << "/#{CGI::escape(options[:name])}"
13
+ def self.path(options)
14
+ path = "projects/#{options[:project_id]}/queues"
15
+ name = options[:name] || options[:queue_name] || options['queue_name']
16
+ if name
17
+ path << "/#{CGI::escape(name)}"
14
18
  end
15
19
  path
16
20
  end
17
21
 
22
+ def path(options={})
23
+ options[:project_id] = @client.project_id
24
+ Queues.path(options)
25
+ end
26
+
18
27
  def list(options={})
19
28
  ret = []
20
29
  r1 = @client.get("#{path(options)}", options)
@@ -46,20 +55,22 @@ module IronMQ
46
55
  # :name => can specify an alternative queue name
47
56
  def get(options={})
48
57
  options[:name] ||= @client.queue_name
49
- res = @client.parse_response(@client.get("#{path(options)}"))
58
+ r = @client.get("#{path(options)}")
59
+ puts "HEADERS"
60
+ p r.headers
61
+ res = @client.parse_response(r)
50
62
  return Queue.new(@client, res)
51
63
  end
52
64
 
53
65
  # Update a queue
54
66
  # options:
55
67
  # :name => if not specified, will use global queue name
56
- # :subscriptions => url's to subscribe to
68
+ # :subscribers => url's to subscribe to
57
69
  def post(options={})
58
70
  options[:name] ||= @client.queue_name
59
71
  res = @client.parse_response(@client.post(path(options), options))
60
- res
61
72
  p res
62
-
73
+ res
63
74
  end
64
75
 
65
76
 
@@ -67,6 +78,8 @@ module IronMQ
67
78
 
68
79
  class Queue
69
80
 
81
+ attr_reader :client
82
+
70
83
  def initialize(client, res)
71
84
  @client = client
72
85
  @data = res
@@ -89,14 +102,20 @@ module IronMQ
89
102
  end
90
103
 
91
104
  def reload
92
- load_queue
105
+ load_queue(:force => true)
106
+ end
107
+
108
+ def messages
109
+ raw["messages"]
93
110
  end
94
111
 
95
112
  # Used if lazy loading
96
- def load_queue
113
+ def load_queue(options={})
114
+ return if @loaded && !options[:force]
97
115
  q = @client.queues.get(:name => name)
98
116
  @client.logger.debug "GOT Q: " + q.inspect
99
117
  @data = q.raw
118
+ @loaded = true
100
119
  q
101
120
  end
102
121
 
@@ -105,23 +124,43 @@ module IronMQ
105
124
  end
106
125
 
107
126
  def delete_queue()
108
- @client.queues.delete(:name=>name)
127
+ @client.queues.delete(:name => name)
128
+ end
129
+
130
+ # updates the Queue object itself
131
+ def update_queue(options)
132
+ @client.queues.post(options.merge(:name => name))
109
133
  end
110
134
 
111
135
  def size
112
- return raw["size"] if raw["size"]
113
- return @size if @size
114
- q = load_queue()
115
- @size = q.size
116
- @size
136
+ load_queue()
137
+ return raw["size"]
117
138
  end
118
139
 
119
140
  def total_messages
120
- return raw["total_messages"] if raw["total_messages"]
121
- return @total_messages if @total_messages
122
- q = load_queue()
123
- @total_messages = q.total_messages
124
- @total_messages
141
+ load_queue()
142
+ return raw["total_messages"]
143
+ end
144
+
145
+ def subscribers
146
+ load_queue()
147
+ return raw["subscribers"]
148
+ end
149
+
150
+ def add_subscriber(subscriber_hash, options={})
151
+ puts 'add_subscriber'
152
+ res = @client.post("#{@client.queues.path(name: name)}/subscribers", subscribers: [subscriber_hash])
153
+ res = @client.parse_response(res)
154
+ p res
155
+ res
156
+ end
157
+
158
+ def remove_subscriber(subscriber_hash)
159
+ puts 'remove_subscriber'
160
+ res = @client.delete("#{@client.queues.path(name: name)}/subscribers", {subscribers: [subscriber_hash]}, {"Content-Type"=>@client.content_type})
161
+ res = @client.parse_response(res)
162
+ p res
163
+ res
125
164
  end
126
165
 
127
166
  def post(body, options={})
@@ -132,6 +171,11 @@ module IronMQ
132
171
  @client.messages.get(options.merge(:queue_name => name))
133
172
  end
134
173
 
174
+ def delete(id, options={})
175
+ @client.messages.delete(id, options.merge(:queue_name => name))
176
+ end
177
+
178
+
135
179
  # This will continuously poll for a message and pass it to the block. For example:
136
180
  #
137
181
  # queue.poll { |msg| puts msg.body }
@@ -157,8 +201,8 @@ module IronMQ
157
201
  end
158
202
  end
159
203
 
160
- def delete(id, options={})
161
- @client.messages.delete(id, options.merge(:queue_name => name))
204
+ def messages
205
+ Messages.new(client, self)
162
206
  end
163
207
 
164
208
  end
@@ -0,0 +1,27 @@
1
+
2
+ module IronMQ
3
+
4
+ class ResponseBase
5
+
6
+ attr_reader :raw
7
+
8
+ def initialize(raw)
9
+ @raw = raw
10
+ end
11
+
12
+ def [](key)
13
+ raw[key]
14
+ end
15
+
16
+ def id
17
+ raw["id"]
18
+ end
19
+
20
+ def msg
21
+ raw["msg"]
22
+ end
23
+
24
+ end
25
+
26
+
27
+ end
@@ -0,0 +1,34 @@
1
+ module IronMQ
2
+ class Subscribers
3
+ def self.path(options)
4
+ path = "#{Messages.path(options)}/subscribers"
5
+ if options[:subscriber_id]
6
+ path << "/#{options[:subscriber_id]}"
7
+ end
8
+ path
9
+ end
10
+ end
11
+
12
+ class Subscriber < ResponseBase
13
+ attr_accessor :options
14
+
15
+ def initialize(raw, message, options={})
16
+ super(raw)
17
+ @message = message
18
+ @options = options
19
+ end
20
+
21
+ def delete(options={})
22
+ client = @message.messages.client
23
+
24
+ options[:subscriber_id] ||= @raw["id"]
25
+ options[:msg_id] ||= @message.id
26
+ options[:project_id] ||= client.project_id
27
+ options[:queue_name] ||= client.queue_name
28
+ path = Subscribers.path(options)
29
+ raw = client.delete(path)
30
+ res = client.parse_response(raw)
31
+ return ResponseBase.new(res)
32
+ end
33
+ end
34
+ end
@@ -1,3 +1,4 @@
1
1
  module IronMQ
2
- VERSION = "2.1.3"
2
+ VERSION = "3.0.0"
3
3
  end
4
+
data/lib/iron_mq.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'rest'
2
+ require_relative 'iron_mq/response'
2
3
  require_relative 'iron_mq/queues'
3
4
  require_relative 'iron_mq/messages'
4
5
  require_relative 'iron_mq/client'
data/test/quick_run.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  require_relative 'test_base'
2
2
 
3
+ TIMES = 1
4
+
3
5
  class QuickRun < TestBase
4
6
 
5
7
  def setup
@@ -10,39 +12,43 @@ class QuickRun < TestBase
10
12
 
11
13
  def test_basics
12
14
 
13
- res = @client.messages.post("hello world!")
14
- p res
15
- assert res.id
16
- post_id = res.id
17
- assert res.msg
18
-
19
- res = @client.messages.get()
20
- p res
21
- puts "post_id=" + post_id.inspect
22
- assert res.id
23
- assert_equal res.id, post_id
24
- assert res.body
25
-
26
- res = @client.messages.delete(res["id"])
27
- p res
28
- assert res.msg
29
-
30
- res = @client.messages.get()
31
- p res
32
- assert res.nil?
33
-
34
- res = @client.messages.post("hello world!", :queue_name=>'test2')
35
- p res
36
- assert res.id
37
- assert res.msg
38
-
39
- res = @client.messages.get(:queue_name=>'test2')
40
- p res
41
- assert res.id
42
- assert res.body
43
-
44
- res = res.delete
45
- p res
15
+ TIMES.times do |i|
16
+ puts "==== LOOP #{i} =================================="
17
+
18
+ res = @client.messages.post("hello world!")
19
+ p res
20
+ assert res.id
21
+ post_id = res.id
22
+ assert res.msg
23
+
24
+ res = @client.messages.get()
25
+ p res
26
+ puts "post_id=" + post_id.inspect
27
+ assert res.id
28
+ assert_equal res.id, post_id
29
+ assert res.body
30
+
31
+ res = @client.messages.delete(res["id"])
32
+ p res
33
+ assert res.msg
34
+
35
+ res = @client.messages.get()
36
+ p res
37
+ assert res.nil?
38
+
39
+ res = @client.messages.post("hello world!", :queue_name => 'test2')
40
+ p res
41
+ assert res.id
42
+ assert res.msg
43
+
44
+ res = @client.messages.get(:queue_name => 'test2')
45
+ p res
46
+ assert res.id
47
+ assert res.body
48
+
49
+ res = res.delete
50
+ p res
51
+ end
46
52
 
47
53
 
48
54
  end
data/test/test_base.rb CHANGED
@@ -9,14 +9,21 @@ rescue Exception => ex
9
9
  raise ex
10
10
  end
11
11
 
12
+ LOG = Logger.new(STDOUT)
13
+ MAX_TRIES = 100
12
14
 
13
15
  class TestBase < Test::Unit::TestCase
16
+
14
17
  def setup
15
18
  puts 'setup'
16
19
  # check multiple config locations
17
20
  @config = UberConfig.load
18
21
  puts "config=" + @config.inspect
22
+
23
+ config = @config['iron']
24
+ @host = "#{config['host'] || "mq-aws-us-east-1.iron.io"}"
19
25
  @client = IronMQ::Client.new(@config['iron'])
26
+ Rest.logger.level = Logger::DEBUG # this doesn't work for some reason?
20
27
  IronCore::Logger.logger.level = Logger::DEBUG
21
28
  @client.queue_name = 'ironmq-ruby-tests'
22
29
 
@@ -26,11 +33,8 @@ class TestBase < Test::Unit::TestCase
26
33
  def clear_queue(queue_name=nil)
27
34
  queue_name ||= @client.queue_name
28
35
  puts "clearing queue #{queue_name}"
29
- while res = @client.messages.get(:queue_name=>queue_name)
30
- p res
31
- puts res.body.to_s
32
- res.delete
33
- end
36
+ @client.queue(queue_name).post("test")
37
+ @client.queue(queue_name).clear
34
38
  puts 'cleared.'
35
39
  end
36
40
 
@@ -9,11 +9,11 @@ class BeanstalkTests < TestBase
9
9
  super
10
10
 
11
11
  config = @config['iron']
12
- @host = "#{config['host'] || "mq-aws-us-east-1.iron.io"}:#{config['beanstalkd_port'] || 11300}"
13
- puts "beanstalkd url: #{@host}"
12
+ beanstalkd_host = "#{@host}:#{config['beanstalkd_port'] || 11300}"
13
+ puts "beanstalkd url: #{beanstalkd_host}"
14
14
  @skip = @host.include? 'rackspace'
15
15
  return if @skip # bypass these tests if rackspace
16
- @beanstalk = Beanstalk::Connection.new(@host)
16
+ @beanstalk = Beanstalk::Connection.new(beanstalkd_host)
17
17
  @beanstalk.put("oauth #{config['token']} #{config['project_id']}")
18
18
 
19
19
  clear_tube('default')