JBoss.orgCommunity Documentation
This chapter builds upon the simple Rails application we created in Chapter 1, First Steps by modifying it to take advantage of TorqueBox features.
TorqueBox ships with a Rails template that we can use to
automatically add torquebox
to the
Gemfile, convert the session store to the optional TorqueBox
clustered session storage, setup all ActiveRecord objects to
have TorqueBox::Backgroundable
methods
available, and add some TorqueBox-specific Rake tasks.
$
cd ~/torquebox_examples/rails_example
$
torquebox rails
apply /Users/someone/torquebox-2.3.0-SNAPSHOT/share/rails/template.rb gemfile torquebox (2.3.0-SNAPSHOT) remove config/initializers/session_store.rb initializer session_store.rb initializer active_record_backgroundable.rb rakefile torquebox.rake
To illustrate how TorqueBox makes it effortless to run
long-running tasks in the background, let's first add a
long-running task to our Post
model. After each Post
is created, lets
publish a message to our favorite social network linking to
that post. For simplicitly we'll just log a message and sleep
for a few seconds to simulate the publish.
Example 2.1. ~/torquebox_examples/rails_example/app/models/post.rb
class Post < ActiveRecord::Base attr_accessible :body, :title after_create :publish_to_social_network def publish_to_social_network puts "Publishing '#{title}' to our favorite social network" sleep(5) puts "Post published" end end
Start TorqueBox if it isn't already running via
torquebox run
(Windows users remember to
use echo Y | jruby -S torquebox run
),
navigate to http://localhost:8080/posts/,
create a new post, and observe the output from the TorqueBox
console.
09:11:19,746 INFO [stdout] (http-localhost/127.0.0.1:8080-1) Publishing 'Chunky Bacon Fever' to our favorite social network 09:11:24,747 INFO [stdout] (http-localhost/127.0.0.1:8080-1) Post published
As you can see, it took 5 seconds to publish the post and during that five seconds the browser was waiting on a response from the server. There's no reason the browser needs to wait until the post is published, so let's see how easy it is to convert the publish_to_social_network method to run in the background.
Example 2.2. ~/torquebox_examples/rails_example/app/models/post.rb
class Post < ActiveRecord::Base attr_accessible :body, :title after_create :publish_to_social_network always_background :publish_to_social_network def publish_to_social_network puts "Publishing '#{title}' to our favorite social network" sleep(5) puts "Post published" end end
Create a new post and you'll see that the browser returns
immediately and in the TorqueBox console the messaging runtime
will spin up (since
TorqueBox::Backgroundable
uses
messaging and the first message we send starts the messaging
runtime pool) and publish the post to our favorite social
network in the background.
TorqueBox also has built-in support for scheduled jobs (like
Cron or Windows Scheduler) but in a cross-platform way. To see
how scheduled jobs work, let's create a job that logs the
number of posts in our database every 10 seconds. To do this
create a PostCounter
class in the
app/jobs
directory created for us by the
TorqueBox Rails template earlier.
Example 2.3. ~/torquebox_examples/rails_example/app/jobs/post_counter.rb
class PostCounter def run puts "#{Post.count} posts in the database" end end
We also have to tell TorqueBox about this new job and when to
run it. To do that, edit the
config/torquebox.yml
created for us by
the TorqueBox Rails template to have the contents below.
Example 2.4. ~/torquebox_examples/rails_example/app/config/torquebox.yml
--- # This is the TorqueBox configuration file. Refer to the TorqueBox # documentation at http://torquebox.org/documentation/current/ # for all configuration options. web: context: "/" jobs: post_counter: job: PostCounter cron: "*/10 * * * * ?"
Since we had to make a change to
config/torquebox.yml
, we need to restart
TorqueBox for the job to start running. After restarting
TorqueBox you should see output like below every 10 seconds.
09:45:30,029 INFO [stdout] (JobScheduler$rails_example-knob.yml_Worker-2) 2 posts in the database
TorqueBox supports the notion of long-running services that get started when the application is deployed and stopped when the application is undeployed. This could be useful to connect a client to a streaming API service (like that provided by some social networks), monitor a resource for changes and take some action, or many other things. As an example, we'll create a service that pretends to connect to a social network and submit post ideas to a queue for later processing.
Example 2.5. ~/torquebox_examples/rails_example/app/services/post_idea_grabber.rb
class PostIdeaGrabber def initialize(options) @queue = TorqueBox::Messaging::Queue.new(options['queue_name']) end def start puts "******** Starting PostIdeaGrabber ********" Thread.new do until @done @queue.publish("Random idea #{rand(100)}") sleep 2 end end end def stop @done = true end end
Just like with our scheduled job, we need to tell TorqueBox
about this new service and the message queue it uses.
Example 2.6. ~/torquebox_examples/rails_example/app/config/torquebox.yml
--- # This is the TorqueBox configuration file. Refer to the TorqueBox # documentation at http://torquebox.org/documentation/current/ # for all configuration options. web: context: "/" jobs: post_counter: job: PostCounter cron: "*/10 * * * * ?" services: post_idea_grabber: service: PostIdeaGrabber config: queue_name: "/queue/post_ideas" queues: /queue/post_ideas: durable: false
Restart TorqueBox and you should see the service starting in
the logs.
10:43:56,316 INFO [org.torquebox.core.runtime] (MSC service thread 1-7) Created ruby runtime (ruby_version: RUBY1_8, compile_mode: JIT, app: rails_example, context: services) in 17.73s 10:43:56,325 INFO [stdout] (MSC service thread 1-5) ******** Starting PostIdeaGrabber ********
We have a long-running service placing messages on a queue but now we need something to consume those messages and do something with them. TorqueBox has a feature designed specifically for this purpose - message processors. We'll create a message processor to randomly choose some of the ideas and create new posts from them.
Example 2.7. ~/torquebox_examples/rails_example/app/processors/post_idea_processor.rb
class PostIdeaProcessor < TorqueBox::Messaging::MessageProcessor def on_message(message) if (rand(10) > 8) puts "Creating new post from idea #{message}" Post.create(:title => message, :body => "Random post created from an idea") end end end
As usual we need to edit
config/torquebox.yml
so TorqueBox knows
how to wire up this new message processor.
Example 2.8. ~/torquebox_examples/rails_example/app/config/torquebox.yml
--- # This is the TorqueBox configuration file. Refer to the TorqueBox # documentation at http://torquebox.org/documentation/current/ # for all configuration options. web: context: "/" jobs: post_counter: job: PostCounter cron: "*/10 * * * * ?" services: post_idea_grabber: service: PostIdeaGrabber config: queue_name: "/queue/post_ideas" queues: /queue/post_ideas: durable: false messaging: /queue/post_ideas: PostIdeaProcessor
Restart TorqueBox and you should see new posts being created
from the random ideas.
11:10:31,891 INFO [stdout] (Thread-2 (HornetQ-client-global-threads-9512807)) Creating new post from idea Random idea 66
Congratulations! You now have an application that uses many of the features of TorqueBox. For detailed documentation on TorqueBox, look for the User Manual in the same location you found this Getting Started Guide.