propono 1.7.0 → 2.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +2 -9
  4. data/CHANGELOG.md +9 -0
  5. data/Gemfile +0 -2
  6. data/README.md +35 -91
  7. data/lib/propono.rb +4 -144
  8. data/lib/propono/components/aws_client.rb +78 -0
  9. data/lib/propono/components/aws_config.rb +4 -9
  10. data/lib/propono/components/client.rb +93 -0
  11. data/lib/propono/components/queue.rb +4 -6
  12. data/lib/propono/components/queue_subscription.rb +32 -22
  13. data/lib/propono/components/sqs_message.rb +3 -6
  14. data/lib/propono/components/topic.rb +6 -5
  15. data/lib/propono/configuration.rb +0 -2
  16. data/lib/propono/services/publisher.rb +21 -44
  17. data/lib/propono/services/queue_listener.rb +54 -57
  18. data/lib/propono/version.rb +1 -1
  19. data/propono.gemspec +3 -2
  20. data/test/components/aws_config_test.rb +4 -4
  21. data/test/components/client_test.rb +68 -0
  22. data/test/components/queue_subscription_test.rb +68 -70
  23. data/test/components/queue_test.rb +6 -3
  24. data/test/components/topic_test.rb +4 -2
  25. data/test/configuration_test.rb +27 -55
  26. data/test/integration/integration_test.rb +4 -7
  27. data/test/integration/slow_queue_test.rb +11 -8
  28. data/test/integration/sns_to_sqs_test.rb +17 -17
  29. data/test/services/publisher_test.rb +59 -156
  30. data/test/services/queue_listener_test.rb +96 -103
  31. data/test/test_helper.rb +21 -48
  32. metadata +26 -39
  33. data/lib/propono/components/post_subscription.rb +0 -19
  34. data/lib/propono/components/sns.rb +0 -11
  35. data/lib/propono/components/sqs.rb +0 -12
  36. data/lib/propono/services/queue_creator.rb +0 -29
  37. data/lib/propono/services/subscriber.rb +0 -12
  38. data/lib/propono/services/tcp_listener.rb +0 -48
  39. data/lib/propono/services/topic_creator.rb +0 -23
  40. data/lib/propono/services/udp_listener.rb +0 -52
  41. data/test/components/post_subscription_test.rb +0 -29
  42. data/test/components/sns_test.rb +0 -25
  43. data/test/components/sqs_test.rb +0 -26
  44. data/test/integration/tcp_to_sqs_test.rb +0 -53
  45. data/test/integration/udp_proxy_test.rb +0 -50
  46. data/test/integration/udp_to_sqs_test.rb +0 -53
  47. data/test/propono_test.rb +0 -83
  48. data/test/services/queue_creator_test.rb +0 -61
  49. data/test/services/subscriber_test.rb +0 -21
  50. data/test/services/tcp_listener_test.rb +0 -76
  51. data/test/services/topic_creator_test.rb +0 -40
  52. data/test/services/udp_listener_test.rb +0 -73
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 013ba7a6dc0e9ffb8fa06aefbec64ee0c398f933
4
- data.tar.gz: 1fd1f5e5b5cca50704e67bc874e33c79360c846a
3
+ metadata.gz: d42471617c3c3d8f3b41074c4088e86a812c7c7d
4
+ data.tar.gz: 7403c09c886c595f642460307b0636e651a5cea1
5
5
  SHA512:
6
- metadata.gz: b5a91dcbc2c42611e718affa73fd7be0a16f8d59d7585384dff86c272bece9d47d2d46dcf45466b8acb515778b181059e63d60cffd40e250643d8e6e2052b334
7
- data.tar.gz: 44ff1b11418f68dca4f5886a66f8c709251310f362f1ec24bf1c450a76e3d42b0e628a6ee93546c7841b56e431b17f9030b7e2a292aa7ec7655a1d1acd589173
6
+ metadata.gz: f21cda9adb199d017845d6155c3721c9f9d4697cee57daa20b7ba90748594c3380f1eddc78f0f1af43b4b61a8778a0810f0792a3bfe770b29e84ac9ed618af42
7
+ data.tar.gz: b6dedfd0fc6645cd8400251a3dadba0f62ef28d685ec3eef47ab55b461e9129c20cfa07f77120c2c37d0d20e2b61d5619d9266c764ff90a279311a835e9f7aeb
data/.gitignore CHANGED
@@ -15,5 +15,6 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  test/config.yml
18
+ manual_test.rb
18
19
  tmp
19
20
  *.swp
@@ -1,14 +1,7 @@
1
1
  language: ruby
2
2
  cache: bundler
3
3
  rvm:
4
- - 1.9.3
5
- - 2.0.0
6
- - rbx-2.1.1
4
+ - 2.2.8
5
+ - 2.4.2
7
6
  script:
8
7
  - bundle exec rake test:local
9
- addons:
10
- code_climate:
11
- repo_token: 88dd239bc2e0010742a42a4e0234b4decd19b46d0e9d3408d8b1fe0f96dd8fc1
12
- matrix:
13
- allow_failures:
14
- - rvm: rbx-2.1.1
@@ -1,3 +1,12 @@
1
+ # 2.0.0 / 2017-03-14
2
+ * [FEATURE] Remove UDP and TCP support
3
+ * [FEATURE] Change default publish behaviour from async to sync
4
+ * [FEATURE] Propono.subscripe_by_post has been removed
5
+ * [FEATURE] Propono.subscripe_by_queue has been renamed to subscribe
6
+ * [FEATURE] Change to Propono::Client interface
7
+ * [FEATURE] Switch fog out for aws gems
8
+ * [FEATURE] Use long polling
9
+
1
10
  # 1.7.0 / 2017-01-17
2
11
  * [FEATURE] Added num_messages_per_poll config option to allow you to change how many messages you pull from AWS per poll cycle.
3
12
 
data/Gemfile CHANGED
@@ -2,5 +2,3 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in propono.gemspec
4
4
  gemspec
5
-
6
- gem "codeclimate-test-reporter", group: :test, require: nil
data/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # Propono
2
2
 
3
- [![Build Status](https://travis-ci.org/meducation/propono.png)](https://travis-ci.org/meducation/propono)
4
- [![Dependencies](https://gemnasium.com/meducation/propono.png?travis)](https://gemnasium.com/meducation/propono)
5
- [![Code Climate](https://codeclimate.com/github/meducation/propono.png)](https://codeclimate.com/github/meducation/propono)
3
+ [![Build Status](https://travis-ci.org/iHiD/propono.png)](https://travis-ci.org/iHiD/propono)
4
+ [![Dependencies](https://gemnasium.com/iHiD/propono.png?travis)](https://gemnasium.com/iHiD/propono)
5
+ [![Code Climate](https://codeclimate.com/github/iHiD/propono.png)](https://codeclimate.com/github/iHiD/propono)
6
6
 
7
7
  Propono is a [pub/sub](http://en.wikipedia.org/wiki/Publish-subscribe_pattern) gem built on top of Amazon Web Services (AWS). It uses Simple Notification Service (SNS) and Simple Queue Service (SQS) to seamlessly pass messages throughout your infrastructure.
8
8
 
@@ -10,17 +10,25 @@ It's beautifully simple to use. [Watch an introduction](https://www.youtube.com/
10
10
 
11
11
  ```ruby
12
12
  # On Machine A
13
- Propono.listen_to_queue('some-topic') do |message|
13
+ Propono::Client.new.listen_to_queue('some-topic') do |message|
14
14
  puts "I just received: #{message}"
15
15
  end
16
16
 
17
17
  # On Machine B
18
- Propono.publish('some-topic', "The Best Message Ever")
18
+ Propono::Client.new.publish('some-topic', "The Best Message Ever")
19
19
 
20
20
  # Output on Machine A a second later.
21
21
  # - "I just received The Best Message Ever"
22
22
  ```
23
23
 
24
+ ## Changes from v1 to v2
25
+
26
+ Version 2 of Propono changed a few things:
27
+ - We moved from a global interface to a client interface. Rather than calling `publish` and equivalent on `Propono`, you should now initialize a `Propono::Client` and then call everything on that client. This fixes issues with thread safety and global config.
28
+ - We have also removed the dependancy on Fog and instead switch to the `sns` and `sqs` mini-gems of `aws-sdk`.
29
+ - UDP and TCP support have been removed, an subscribe_by_post has been removed.
30
+ - We are now using long-polling. This makes Propono **significantly** faster (10-100x).
31
+
24
32
  ## Installation
25
33
 
26
34
  Add this line to your application's Gemfile:
@@ -36,28 +44,31 @@ And then execute:
36
44
  The first thing to do is setup some configuration keys for Propono. It's best to do this in an initializer, or at the start of your application.
37
45
 
38
46
  ```ruby
39
- Propono.config.access_key = "access-key" # From AWS
40
- Propono.config.secret_key = "secret-key" # From AWS
41
- Propono.config.queue_region = "queue-region" # From AWS
47
+ client = Propono::Client.new
48
+ client.config.access_key = "access-key" # From AWS
49
+ client.config.secret_key = "secret-key" # From AWS
50
+ client.config.queue_region = "queue-region" # From AWS
42
51
 
43
52
  # Or use the IAM profile of the machine
44
- Propono.config.use_iam_profile = true
45
- Propono.config.queue_region = "queue-region" # From AWS
53
+ client.config.use_iam_profile = true
54
+ client.config.queue_region = "queue-region" # From AWS
46
55
 
47
56
  ```
48
57
 
49
58
  You can then start publishing messages easily from anywhere in your codebase.
50
59
 
51
60
  ```ruby
52
- Propono.publish('some-topic', "Some string")
53
- Propono.publish('some-topic', {some: ['hash', 'or', 'array']})
61
+ client = Propono::Client.new
62
+ client.publish('some-topic', "Some string")
63
+ client.publish('some-topic', {some: ['hash', 'or', 'array']})
54
64
  ```
55
65
 
56
66
  Listening for messages is easy too. Just tell Propono what your application is called and start listening. You'll get a block yielded for each message.
57
67
 
58
68
  ```ruby
59
- Propono.config.application_name = "application-name" # Something unique to this app.
60
- Propono.listen_to_queue('some-topic') do |message|
69
+ client = Propono::Client.new
70
+ client.config.application_name = "application-name" # Something unique to this app.
71
+ client.listen_to_queue('some-topic') do |message|
61
72
  # ... Do something interesting with the message
62
73
  end
63
74
  ```
@@ -70,75 +81,12 @@ This is because a queue is established for each application_name/topic combinati
70
81
  * subscribers that share the same `application_name` will act as multiple workers on the same queue. Only one will get to process each message.
71
82
  * subscribers that have a different `application_name` will each get a copy of a message to process independently i.e. acts as a one-to-many broadcast.
72
83
 
73
-
74
- **Note for using in Rake tasks and similar:** Propono spawns new threads for messages sent via SNS. If your application ends before the final thread is executed, then the last message might not send. There are two options to help you here:
75
- * Pass the `{async: false}` option to Propono.publish. (This was introduced in 1.3.0)
76
- * Do a `Thread#join` on each thread that is returned from calls to `publish`.
77
-
78
- ### Using TCP for messages
79
-
80
- Publishing directly to SNS takes about 15x longer than publishing over a simple TCP connection. It is therefore sometimes favourable to publish to a separate machine listening for TCP messages, which will then proxy them on.
81
-
82
- To send messages this way, you need to set up a little extra config:
83
-
84
- ```ruby
85
- Propono.config.tcp_host = "some.host.running.a.propono.listener"
86
- Propono.config.tcp_port = 12543
87
- ```
88
-
89
- You then simply pass the `:tcp` protocol into `publish`
90
-
91
- ```ruby
92
- Propono.publish('some-topic', message, protocol: :tcp)
93
- ```
94
-
95
- You'll now need another application running Propono to listen to the TCP feed. You can use the same machine or a different one, just make sure the port config is the same in both applications, and you're good to go.
96
-
97
- ```ruby
98
- Propono.listen_to_tcp do |topic, message|
99
- Propono.publish(topic, message) # Proxy the message to SNS
100
- end
101
- ```
102
-
103
- This proxying of TCP to SQS is used so often that there's a simple shortcut. Just run this on the machine receiving the TCP packets.
104
-
105
- ```ruby
106
- Propono.proxy_tcp()
107
- ```
108
-
109
- ### Using UDP for messages
110
-
111
- If you want almost-zero performance impact, and don't mind the occasional message getting lost, you can use UDP. We use this for things like our live dashboard where we don't mind losing a piece of activity here and there, but any performance impact on our Meducation itself is bad news.
112
-
113
- Sending messages in this way is very similar to using TCP. First add some config:
114
-
115
- ```ruby
116
- Propono.config.udp_host = "some.host.running.a.propono.listener"
117
- Propono.config.udp_port = 12543
118
- ```
119
-
120
- You then simply pass the `:udp` protocol into `publish`:
121
-
122
- ```ruby
123
- Propono.publish('some-topic', message, protocol: :udp)
124
- ```
125
-
126
- As per the `listen_to_tcp` method explained above, you now listen to UDP or use the proxy method:
127
-
128
- ```ruby
129
- Propono.listen_to_udp do |topic, message|
130
- Propono.publish(topic, message) # Proxy the message to SNS
131
- end
132
-
133
- Propono.proxy_udp()
134
- ```
135
-
136
84
  ### Configuration
137
85
 
138
86
  The following configuration settings are available:
139
87
 
140
88
  ```
141
- Propono.config do |config|
89
+ Propono::Client.new do |config|
142
90
  # Use AWS access and secret keys
143
91
  config.access_key = "An AWS access key"
144
92
  config.secret_key = "A AWS secret key"
@@ -147,10 +95,6 @@ Propono.config do |config|
147
95
 
148
96
  config.queue_region = "An AWS queue region"
149
97
  config.application_name = "A name unique in your network"
150
- config.udp_host = "The host of a machine used for UDP proxying"
151
- config.udp_port = "The port of a machine used for UDP proxying"
152
- config.tcp_host = "The host of a machine used for TCP proxying"
153
- config.tcp_port = "The port of a machine used for TCP proxying"
154
98
  config.logger = "A logger such as Log4r or Rails.logger"
155
99
 
156
100
  config.max_retries = "The number of retries if a message raises an exception before being placed on the failed queue"
@@ -158,7 +102,7 @@ Propono.config do |config|
158
102
  end
159
103
  ```
160
104
 
161
- These can all also be set using the `Propono.config.access_key = "..."` syntax.
105
+ These can all also be set using the `client.config.access_key = "..."` syntax.
162
106
 
163
107
  ### Is it any good?
164
108
 
@@ -168,22 +112,22 @@ These can all also be set using the `Propono.config.access_key = "..."` syntax.
168
112
 
169
113
  Firstly, thank you!! :heart::sparkling_heart::heart:
170
114
 
171
- We'd love to have you involved. Please read our [contributing guide](https://github.com/meducation/propono/tree/master/CONTRIBUTING.md) for information on how to get stuck in.
115
+ We'd love to have you involved. Please read our [contributing guide](https://github.com/iHiD/propono/tree/master/CONTRIBUTING.md) for information on how to get stuck in.
172
116
 
173
117
  ### Contributors
174
118
 
175
- This project is managed by the [Meducation team](http://company.meducation.net/about#team).
119
+ This project is managed by the [Jeremy Walker](http://ihid.co.uk).
176
120
 
177
121
  These individuals have come up with the ideas and written the code that made this possible:
178
122
 
179
- - [Jeremy Walker](http://github.com/iHiD)
180
- - [Malcolm Landon](http://github.com/malcyL)
181
- - [Charles Care](http://github.com/ccare)
182
- - [Rob Styles](http://github.com/mmmmmrob)
123
+ - [Jeremy Walker](https://github.com/iHiD)
124
+ - [Malcolm Landon](https://github.com/malcyL)
125
+ - [Charles Care](https://github.com/ccare)
126
+ - [Rob Styles](https://github.com/mmmmmrob)
183
127
 
184
128
  ## Licence
185
129
 
186
- Copyright (C) 2015 New Media Education Ltd
130
+ Copyright (C) 2017 Jeremy Walker
187
131
 
188
132
  This program is free software: you can redistribute it and/or modify
189
133
  it under the terms of the MIT License.
@@ -193,5 +137,5 @@ but WITHOUT ANY WARRANTY; without even the implied warranty of
193
137
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
194
138
  MIT License for more details.
195
139
 
196
- A copy of the MIT License is available in [Licence.md](https://github.com/meducation/propono/blob/master/LICENCE.md)
140
+ A copy of the MIT License is available in [LICENCE.md](https://github.com/iHiD/propono/blob/master/LICENCE.md)
197
141
  along with this program.
@@ -7,161 +7,21 @@ require 'propono/logger'
7
7
  require 'propono/configuration'
8
8
  require "propono/utils"
9
9
 
10
+ require 'propono/components/client'
11
+
10
12
  require 'propono/components/aws_config'
11
- require 'propono/components/sns'
12
- require 'propono/components/sqs'
13
+ require 'propono/components/aws_client'
14
+
13
15
  require "propono/components/queue"
14
16
  require "propono/components/topic"
15
- require "propono/components/post_subscription"
16
17
  require "propono/components/queue_subscription"
17
18
  require "propono/components/sqs_message"
18
19
 
19
20
  require "propono/services/publisher"
20
- require "propono/services/queue_creator"
21
21
  require "propono/services/queue_listener"
22
- require "propono/services/subscriber"
23
- require "propono/services/topic_creator"
24
- require "propono/services/udp_listener"
25
- require "propono/services/tcp_listener"
26
22
 
27
23
  # Propono is a pub/sub gem built on top of Amazon Web Services (AWS).
28
24
  # It uses Simple Notification Service (SNS) and Simple Queue Service (SQS)
29
25
  # to seamlessly pass messages throughout your infrastructure.
30
26
  module Propono
31
-
32
- # Propono configuration settings.
33
- #
34
- # Settings should be set in an initializer or using some
35
- # other method that insures they are set before any
36
- # Propono code is used. They can be set as followed:
37
- #
38
- # Propono.config.access_key = "my-access-key"
39
- #
40
- # The following settings are allowed:
41
- #
42
- # * <tt>:access_key</tt> - The AWS access key
43
- # * <tt>:secret_key</tt> - The AWS secret key
44
- # * <tt>:queue_region</tt> - The AWS region
45
- # * <tt>:application_name</tt> - The name of the application Propono
46
- # is included in.
47
- # * <tt>:queue_suffix</tt> - Optional string to append to topic and queue names.
48
- # * <tt>:udp_host</tt> - If using UDP, the host to send to.
49
- # * <tt>:udp_port</tt> - If using UDP, the port to send to.
50
- # * <tt>:logger</tt> - A logger object that responds to puts.
51
- def self.config
52
- @config ||= Configuration.new
53
- if block_given?
54
- yield @config
55
- else
56
- @config
57
- end
58
- end
59
-
60
- # Publishes a new message into the Propono pub/sub network.
61
- #
62
- # This requires a topic and a message. By default this pushes
63
- # out AWS SNS. The method optionally takes a :protocol key in
64
- # options, which can be set to :udp for non-guaranteed but very
65
- # fast delivery.
66
- #
67
- # @param [String] topic The name of the topic to publish to.
68
- # @param [String] message The message to post.
69
- # @param [Hash] options
70
- # * protocol: :udp
71
- def self.publish(topic, message, options = {})
72
- suffixed_topic = "#{topic}#{Propono.config.queue_suffix}"
73
- Publisher.publish(suffixed_topic, message, options)
74
- end
75
-
76
- # Creates a new SNS-SQS subscription on the specified topic.
77
- #
78
- # This is implicitly called by {#listen_to_queue}.
79
- #
80
- # @param [String] topic The name of the topic to subscribe to.
81
- def self.subscribe_by_queue(topic)
82
- Subscriber.subscribe_by_queue(topic)
83
- end
84
-
85
- # Creates a new SNS-POST subscription on the specified topic.
86
- #
87
- # The POST currently needs confirming before the subscription
88
- # can be published to.
89
- #
90
- # @param [String] topic The name of the topic to subscribe to.
91
- def self.subscribe_by_post(topic, endpoint)
92
- Subscriber.subscribe_by_post(topic, endpoint)
93
- end
94
-
95
- # Listens on a queue and yields for each message
96
- #
97
- # Calling this will enter a queue-listening loop that
98
- # yields the message_processor for each messages.
99
- #
100
- # This method will automatically create a subscription if
101
- # one does not exist, so there is no need to call
102
- # <tt>subscribe_by_queue</tt> in addition.
103
- #
104
- # @param [String] topic The topic to subscribe to.
105
- # @param &message_processor The block to yield for each message.
106
- def self.listen_to_queue(topic, &message_processor)
107
- QueueListener.listen(topic, &message_processor)
108
- end
109
-
110
- # Listens on a queue and yields for each message
111
- #
112
- # Calling this will enter a queue-listening loop that
113
- # yields the message_processor for each messages. The
114
- # loop will end when all messages have been processed.
115
- #
116
- # This method will automatically create a subscription if
117
- # one does not exist, so there is no need to call
118
- # <tt>subscribe_by_queue</tt> in addition.
119
- #
120
- # @param [String] topic The topic to subscribe to.
121
- # @param &message_processor The block to yield for each message.
122
- def self.drain_queue(topic, &message_processor)
123
- QueueListener.drain(topic, &message_processor)
124
- end
125
-
126
- # Listens for UDP messages and yields for each.
127
- #
128
- # Calling this will enter a queue-listening loop that
129
- # yields the message_processor for each UDP message received.
130
- #
131
- # @param &message_processor The block to yield for each message.
132
- # Is called with <tt>|topic, message|</tt>.
133
- def self.listen_to_udp(&message_processor)
134
- UdpListener.listen(&message_processor)
135
- end
136
-
137
- # Listens for TCP messages and yields for each.
138
- #
139
- # Calling this will enter a queue-listening loop that
140
- # yields the message_processor for each UDP message received.
141
- #
142
- # @param &message_processor The block to yield for each message.
143
- # Is called with <tt>|topic, message|</tt>.
144
- def self.listen_to_tcp(&message_processor)
145
- TcpListener.listen(&message_processor)
146
- end
147
-
148
- # Listens for UDP messages and passes them onto the queue.
149
- #
150
- # This method uses #listen_to_udp and #publish to proxy
151
- # messages from UDP onto the queue.
152
- def self.proxy_udp
153
- Propono.listen_to_udp do |topic, message, options = {}|
154
- Propono.publish(topic, message, options)
155
- end
156
- end
157
-
158
- # Listens for TCP messages and passes them onto the queue.
159
- #
160
- # This method uses #listen_to_tcp and #publish to proxy
161
- # messages from TCP onto the queue.
162
- def self.proxy_tcp
163
- Propono.listen_to_tcp do |topic, message, options = {}|
164
- Propono.publish(topic, message, options)
165
- end
166
- end
167
27
  end
@@ -0,0 +1,78 @@
1
+ #require 'aws/sns'
2
+ #require 'aws/sqs'
3
+ require 'aws-sdk-sns'
4
+ require 'aws-sdk-sqs'
5
+
6
+ module Propono
7
+ class AwsClient
8
+ attr_reader :aws_config
9
+ def initialize(aws_config)
10
+ @aws_config = aws_config
11
+ end
12
+
13
+ def publish_to_sns(topic, message)
14
+ sns_client.publish(
15
+ topic_arn: topic.arn,
16
+ message: message.to_json
17
+ )
18
+ end
19
+
20
+ def send_to_sqs(queue, message)
21
+ sqs_client.send_message(
22
+ queue_url: queue,
23
+ message_body: message
24
+ )
25
+ end
26
+
27
+ def create_topic(name)
28
+ Topic.new(sns_client.create_topic(name: name))
29
+ end
30
+
31
+ def create_queue(name)
32
+ url = sqs_client.create_queue(queue_name: name).queue_url
33
+ attributes = sqs_client.get_queue_attributes(queue_url: url, attribute_names: ["QueueArn"]).attributes
34
+ Queue.new(url, attributes)
35
+ end
36
+
37
+ def subscribe_sqs_to_sns(queue, topic)
38
+ sns_client.subscribe(
39
+ topic_arn: topic.arn,
40
+ protocol: 'sqs',
41
+ endpoint: queue.arn
42
+ )
43
+ end
44
+
45
+ def set_sqs_policy(queue, policy)
46
+ sqs_client.set_queue_attributes(
47
+ queue_url: queue.url,
48
+ attributes: { "Policy": policy }
49
+ )
50
+ end
51
+
52
+ def read_from_sqs(queue, num_messages, long_poll: true)
53
+ wait_time_seconds = long_poll ? 20 : 0
54
+ sqs_client.receive_message(
55
+ queue_url: queue.url,
56
+ wait_time_seconds: wait_time_seconds,
57
+ max_number_of_messages: num_messages
58
+ ).messages
59
+ end
60
+
61
+ def delete_from_sqs(queue, receipt_handle)
62
+ sqs_client.delete_message(
63
+ queue_url: queue.url,
64
+ receipt_handle: receipt_handle
65
+ )
66
+ end
67
+
68
+ private
69
+
70
+ def sns_client
71
+ @sns_client ||= Aws::SNS::Client.new(aws_config.aws_options)
72
+ end
73
+
74
+ def sqs_client
75
+ @sqs_client ||= Aws::SQS::Client.new(aws_config.aws_options)
76
+ end
77
+ end
78
+ end