A web application that does a “pretend email sending” in the background. The background process then pings back to the client when the action is done (essentially a sleep for some seconds).
Uses resque, redis, faye to accomplish this.
-
Install redis
-
Do a bundle install to install gems resque, faye. Do a db set up (just creates a users table)
bundle install rake db:migrate
-
Run the rake job to start listening to workers (resque side) - these workers listen to requests coming from the rails web app via user browser requests.
RAILS_ENV=development rake resque:work QUEUE='*'
-
Start the faye server
rackup faye.ru -s thin -E development
-
Start the web server
rails s
-
For checking the resque job queue - go to
http://localhost:3000/resque/queues
-
Create a new user by going to localhost:3000/users and clicking on New User link. To submit an email job for the user with user id 1
Go to http://localhost:3000/users/1/ and click on the Email link You should get an alert from the server side in a few seconds. That is it - you have exercised the power of faye and redis to submit a job and get a message back from the server to the client asynchronously`.
When you click on the email link, following events happen:
. In the email action of users controller, we submit a job to Emailer worker . The worker (app/workers/emailer.rb) picks the job in which it sleeps for a few seconds and then sends the “email sent” message to the faye server on the channel “/messages/1”. In this example, the channel id is simply the user id but in real application, it would also have a random guid component so that we do not confuse between different messages and all. . On the client, we are already listening on this channel - so we get the message and give an alert - following is the logic in layout/application.html.erb that does this
<script>
$(function() { var faye = new Faye.Client('http://localhost:9292/faye'); var subscription = faye.subscribe("/messages/1", function(data) { alert(data); }); });
</script>
-
As mentioned, in real application, you would create a separate channel (includes a random guid) for each job - so the clients do not interfere with each other. You would also make the worker more light weight by not loading the entire rails environment for each worker task.