JBoss.orgCommunity Documentation
TorqueBox supports any and all Rack-based web application frameworks, including Ruby On Rails and Sinatra, among others. TorqueBox aims to be unobtrusive, requiring no unusual packaging of your app (e.g. no war files), and unless it depends on obscure native gems, no modifications whatsoever.
So why deploy your Ruby web app on TorqueBox? Because you get cool enterprisey features that every non-trivial app will need eventually if it's successful at all. Let's go over a few.
TorqueBox runs on JRuby, one of the fastest Ruby interpreters available. Because JRuby runs on the Java Virtual Machine, your app runs on real OS threads, so if your app supports multi-threaded invocations, you will make the most of your hardware resources.
Of course, running on the JVM has a drawback: "native" gems that rely upon machine-specific compiled code do not function with JRuby and TorqueBox. You must replace these gems with pure-Ruby or pure-Java implementations. Some native gems using FFI are usable within TorqueBox. Fortunately, gems that won't run on JRuby are becoming more and more rare.
Most successful web apps evolve to the point that passively responding to HTTP requests is not enough. Before you know it, you may need background processes, scheduled jobs, messaging, and active daemons all in support of your web app.
With TorqueBox these things are an integral part of your app and as
such, they share its life cycle. When your application is deployed under
TorqueBox, so are your scheduled jobs, background tasks, services, etc.
It's simply a matter of editing a single
torquebox.yml configuration file within your app.
This will make your operations staff very happy!
For more details, please see Chapter 4, TorqueBox Application Deployment.
Clustering nodes is trivially easy (replace 1.2.3.4 with a real IP address):
$$JBOSS_HOME/bin/standalone.sh --server-config=standalone-ha.xml -b 1.2.3.4
Or, if using the torquebox-server gem:
$torquebox run --clustered -b 1.2.3.4
And when those nodes are behind the JBoss mod_cluster Apache module, you get automatic, dynamic configuration of workers, server-side load factor calculation, and fine-grained application lifecycle control.
But even without mod_cluster, TorqueBox clustering provides automatic web session replication and distributed caching, not to mention automatic load-balancing of message delivery, enabling smart distribution of any background processes spawned by your web app.
For more details, please see Chapter 21, TorqueBox Production Setup.
Ruby web apps are often deployed individually, without respect to hostnames or context-path. Running under TorqueBox, however, you may host several apps under a single host, or multiple apps under different hostnames.
In a YAML configuration, the web settings grouped under the
web key. For the DSL, they are grouped within the
web block.
Table 6.1. web
| YAML Key/DSL Method | Description | Default |
|---|---|---|
rackup | The "rackup" script containing the complete logic for initializing your application. | config.ru |
host | Virtual hosts allow one application to respond to www.host-one.com, while another running within the same JBoss AS to respond to www.host-two.com. This value can be either a single hostname or a YAML list of hostnames. | localhost |
context | Applications within a single TorqueBox Server may be separated purely by a context path. For a given host, the context path is the prefix used to access the application, e.g. http://some.host.com/context. Traditional Ruby web apps respond from the top of a site, i.e. the root context. By using a context path, you can mount applications at a location beneath the root. | / |
static | Any static web content provided by your app should reside beneath this directory. | none unless deploying a Rails
application, then public. |
session-timeout | Time (defaults to minutes) for idle sessions to timeout.
Specified as an integer followed by a units
designation
| 30m, specifying 30 minutes. |
For example, in YAML:
web: rackup: alternative/path/to/my_config.ru context: /app-one static: public host: www.host-one.com
And via the DSL:
TorqueBox.configure do
web do
rackup "alternative/path/to/my_config.ru"
context "/app-one"
static "public"
host "www.host-one.com"
end
endBy using the TorqueBox application-server-based session store, your application gets the benefits of clusterable sessions without having to setup and maintain a database. When clustered, session state is automatically replicated throughout an Infinispan data grid.
Additionally, by using the TorqueBox session store, your application can communicate between both the Java and Ruby sides through the HTTP session. Where possible, elemental scalar attributes of the Ruby session are synchronized to similar attributes in the Java session, and vice-versa.
For complex objects, they are retained in a Ruby hash, and serialized as a blob into a single attribute of the Java session.
When copying between the Ruby and Java sessions, attributes will be retained under symbol keys in the ruby session, and string keys in the Java session. The supported scalar types are numerics, strings, booleans and nil.
How you enable the TorqueBox session store varies based on the web framework used. For Rack applications, just add use TorqueBox::Session::ServletStore to your config.ru. For specific examples in Rails and Sinatra applications, see Section 6.8.4, “Rails Sessions Configuration” and Section 6.9.1, “Sinatra Sessions Configuration”.
The session timeout can be configured in your TorqueBox
deployment descriptor(s). The general format for the session
timeout value is numeric with an optional unit of measure, where
ms = milliseconds, s =
seconds, m = minutes and h =
hours. If no unit of measure is provided, minutes will be assumed.
Ex: session-timeout: 10 h will set the session
timeout to 10 hours.
Example 6.1. Example deployment descriptor
Configuring session timeout:
... web: host: foobar.com context: /tacos session-timeout: 10
TorqueBox provides an implementation of the Rails 3.x
ActiveSupport::Cache::Store that exposes your
application to the sexy Infinispan data grid. Additionally,
TorqueBox provides similar functionality for Sinatra sessions. See
specific configuration options in the Ruby Web Frameworks sections below.
To learn more about ActiveSupport::Cache::Store, the
Infinispan cache, and the many other ways it is used by TorqueBox and can
be used by you, please see Chapter 7, TorqueBox Caching.
Rack is a specification which describes how web server engines can integrate with additional logic written in Ruby. Rack is a akin to CGI or the Java Servlets Spec in terms of goals and functionality.
TorqueBox currently supports general
config.ru-based applications. In your
application's directory, your Rack application can be booted
from a file named config.ru that you
provide. The Ruby runtime provided to your application is quite
rudimentary. If you desire to use RubyGems or other libraries,
it is up to you to require the necessary files (for instance,
require 'rubygems').
app = lambda {|env| [200, { 'Content-Type' => 'text/html' }, 'Hello World'] }
run appThe directory containing the
config.ru is considered the current working
directory, and is included in the load path.
TorqueBox aims to provide complete Ruby Rack
compatibility. Please refer to the Rack specification at http://rack.rubyforge.org/doc/SPEC.html
for more information.
Applications implemented by the user must simply provide
an object implementing a single-argument method in the form of
.call(env)
Table 6.2. Rack environment
| Variable | Description |
|---|---|
REQUEST_METHOD | The HTTP request method, such as
“GET” or “POST”.
This cannot ever be an empty string, and so is always
required. |
SCRIPT_NAME | The initial portion of the request URL’s “path” that corresponds to the application object, so that the application knows its virtual “location”. This may be an empty string, if the application corresponds to the “root” of the server. |
PATH_INFO | The remainder of the request URL’s “path”, designating the virtual “location” of the request’s target within the application. This may be an empty string, if the request URL targets the application root and does not have a trailing slash. This value may be percent-encoded when I originating from a URL. |
QUERY_STRING | The portion of the request URL that follows the
?, if any. |
SERVER_NAME | |
SERVER_PORT | |
HTTP_ variables | Variables corresponding to the client-supplied HTTP request headers (i.e., variables whose names begin with HTTP_). The presence or absence of these variables should correspond with the presence or absence of the appropriate HTTP header in the request. |
rack.version | The Array [m, n], representing this version of Rack. |
rack.url_scheme | http or
https, depending on the request
URL. |
rack.input | Input stream |
rack.errors | Error output stream |
rack.multithread | Always true |
rack.multiprocess | Always true |
rack.run_once | Always false |
rack.session | |
rack.logger | Not implemented |
java.servlet_request | The underlying Java
HTTPServletRequest |
Ruby-on-Rails (also referred to as "RoR" or "Rails") is one of the most popular Model-View-Controller (MVC) frameworks for the Ruby language. It was originally created by David Heinemeier Hansson at 37signals during the course of building many actual Ruby applications for their consulting business.
Rails has straight-forward components representing models, views, and controllers. The framework as a whole values convention over configuration. It has been described as "opinionated software" in that many decisions have been taken away from the end-user.
It is exactly the opinionated nature of Rails that allows it to be considered a simple and agile framework for quickly building web-based applications. Additionally, since Ruby is an interpreted language instead of compiled, the assets of an application can be edited quickly, with the results being immediately available. In most cases, the application does not need to be restarted to see changes in models, views or controllers reflected.
TorqueBox supports both the 2.3.x and 3.x codelines of Rails. By default, all utilities prefer the latest version of a given gem.
While TorqueBox is 100% compatible with Ruby-on-Rails, there are a few steps that must be taken to ensure success. The biggest issues to contend with involve database access and native gems. The distribution includes a Rails application template to make the creation or adaptation of a codebase to TorqueBox easier.
Previous releases of TorqueBox bundled Rails but it is no longer included. You'll need to install the version needed by your application.
$geminstall rails --version=[rails version]
TorqueBox ships with a command line application which you can use to setup a new Rails application or modify an existing one to work with TorqueBox. The same command works for both scenarios. If the application directory exists, it will apply the TorqueBox rails template to that application. If it does not exist, a new Rails application will be created.
$torqueboxrails/path/to/myapp
If you have multiple versions of Rails installed, you can generate applications for a specific version by using bundler. For example, you have Rails 2.3.14 and 3.2.2 installed. By default, Rails will use version 3.2.2 when creating a new application. To create a new Rails 2.3.14 application using the TorqueBox template, just create a Gemfile that specifies the Rails version.
gem 'rails', 2.3.14' gem 'torquebox', '2.x.incremental.1020'
To generate the Rails app, first run bundler.
$bundleinstall
Then, when you generate the application, use bundler. It will use the Rails version you specified in your Gemfile.
$bundleexec torquebox rails [myapp]
ActiveRecord applications deployed on TorqueBox benefit from
using the Java-based JDBC database drivers. These drivers are
provided as a handful of gems which you may include into your
application through config/environment.rb or
a Gemfile. For more information on database
connectivity within the TorqueBox environment, please see Chapter 14, Database Connectivity in TorqueBox.
When using the TorqueBox Rails application template described above, these modifications are made for you.
You simply must reference the
activerecord-jdbc-adapter from your
environment.rb within the
Rails::Initializer.run block.
Rails::Initializer.run do |config|
config.gem "activerecord-jdbc-adapter",
:require=>'jdbc_adapter'
endAll databases will require inclusion of the
activerecord-jdbc-adapter. No other gems need
to be required or loaded, since ActiveRecord will perform further
discovery on its own.
Rails 3 uses bundler to manage the dependencies of
your application. To specify the requirement of the
activerecord-jdbc-adapter with Rails 3,
simple add it to your Gemfile.
Additionally, any specific JDBC driver your application will
require should be indicated. Applications created with Rails
3.1 and later should already include the necessary JDBC
gems.
gem 'activerecord-jdbc-adapter' gem 'jdbc-sqlite3'
By default, both Rails 2 and Rails 3 use the simple
cookie-based session store, which requires no support from the
server. TorqueBox can leverage the cluster-compatible sessions
provided by the application server to keep session state on the
server. The TorqueBox session store requires no specific
configuration of a database or other technology. To use the
TorqueBox session store, you must adjust
config/initializers/session_store.rb. The
contents vary depending on the version of Rails your application
uses.
In both cases, your application should require the
torquebox gem, which provides the
implementation.
When using the TorqueBox Rails application template described above, these modifications are made for you.
In
config/initializers/session_store.rb
ActionController::Base.session_store = :torquebox_store
In
config/initializers/session_store.rb
(adjust for your application's name)
MyApp::Application.config.session_store :torquebox_storeYou configure the TorqueBox cache store the same way you would
any other Rails cache store, but we recommend setting it in
config/application.rb because it will adapt to
whichever environment it finds itself. Regardless of its
configuration, it will always fallback to local
mode when run in a non-clustered, even non-TorqueBox,
environment.
In whatever context you use the cache store, you must include
the torquebox gem, which provides the
implementation.
module YourApp
class Application < Rails::Application
config.cache_store = :torque_box_store
end
endUsing this symbolized form causes Rails to load the appropriate
Ruby file for you. Alternatively, you may load the file yourself and
then refer to the fully-qualified class name,
ActiveSupport::Cache::TorqueBoxStore.
By default, the TorqueBoxStore will be in
asynchronous invalidation mode when
clustered and local mode when not. But you
can certainly override the defaults:
config.cache_store = :torque_box_store, {:mode => :distributed, :sync => true}You can even create multiple cache stores in your app, each
potentially in a different clustering mode. You should use the
:name option to identify any additional caches you
create, e.g.
COUNTERS = ActiveSupport::Cache::TorqueBoxStore.new(:name => 'counters',
:mode => :replicated,
:sync => true)By default, Rails logs where you would expect, but it's possible to tap into the JBoss log system for more sophisticated logging. For more information, see Section 3.4.1, “TorqueBox::Logger”.
Sinatra is a very simple DSL for creating web applications. And all the TorqueBox features available to Rails apps, e.g. clustering, session replication, and caching, will work for Sinatra app just as well.
Because the TorqueBox session store is Rack compliant, you configure it the same way you would any other session store in Sinatra.
require 'sinatra''
require 'torquebox'
class SinatraSessions < Sinatra::Base
use TorqueBox::Session::ServletStore
get '/foo' do
session[:message] = 'Hello World!'
redirect '/bar'
end
get '/bar' do
session[:message] # => 'Hello World!'
end
endBecause the TorqueBox cache store is derived from
ActiveSupport::Cache::Store, you must include
activesupport-3.x in your Sinatra app.
In whatever context you use the cache store, you must include the torquebox RubyGem, which provides the implementation.
require 'active_support/cache/torque_box_store' class SinatraCache < Sinatra::Base set :cache, ActiveSupport::Cache::TorqueBoxStore.new end
By default, the TorqueBoxStore will be in
asynchronous invalidation mode when
clustered and local mode when not. But you
can certainly override the defaults:
set :cache, ActiveSupport::Cache::TorqueBoxStore.new(:mode => :distributed, :sync => true)
You can even create multiple cache stores in your app, each
potentially in a different clustering mode. You should use the
:name option to identify any additional caches you
create, e.g.
COUNTERS = ActiveSupport::Cache::TorqueBoxStore.new(:name => 'counters',
:mode => :replicated,
:sync => true)By default, Sinatra log support is minimal, sending most errors to stdout or stderr. For more sophisticated logging, see Section 3.4.1, “TorqueBox::Logger”.