Compare commits

...

15 commits

Author SHA1 Message Date
Chas Emerick
a0fb4273b2 Merge pull request #11 from dacamo76/readme-long-polling-example
Update README with long-polling usage example
2014-09-13 07:30:15 -04:00
Daniel Alberto Cañas
478210ccb2 Update README with long-polling usage example 2014-09-12 16:26:30 -06:00
Chas Emerick
e4a15227f6 [maven-release-plugin] prepare for next development iteration 2014-09-09 08:02:07 -04:00
Chas Emerick
09e7772fd7 [maven-release-plugin] prepare release bandalore-0.0.6 2014-09-09 08:02:07 -04:00
Chas Emerick
42751b891a 0.0.6 2014-09-09 07:57:14 -04:00
Daniel Alberto Cañas
daffed7bcc Minimize Integer object construction
Use Integer.valueOf(int) factory method instead of new Integer(int) constructor
to take advantage of caching.
This is especially useful when creating millions of
ReceiveMessageRequests with the same options.
2014-06-24 21:48:33 -06:00
Daniel Alberto Cañas
ce8c02bdc4 Adds long polling support
Adds long polling support to receive message requests.
The option 'wait-time-seconds' has been added to the 'receive' function.
This option behaves exactly the same as the 'WaitTimeSeconds' parameter
of the ReceiveMessageRequest class in the AWS Java SDK.

The following text is shamelessly taken from the (docs
http://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-long-polling.html):

Long polling allows the Amazon SQS service to wait until a message is
available in the queue before sending a response. This helps reduce the
amount of empty responses, thus reducing costs.

Another benefit is reducing the false empty reponses, where messages are
available in the queue but are not included in the response.
This happens when Amazon SQS uses short (standard) polling, the default
behavior, where only a subset of the servers (based on a weighted random
distribution) are queried to see if any messages are available to
include in the response. On the other hand, when long polling is
enabled, Amazon SQS queries all of the servers.
2014-06-24 21:18:06 -06:00
Daniel Alberto Cañas
98cb434787 Bumps aws-sdk-java to 1.8.0
Updates version to support long polling.
2014-06-24 16:46:04 -06:00
Chas Emerick
bfb0fca2e7 0.0.5 in README 2013-12-11 07:46:15 -05:00
Chas Emerick
e9f1afbb50 [maven-release-plugin] prepare for next development iteration 2013-12-11 06:55:22 -05:00
Chas Emerick
3d1c859c62 [maven-release-plugin] prepare release bandalore-0.0.5 2013-12-11 06:55:22 -05:00
Tim Chagnon
382fd20418 Make :prefix a keyword argument of list-queues 2013-11-26 10:21:16 -08:00
Tim Chagnon
960c5e4966 Add optional prefix argument to list-queues 2013-11-25 21:07:09 -08:00
Chas Emerick
b7d186125c link to better page on IAM roles for Java devs 2013-10-17 06:52:15 -04:00
Chas Emerick
e31c010c08 [maven-release-plugin] prepare for next development iteration 2013-10-17 06:47:08 -04:00
4 changed files with 54 additions and 12 deletions

View file

@ -14,14 +14,14 @@ Bandalore is available in Maven central. Add it to your Maven project's `pom.xm
<dependency>
<groupId>com.cemerick</groupId>
<artifactId>bandalore</artifactId>
<version>0.0.4</version>
<version>0.0.6</version>
</dependency>
```
or your leiningen project.clj:
```clojure
[com.cemerick/bandalore "0.0.4"]
[com.cemerick/bandalore "0.0.6"]
```
Bandalore is compatible with Clojure 1.2.0+.
@ -56,7 +56,7 @@ to do anything:
**Security Note** If your application using Bandalore is deployed to EC2, _you
should not put your AWS credentials on those EC2 nodes_. Rather,
[give your EC2 instances IAM roles](http://docs.aws.amazon.com/IAM/latest/UserGuide/role-usecase-ec2app.html),
[give your EC2 instances IAM roles](http://docs.aws.amazon.com/AWSSdkDocsJava/latest/DeveloperGuide/java-dg-roles.html),
and use the nullary arity of `create-client`:
```clojure
@ -108,6 +108,28 @@ That's cleaner than having to interop directly with the Java SDK, but it's all
pretty pedestrian stuff. You can do more interesting things with some
simple higher-order functions and other nifty Clojure facilities.
### Enabling SQS Long Polling
[Long polling](http://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-long-polling.html) reduces the number of empty responses by allowing Amazon SQS service to wait until a message is available in the queue before sending a response. You can enable long polling on an individual receive request by supplying the optional kwarg `:wait-time-seconds`:
:wait-time-seconds - time in seconds (bewteen 0 and 20) for SQS to wait if there are no messages in the queue. A value of 0 indicates no long polling.
```clojure
; ensure our queue is empty to start
#> (get (sqs/queue-attrs client q) "ApproximateNumberOfMessages")
"0"
#> (let [no-polling (future (sqs/receive client q))
long-polling (future (sqs/receive client q :wait-time-seconds 20))]
(Thread/sleep 10000) ;; Sleep 10s before sending message
(sqs/send client q "my message body")
(println (count @no-polling))
(println (count @long-polling)))
0
1
nil
```
### Sending and receiving Clojure values
SQS' message bodies are strings, so you can stuff anything in them that you can

View file

@ -2,7 +2,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.cemerick</groupId>
<artifactId>bandalore</artifactId>
<version>0.0.4</version>
<version>0.0.7-SNAPSHOT</version>
<name>bandalore</name>
<description>A Clojure library for Amazon's Simple Queue Service (SQS).</description>
<url>http://github.com/cemerick/bandalore</url>
@ -36,7 +36,7 @@
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk</artifactId>
<version>1.3.21.1</version>
<version>1.8.0</version>
</dependency>
</dependencies>

View file

@ -50,9 +50,10 @@
(.deleteQueue client (DeleteQueueRequest. queue-url)))
(defn list-queues
"Returns a seq of all queues' URL strings."
[^AmazonSQSClient client]
(->> (ListQueuesRequest.)
"Returns a seq of all queues' URL strings. Takes an optional string prefix
argument to only list queues with names that start with the prefix."
[^AmazonSQSClient client & {:keys [prefix]}]
(->> (ListQueuesRequest. prefix)
(.listQueues client)
.getQueueUrls
seq))
@ -105,6 +106,11 @@
Defaults to the empty set (i.e. no attributes will be included in
received messages).
See the SQS documentation for all support message attributes.
:wait-time-seconds - enables long poll support. time is in seconds, bewteen
0 (default - no long polling) and 20.
Allows Amazon SQS service to wait until a message is available
in the queue before sending a response.
See the SQS documentation at (http://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-long-polling.html)
Returns a seq of maps with these slots:
@ -115,13 +121,17 @@
:receipt-handle - the ID used to delete the message from the queue after
it has been fully processed.
:source-queue - the URL of the queue from which the message was received"
[^AmazonSQSClient client queue-url & {:keys [limit visibility ^java.util.Collection attributes]
[^AmazonSQSClient client queue-url & {:keys [limit
visibility
wait-time-seconds
^java.util.Collection attributes]
:or {limit 1
attributes #{}}}]
(let [req (-> (ReceiveMessageRequest. queue-url)
(.withMaxNumberOfMessages (-> limit (min 10) (max 1) int Integer.))
(.withMaxNumberOfMessages (-> limit (min 10) (max 1) int Integer/valueOf))
(.withAttributeNames attributes))
req (if visibility (.withVisibilityTimeout req (Integer. (int visibility))) req)]
req (if wait-time-seconds (.withWaitTimeSeconds req (Integer/valueOf (int wait-time-seconds))) req)
req (if visibility (.withVisibilityTimeout req (Integer/valueOf (int visibility))) req)]
(->> (.receiveMessage client req)
.getMessages
(map (partial message-map queue-url)))))

View file

@ -59,7 +59,9 @@
; sending a msg seems to "force" the queue's existence in listings
(send client *test-queue-url* msg)
(wait-for-condition #((set (list-queues client)) *test-queue-url*)
"Created queue not visible in result of list-queues")))
"Created queue not visible in result of list-queues")
(wait-for-condition #((set (list-queues client :prefix test-queue-name-prefix)) *test-queue-url*)
"Created queue not visible in result of list-queues with prefix")))
(defsqstest test-queue-attrs
(let [{:strs [MaximumMessageSize] :as base-attrs} (queue-attrs client *test-queue-url*)
@ -119,3 +121,11 @@
(let [v (-> (receive client *test-queue-url* :visibility 5) first :body read-string)]
(is (some #(= v (-> % :body read-string)) (polling-receive client *test-queue-url* :max-wait 10000)))))
(defsqstest test-receive-long-polling
(let [q *test-queue-url*
no-poll (future (receive client q))
long-poll (future (receive client q :wait-time-seconds 20))]
(Thread/sleep 10000)
(send client q "1")
(is (== 0 (count @no-poll)) "Should not return messages")
(is (== 1 (count @long-poll)) "Should return 1 message")))