README.md in pwwka-0.3.2 vs README.md in pwwka-0.4.0
- old
+ new
@@ -1,11 +1,11 @@
# Pwwka
Pronounced "Poo-ka" |ˈpo͞okə|
-![Pwwka Bunny Bus](http://res.cloudinary.com/stitch-fix/image/upload/c_scale,w_317/v1408570794/bunny-bus_ba72ou.png)
+![Pwwka Legit](http://res.cloudinary.com/stitch-fix/image/upload/c_scale,h_300/v1413580920/pwwka_yuw7hl.png)
---
This gem connects to a topic exchange on a RabbitMQ server. It gives any app using it the ability to do two things:
@@ -19,15 +19,15 @@
> The transmitter should send messages to inform anyone who listens that an event has occurred. It's up to the receiver to interpret the message.
As an example:
-* public_app sends a message that a new client has signed up
-* admin_app receives that message and updates its client index
-* email_app receives that message and sends a welcome email to the client
+* public-app sends a message that a new client has signed up
+* admin-app receives that message and updates its client index
+* email-app receives that message and sends a welcome email to the client
-### Persistence
+## Persistence
All transmitters and receivers share the same exchange. This means that all receivers can read all messages that any transmitter sends. To ensure that all messages are received by eveyone who wants them the Pwwka message bus is configured as follows:
* The exchange is named and durable. If the service goes down and restarts the named exchange will return with the same settings so everyone can reconnect.
* The receiver queues are all named and durable. If the service goes down and restarts the named queue will return with the same settings so everyone can reconnect, and with any unacknowledged messages waiting to be received.
@@ -113,11 +113,11 @@
Pwwka::Transmitter.send_message!(payload, routing_key, delayed: true, delay_by: 3000)
```
`delay_by` is an integer of milliseconds to delay the message. The default (if no value is set) is 5000 (5 seconds).
-These extra arguments work for all message sending methods - the safe ones, the handling, and the message_queuer methods (see below).
+These extra arguments work for all message sending methods - the safe ones, the handling, and the `message_queuer` methods (see below).
### Message Queuer
You can queue up messages and send them in a batch. This is most useful when multiple messages need to sent from within a transaction block.
For example:
@@ -156,12 +156,12 @@
### Queues - what messages will your queue receive
It depends on your `routing_key`. If you set your routing key to `#.#` (the default) it will receive all the messages. The `#` is a wildcard so if you set it to `client.#` it will receive any message with `client.` at the beginning. The exchange registers the queue's name and routing key so it knows what messages the queue is supposed to receive. A named queue will receive each message it expects to get once and only once.
-The available wildcards are as follows
-* `*` (star) can substitute for exactly one word.
+The available wildcards are as follows (and are not intuitive):
+* `*` (star) can substitute for **exactly one word**.
* `#` (hash) can substitute for zero or more words.
__A note on re-queuing:__ At the moment messages that raise an error on receipt are marked 'not acknowledged, don't resend', and the failure message is logged. All unacknowledged messages will be resent when the worker is restarted. The next iteration of this gem will allow for a specified number of resends without requiring a restart.
__Spinning up some more handlers to handle the load:__ Since each named queue will receive each message only once you can spin up multiple process using the *same named queue* and they will share the messages between them. If you spin up three processes each will receive roughly one third of the messages, but each message will still only be received once.
@@ -195,9 +195,54 @@
###
end
end
```
+
+#### Handling Messages with Resque
+
+If you use [Resque][resque], and you wish to handle messages in a resque job, you can use `Pwwka::QueueResqueJobHandler`, which is an adapter between the
+standard `handle!` method provided by pwwka and your Resque job.
+
+1. First, modify your `Gemfile` or otherwise arrange to include `pwwka/queue_resque_job_handler`:
+
+ ```ruby
+ gem 'pwwka', require: [ 'pwwka', 'pwwka/queue_resque_job_handler' ]
+ ```
+
+ or, in `config/initializers/pwwka.rb`:
+
+ ```ruby
+ require 'pwwka/queue_resque_job_handler'
+ ```
+
+2. Now, configure your handler. For a `Procfile` setup:
+
+ ```
+ my_handler: rake message_handler:receive HANDLER_KLASS=Pwwka::QueueResqueJobHandler JOB_KLASS=MyResqueJob QUEUE_NAME=my_queue ROUTING_KEY="my.key.completed"
+ ```
+
+ Note the use of the environment variable `JOB_KLASS`. This tells `QueueResqueJobHandler` which class to queue.
+3. Now, write your job.
+
+ ```ruby
+ class MyResqueJob
+ @queue = :my_resque_queue
+
+ def self.process(args) # i.e. payload
+ user = User.find(args.fetch("user_id")) # or whatever
+ user.frobnosticate!
+ end
+ end
+ ```
+
+ Note that you must provide `@queue` in your job. `QueueResqueJobHandler` doesn't support setting a custom queue and enqueue-time (PRs welcome :).
+ Note further that your job class is not given the routing key, so you'll have to set `ROUTING_KEY` appropriately for whatever it is you're trying to
+ do.
+3. Profit!
+
+[resque]: https://github.com/resque/resque/tree/1-x-stable
+
## Monitoring
RabbitMQ has a good API that should make it easy to set up some simple monitoring. In the meantime there is logging and manual monitoring.