JBoss.orgCommunity Documentation

Chapter 6. TorqueBox Web Applications

6.1. Performance
6.2. Deployment
6.3. Clustering
6.4. Configuration
6.5. Sessions
6.6. Caching
6.7. Rack
6.7.1. Rack Applications
6.7.2. Rack API
6.7.3. Sendfile support
6.8. Ruby on Rails
6.8.1. Ruby on Rails™ Applications
6.8.2. Rails 2.3.x versus 3.x
6.8.3. Preparing your Rails application
6.8.4. Rails Sessions Configuration
6.8.5. Rails Caching Configuration
6.8.6. Logging
6.9. Sinatra
6.9.1. Sinatra Sessions Configuration
6.9.2. Sinatra Caching Configuration
6.9.3. Logging

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 Tips.

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.


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
end

By 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.

TorqueBox Session Store and Sticky Sessions

It is only recommended to use the TorqueBox session store with a load balancer configured to use sticky sessions. If you want to use round-robin or some other non-sticky load-balancing policy, you may may experience delays as servers wait for the user's session to replicate from other nodes in the cluster. Under high session loads, these delays may turn into timeouts.

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.

Configuring session timeout, in YAML:

...
  
web:
  host: foobar.com
  context: /tacos
  session_timeout: 10 m

And via the DSL:

TorqueBox.configure do
  web do
    host "foobar.com"
    context "/tacos"
    session_timeout "10 m"
  end
end

TorqueBox provides an implementation of the Rails 3.x ActiveSupport::Cache::Store that exposes your application to the 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 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.

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).


With TorqueBox it is possible to delegate the delivery of the response content from a file to the application server itself, without the need to read the file in the application. This is very useful for static files. The X-Sendfile header is designed for this usage. You can read more about Rack Sendfile. Additionally the TorqueBox implementation allows to use byte-ranges to fetch only part of the file by using the Range header.

Sendfile support is available in TorqueBox for all Rack-based applications (including Sinatra and Ruby on Rails frameworks).

It is still possible to use a proxy in front of TorqueBox that handles the X-Sendfile header instead of the application server. TorqueBox will not handle the file if a special X-Sendfile-Type header is set.

By default the sendfile support is disabled in TorqueBox since it requires native connectors in the JBoss AS web subsystem. To enable the sendfile support in TorqueBox you need to modify the $JBOSS_HOME/standalone/configuration/standalone.xml file and change the native attribute to true in the web subsystem, like this:

<subsystem xmlns="urn:jboss:domain:web:1.4" default-virtual-server="default-host" native="true">
  ...
</subsystem>

This will automatically make the sendfile support available.

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.

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.

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.

Rails 2.x

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'

end

All 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.x

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'

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.