<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="messaging">
  <title>TorqueBox Messaging</title>

  <section id="messaging-intro">
    <title>Introduction</title>

    <formalpara>
      <title>HornetQ</title>

      <para>TorqueBox integrates the JBoss HornetQ message broker technology.
      It is automatically available to you, with no additional configuration
      required to start the messaging service. HornetQ supports clustered
      messaging, to allow for load-balancing, failover, and other advanced
      deployments.</para>
    </formalpara>

    <para>The term "messaging" encompasses a large area of functionality.
    Messaging solutions are used to achieve loosely-coupled, asynchronous
    systems. The primary actors in a messaging-based system are messages,
    destinations, consumers, and producers. From an implementation
    perspective, a broker mediates the relationships between the other
    actors.</para>

    <mediaobject>
      <imageobject role="html">
        <imagedata align="center" contentwidth="4in"
                   fileref="images/messaging-overview.png" format="PNG" />
      </imageobject>

      <imageobject role="fo">
        <imagedata align="center" contentwidth="4in"
                   fileref="images/messaging-overview.svg" format="SVG" />
      </imageobject>
    </mediaobject>

    <formalpara>
      <title>Messages</title>

      <para>The unit of communication within a messaging system is a message.
      A message may either be simply a blob of octets, or it might have some
      higher-order, application-defined semantics. All messages include a set
      of headers, similar to email.</para>
    </formalpara>

    <formalpara>
      <title>Destinations</title>

      <para>A destination represents a rendezvous where messages are
      exchanged. A message may be sent to a destination by one actor, and
      received from the destination by another.</para>
    </formalpara>

    <para>There are two main types of destinations:
    <emphasis>queues</emphasis> and <emphasis>topics</emphasis>. All
    destinations allow multiple actors to place messages with them. The type
    of destination affects what happens to the message once given to the
    destination. A queue delivers the message to a single recipient (possibly
    one of many candidate recipients). A topic delivers the message to
    multiple interested recipients.</para>

    <para>In the image below, the green lines represent the flow of a single
    message from a producer to one-or-more consumers through a topic and a
    queue.</para>

    <mediaobject>
      <imageobject role="html">
        <imagedata align="center" contentwidth="4in"
                   fileref="images/messaging-queues-vs-topics.png"
                   format="PNG" />
      </imageobject>

      <imageobject role="fo">
        <imagedata align="center" contentwidth="4in"
                   fileref="images/messaging-queues-vs-topics.svg"
                   format="SVG" />
      </imageobject>
    </mediaobject>

    <formalpara>
      <title>Producers</title>

      <para>Any component or client code that creates messages and gives them
      to the message broker for delivery is considered a
      <glossterm>producer</glossterm>. Generally speaking, the producer does
      not know the details of the destination.</para>
    </formalpara>

    <formalpara>
      <title>Consumers</title>

      <para>Any component that waits for messages to be delivered to it by the
      message broker is consider a <glossterm>consumer</glossterm>. A consumer
      is unaware of the producer and any other consumers, potentially.</para>
    </formalpara>
  </section>

  <section id="deploying-destinations">
    <title>Deploying Destinations</title>

    <para>Queues and topics (collectively known as destinations) may
    be deployed with your application, or separate from your
    application. Various parts of your application may also implicitly
    deploy and use some destinations.</para>

    <para>Each method has advantages and disadvantages involving the
    expectations of your application and its interaction with resources
    outside the scope of the application.</para>

    <section id="destination-deployment-styles">
      <title>Deployment Styles</title>

      <section id="destination-deployment-with-app">
        <title>Deploying destinations with your application</title>

        <para>The recommended style is to deploy your queues and
        topics with your application. This aligns their lifecycle to
        the deployment cycle of your application. When the app is
        deployed, its message destinations will be started, if
        necessary. And when the app is undeployed, its message
        destinations will be stopped as well, unless they're currently
        in use by another application. This is by design: messaging
        destinations are an excellent means of inter-application
        coordination, so destinations are only stopped when there are
        no other applications consuming messages from them.</para>
      </section>

      <section id="destination-deployment-apart-from-app">
        <title>Deploying destinations apart from your application</title>

        <para>If you deploy destinations separate and apart from your
        application, they become long-lived first-class component citizens in
        your environment. Applications may be deployed and undeployed, while
        the destinations continue to function, accepting and processing
        messages to the best of their ability.</para>

        <para>If the consumers to a destination are offline, the destination
        may persist and store any unhandled messages until a consumer
        re-attaches.</para>

        <para>The downside is that by making destinations first-class
        top-level components of your environment, you must also manage, deploy
        and undeploy them separate from any app, creating additional
        work.</para>
      </section>

      <section id="destination-deployment-runtime">
        <title>Deploying destinations at runtime</title>

        <para>You can also choose to deploy messaging destinations at runtime:</para>

        <para><example>
          <title>Deploying queues and topics at runtime</title>
        
          <para><programlisting>TorqueBox::Messaging::Queue.start '/queues/foo'
TorqueBox::Messaging::Topic.start '/topics/bar'</programlisting>
          </para></example>
        </para>
      </section>
    </section>
  
    <section id="messaging-deployment-descriptors">
      <title>Deployment Descriptors</title>

      <para>You have several options when deploying queues and topics, based
      on the lifecycle that suits your systems best.</para>

      <section id="application-linked-destinations">
        <title>Application-linked queues and topics</title>

        <para>
          Destinations deployed with your application are configured
          in your application's <link
          linkend="deployment-descriptors">deployment
          descriptor</link>, either its internal one or its external
          "knob" file.
        </para>

        <para>Within either of these files, you may use a
        <parameter>queues:</parameter> section to define queues and a
        <parameter>topics:</parameter> section to define topics.</para>

        <para><example>
            <title>Defining topics and queues in a deployment
            descriptor</title>

            <para>Using the YAML syntax:<programlisting>application:
  ..
queues:
  /queues/my_app_queue:

topics:
  /queues/my_app_topic:</programlisting></para>

            <para>And via the DSL:<programlisting>TorqueBox.configure do
  ...
  queue '/queues/my_app_queue'
  topic '/queues/my_app_topic'
end</programlisting></para>
          </example></para>
      </section>

      <section id="long-lived-destinations">
        <title><filename>Long-lived queues and topics</filename></title>

        <para>If your queues and topics have a lifecycle that extends
        beyond the deployment of your applications, you may want
        long-lived destinations, which are first-order components, and
        may be deployed on their own. In this way, many applications
        can come and go over time, publishing and consuming from the
        same queues.</para>

        <para>When using long-lived destinations,
        <filename><replaceable>*</replaceable>-knob.yml</filename>
        deployment descriptors are placed directly into the
        <filename>deployments/</filename> directory of TorqueBox
        AS. Note that a corresponding
        <filename><replaceable>*</replaceable>-knob.yml.dodeploy</filename>
        file is also required in this <filename>deployments/</filename> 
        directory. Simply touch/create a blank file here as part of your 
        deployment.</para>

        <formalpara>
          <title>Queues</title>

          <para>To deploy queues, a simple YAML file is required to name the
          queues and provide additional configuration parameters. The file
          should have the suffix of <filename>-knob.yml</filename>, such as
          <filename><replaceable>these-queues</replaceable>-knob.yml</filename>
          or
          <filename><replaceable>those-queues</replaceable>-knob.yml</filename>.
          The only configuration option available on queues is the
          <parameter>durable</parameter> option.</para>
        </formalpara>

        <para>Durability is enabled by default, and involves writing each
        message to disk so as to be able to recover in the event of failure or
        server restart. Disabling durability on queues may result in better
        performance, but increases the risk of losing messages.</para>

        <para><example>
            <title>queues-knob.yml</title>

            <para><programlisting>queues:
  /queues/my_queue:

  /queues/my_other_queue:
    durable: false</programlisting> The name of the queue will be used when
            registering the queue in the naming-service, and is used to
            discover the queue for attaching consumers and producers.</para>

            <para>By convention, queues are named with the prefix of
            <filename>/queues</filename>.</para>
          </example></para>

        <formalpara>
          <title>Topics</title>

          <para>To deploy topics, a simple YAML file is required to name the
          topics and provide additional configuration parameters. The file
          should have the suffix of <filename>-knob.yml</filename>, such as
          <filename><replaceable>these-topics</replaceable>-knob.yml</filename>
          or
          <filename><replaceable>those-topics</replaceable>-knob.yml</filename>.
          Currently, no additional configuration parameters are allowed -
          topic durability is controlled via options on the attached
          processors (See <xref
          linkend="connecting-consumers-to-destinations" />).</para>
        </formalpara>

        <para><example>
            <title>topics-knob.yml</title>

            <para><programlisting>topics:
  /topics/my_topic:

  /topics/my_other_topic:</programlisting> The name of the topic will be used
            when registering the topic in the naming-service, and is used to
            discover the topic for attaching consumers and producers.</para>

            <para>By convention, topics are named with the prefix of
            <filename>/topics</filename>.</para>
          </example></para>
      </section>

    </section>
  </section>

  <section id="messaging-ruby-classes">
    <title>TorqueBox Ruby Classes</title>

    <para>All classes in the <classname>TorqueBox::Messaging</classname>
    module reside in the Ruby gem, <filename>torquebox-messaging</filename>,
    so to use them in your Rails app, you'll need to configure your app to
    load the gem.</para>

    <formalpara>
      <title>Rails 2.x</title>

      <para>Add this to your
      <filename>config/environment.rb</filename>:</para>
    </formalpara>

    <example>
      <title>To use <classname>TorqueBox::Messaging</classname> in a Rails 2.x
      app</title>

      <para><programlisting>Rails::Initializer.run do |config|
  ...
  config.gem 'torquebox-messaging'
  ...</programlisting></para>
    </example>

    <formalpara>
      <title>Rails 3.x</title>

      <para>Add this to your <filename>Gemfile</filename>:</para>
    </formalpara>

    <example>
      <title>To use <classname>TorqueBox::Messaging</classname> in a Rails 3.x
      app</title>

      <para><programlisting>source 'http://rubygems.org'

gem 'rails', '3.0.4'
...
gem 'torquebox-messaging'</programlisting></para>
    </example>

    <para>And to use them in any other JRuby script, it's even simpler. First,
    ensure that <filename>rubygems</filename> is loaded, then require the
    <filename>torquebox-messaging</filename> feature.</para>

    <example>
      <title>To use <classname>TorqueBox::Messaging</classname> in a shell
      script</title>

      <para><programlisting>#!/usr/bin/env jruby

require 'rubygems'
require 'torquebox-messaging'
        </programlisting></para>
    </example>
  </section>

  <section id="messaging-abstractions">
    <title>Messaging Abstractions</title>

    <section id="messaging-queues-and-topics">
      <title>Queues and Topics</title>

      <para>There are two main messaging destination abstractions:
      <classname>TorqueBox::Messaging::Queue</classname> and
      <classname>TorqueBox::Messaging::Topic</classname>. Each has a
      <methodname>publish</methodname> and a <methodname>receive</methodname>
      method, and each must be constructed with a <parameter>name</parameter>
      and an optional hash of options:</para>

      <table>
        <title>Message destination options</title>

        <tgroup cols="3">
          <colspec align="left" />

          <thead>
            <row>
              <entry>Option</entry>

              <entry>Default</entry>

              <entry>Description</entry>
            </row>
          </thead>

          <tbody>
            <row>
              <entry><parameter>:host</parameter></entry>

              <entry>localhost</entry>

              <entry>Should be the hostname or ip address of the
              HornetQ server containing the destinations.</entry>
            </row>

            <row>
              <entry><parameter>:port</parameter></entry>

              <entry>5445</entry>

              <entry>The port of the HornetQ server.</entry>
            </row>

            <row>
              <entry><parameter>:username</parameter></entry>

              <entry>nil</entry>

              <entry>The username to use when connecting to the HornetQ server.</entry>
            </row>

            <row>
              <entry><parameter>:password</parameter></entry>

              <entry>nil</entry>

              <entry>The password to use when connecting to the HornetQ server.</entry>
            </row>

            <row>
              <entry><parameter>:client_id</parameter></entry>

              <entry></entry>

              <entry>A string to uniquely indentify the connecting client.
              Optional unless you are using the <varname>:durable</varname>
              option with <methodname>receive</methodname> on a
              <classname>Topic</classname>.</entry>
            </row>
          </tbody>
        </tgroup>
      </table>

      <para>You can also set these options via the
      <methodname>connect_options</methodname> on the destination
      object.</para>

      <para>Though sometimes convenient, these methods are fairly low-level
      and higher-level abstractions such as <link
      linkend="messaging-consumers">Message Processors</link>, and <link
      linkend="backgroundable">Backgroundable</link> are often better-suited
      to the task.</para>
    </section>

      <section id="messaging-producers">
        <title>Publishing Messages</title>

        <para>It's trivial to publish a message to a JMS
        <classname>Queue</classname> or <classname>Topic</classname> with
        TorqueBox. And if all of your message consumers are Ruby clients, the
        contents of the messages can be any serializable Ruby or Java object.
        You just need to ensure that the type of content you produce resides
        in the runtime environments of both the producer and the
        consumer.</para>

        <para>To send a message, you will need access to a
        <classname>Topic</classname> or <classname>Queue</classname> instance.
        The preferred method for accessing the destination instance is to use
        <methodname>fetch(...)</methodname> (see <xref
        linkend="injectable-destinations" /> for more details). If you need to
        pass options to the instance, or only have access to the destination
        name at runtime, construct either a <classname>Topic</classname> or a
        <classname>Queue</classname> instance with its name and options. Once
        you have a destination instance, simply call its publish method. The
        API's of both Topics and Queues are identical; they each simply
        represent a destination for your messages.</para>

        <para>By default, messages are encoded using Ruby's Marshal
        serialization mechanism, allowing you to include Ruby objects in your
        message. If you need to produce messages that will be consumed by
        non-Ruby or TorqueBox 1.x clients, you can override the encoding
        mechanism globally or on a per <methodname>publish</methodname> basis.
        See <xref linkend="message-encodings" /> for more information.</para>

        <example>
          <title>Publish text messages</title>

          <para><programlisting>queue = fetch('/queues/foo')
queue.publish "A text message"

topic = fetch('/topics/foo')
topic.publish "A text message"
          </programlisting></para>
        </example>

        <example>
          <title>Publish a Ruby Hash</title>

          <para><programlisting>queue = fetch('/queues/foo')
queue.publish {:key =&gt; 'value', :list =&gt; %w{one two three}}
          </programlisting></para>

          <para>This is enormously convenient, as any serializable object is
          permitted, but it only makes sense if your queue consumers are also
          written in Ruby.</para>
        </example>

        <example>
          <title>Send message using a remote HornetQ server</title>

          <para><programlisting>queue = TorqueBox::Messaging::Queue.new('/queues/foo', 
                                        :host =&gt; 'hornetq_server.mydomain.com',
                                        :port =&gt; 5445)
queue.publish "Some message"</programlisting></para>
        </example>

        <para>The <methodname>publish</methodname> method takes an optional
        second argument containing a hash of options:</para>

        <table id="messaging-producers-options">
          <title>Publish options</title>

          <tgroup cols="3">
            <colspec align="left" />

            <thead>
              <row>
                <entry>Option</entry>

                <entry>Default</entry>

                <entry>Description</entry>
              </row>
            </thead>

            <tbody>
              <row>
                <entry><parameter>:encoding</parameter></entry>

                <entry>:marshal</entry>

                <entry>Specifies the serialization encoding to use for the
                message. TorqueBox provides the following built-in encodings:
                <itemizedlist>
                    <listitem>
                      <para><parameter>:marshal</parameter> - The message is
                      encoded/decoded via Marshal, and is transmitted as a
                      binary message.</para>
                    </listitem>

                    <listitem>
                      <para><parameter>:marshal_base64</parameter> - The
                      message is encoded/decoded via Marshal, and is
                      transmitted as a base64 encoded text message. This was
                      the encoding scheme used in TorqueBox 1.x.</para>
                    </listitem>

                    <listitem>
                      <para><parameter>:json</parameter> - The message is
                      encoded/decoded via JSON, and is transmitted as a text
                      message. This encoding is limited, and should only be
                      used for simple messages.</para>
                    </listitem>

                    <listitem>
                      <para><parameter>:clojure</parameter> - The
                      message is encoded/decoded via the
                      <filename>clj</filename> gem, and is transmitted
                      as a text message. This encoding is most
                      convenient for messages that can be represented
                      using standard Clojure data structures.</para>
                    </listitem>

                    <listitem>
                      <para><parameter>:text</parameter> - The message isn't
                      encoded/decoded at all, and is passed straight through
                      as a text message. The content of the message must be a
                      string.</para>
                    </listitem>
                  </itemizedlist> See <xref linkend="message-encodings" /> for
                more information.</entry>
              </row>

              <row>
                <entry><parameter>:priority</parameter></entry>

                <entry>:normal</entry>

                <entry>higher priority messages will be delivered before lower
                priority messages within the context of a queue. You can
                specify the priority as an integer in the range 0..9, or as
                one of the following convenience symbols (with the
                corresponding integer priorities in parentheses):
                <itemizedlist>
                    <listitem>
                      <para><parameter>:low</parameter> (1)</para>
                    </listitem>

                    <listitem>
                      <para><parameter>:normal</parameter> (4)</para>
                    </listitem>

                    <listitem>
                      <para><parameter>:high</parameter> (7)</para>
                    </listitem>

                    <listitem>
                      <para><parameter>:critical</parameter> (9)</para>
                    </listitem>
                  </itemizedlist> Higher priority messages will be processed
                before lower priority ones for a specific message
                processor.</entry>
              </row>

              <row>
                <entry><parameter>:ttl</parameter></entry>

                <entry>0</entry>

                <entry>The maximum time the message will wait in a destination
                to be consumed, in milliseconds. If the message isn't consumed
                within this time it will be delivered to an expiry queue. By
                default, messages don't have a ttl (and therefore never
                expire). By default, expired messages end up on the
                <varname>/queue/ExpiryQueue</varname> queue. If you want to do
                something special with those messages, you'll need to add a
                processor for that queue.</entry>
              </row>

              <row>
                <entry><parameter>:scheduled</parameter></entry>

                <entry>nil</entry>

                <entry>By default a message will be delivered to the queue or topic
                immediately. You can delay the delivery by using the
                <parameter>:scheduled</parameter>. The specified value must be a
                <ulink url="http://www.ruby-doc.org/core/Time.html">Time</ulink>
                object containing the time it should be delivered. Please note that
                scheduled messages will be delivered only to the consumers connected
                at the time of publishing the message.</entry>
              </row>

              <row>
                <entry><parameter>:tx</parameter></entry>

                <entry>true</entry>

                <entry>By default, messages published within the scope
                of a transaction will not be delivered until that
                transaction commits. Set to
                <parameter>false</parameter> to override.</entry>
              </row>

              <row>
                <entry><parameter>:persistent</parameter></entry>

                <entry>true</entry>

                <entry>By default, queued messages will survive across AS
                restarts. If you don't want a message to be persistent, set
                the persistence to <parameter>false</parameter> (see <xref
                linkend="long-lived-destinations" /> for controlling message
                durability globally for a queue).</entry>
              </row>

              <row>
                <entry><parameter>:correlation_id</parameter></entry>

                <entry>nil</entry>

                <entry>The string value to set for the <ulink
                url="http://download.oracle.com/javaee/1.3/api/javax/jms/Message.html#setJMSCorrelationID%28java.lang.String%29">JMSCorrelationID</ulink>
                message header.</entry>
              </row>

              <row>
                <entry><parameter>:reply_to</parameter></entry>

                <entry>nil</entry>

                <entry>The <classname>javax.jms.Destination</classname> value
                to set for the <ulink
                url="http://download.oracle.com/javaee/1.3/api/javax/jms/Message.html#setJMSReplyTo%28javax.jms.Destination%29">JMSReplyTo</ulink>
                message header.</entry>
              </row>

              <row>
                <entry><parameter>:type</parameter></entry>

                <entry>nil</entry>

                <entry>The string value to set for the <ulink
                url="http://download.oracle.com/javaee/1.3/api/javax/jms/Message.html#setJMSType%28java.lang.String%29">JMSType</ulink>
                message header.</entry>
              </row>

              <row>
                <entry><parameter>:properties</parameter></entry>

                <entry>nil</entry>

                <entry>A hash of string key/value pairs to set as message
                properties. This can be used as application-specific headers
                and matched against in the <varname>:selector</varname> option
                of the <methodname>receive</methodname> method.</entry>
              </row>

              <row>
                <entry><parameter>:startup_timeout</parameter></entry>

                <entry>30000</entry>

                <entry>The maximum time to wait for the destination to become
                ready on initial app startup, in milliseconds. On a very slow
                machine this may need to be increased from the
                default.</entry>
              </row>
            </tbody>
          </tgroup>
        </table>
      </section>

      <section id="receiving-messages">
        <title>Receiving Messages</title>

        <para>Receiving messages from a JMS <classname>Queue</classname> or
        <classname>Topic</classname> is very similar to publishing messages.
        To consume a message, simply construct either a
        <classname>Queue</classname> or <classname>Topic</classname> instance
        with its name, and then call its receive method. The API's of both
        Topics and Queues are identical.</para>

        <example>
          <title>Receive messages</title>

          <para><programlisting>queue = TorqueBox::Messaging::Queue.new('/queues/foo')
message = queue.receive

topic = TorqueBox::Messaging::Topic.new('/topics/foo')
message = topic.receive
          </programlisting></para>
        </example>

        <para>The <methodname>receive</methodname> method takes an
        optional hash of options, described below. It can also take an
        optional block, to which the received message will be yielded.
        If a block is supplied, <methodname>receive</methodname>
        returns the value of the block. If the block tosses an
        exception, the broker will consider the message undelivered
        and will automatically retry delivery up to some configurable
        limit [10].</para>

        <table>
          <title>Receive options</title>

          <tgroup cols="3">
            <colspec align="left" />

            <thead>
              <row>
                <entry>Option</entry>

                <entry>Default</entry>

                <entry>Description</entry>
              </row>
            </thead>

            <tbody>
              <row>
                <entry><parameter>:decode</parameter></entry>

                <entry>true</entry>

                <entry>When <parameter>:decode</parameter> is set to true,
                <methodname>receive</methodname> returns the same value that
                was sent via <methodname>publish</methodname>. If
                <parameter>:decode</parameter> is false, the JMS <ulink
                url="http://download.oracle.com/javaee/1.3/api/javax/jms/Message.html">javax.jms.Message</ulink>
                object will be returned instead. This should be true unless
                you need to access headers or properties of the JMS
                message.</entry>
              </row>

              <row>
                <entry><parameter>:timeout</parameter></entry>

                <entry>0</entry>

                <entry>The amount of time to wait before giving up, in
                milliseconds. A value of 0 means to wait indefinitely. If
                <methodname>receive</methodname> times out it will return a
                <literal>nil</literal> value.</entry>
              </row>

              <row>
                <entry><parameter>:selector</parameter></entry>

                <entry>nil</entry>

                <entry>The JMS selector string used to filter messages
                received by this consumer. For details see the "Message
                Selectors" section of the <ulink
                url="http://download.oracle.com/javaee/1.3/api/javax/jms/Message.html">javax.jms.Message</ulink>
                documentation. A <literal>nil</literal> value means all
                messages are received.</entry>
              </row>

              <row>
                <entry><parameter>:startup_timeout</parameter></entry>

                <entry>30000</entry>

                <entry>The maximum time to wait for the destination to become
                ready on initial app startup, in milliseconds. On a very slow
                machine this may need to be increased from the
                default.</entry>
              </row>

              <row>
                <entry><parameter>:durable</parameter></entry>

                <entry>false</entry>

                <entry>Specifies that the connection to a topic should be
                durable. This causes any messages that arrive on the topic to
                be queued. If false, messages that arrive on the topic when a
                <methodname>receive</methodname> is not waiting will be
                discarded. If <parameter>true</parameter>, you must also
                supply a <varname>:client_id</varname> in the connect options
                for the Topic. This option is ignored for Queues.</entry>
              </row>

              <row>
                <entry><parameter>:subscriber_name</parameter></entry>

                <entry>'subscriber-1'</entry>

                <entry>Specifies the subscriber name to be used when creating
                a durable topic subscription. This option is ignored for
                Queues and for non-durable receives on a Topic.</entry>
              </row>
            </tbody>
          </tgroup>
        </table>

        <section id="durable-topic-unsubscribe">
          <title>Unsubscribing a Durable Topic</title>

          <para>If you create a durable topic subscriber by passing the
          <varname>:durable</varname> option to the
          <methodname>receive</methodname> method, that subscription will
          remain until the HornetQ Topic is shut down. If you no longer need
          the subscription, you should unsubscribe it by calling the
          <methodname>unsubscribe</methodname> method on the
          <classname>Topic</classname> object. If you provided a
          <varname>:subscriber_name</varname> to the
          <methodname>receive</methodname> call, you will need to provide that
          same name as an argument to
          <methodname>unsubscribe</methodname>.</para>
        </section>
      </section>

      <section id="managing-destinations">
          <title>Destination management</title>

          <para>
              TorqueBox offers a simple way to manage queues and topics.
          </para>

          <section id="managing-queue-instances">
              <title>Queue management</title>

              <para>
                  There are several methods available in the
                  <classname>TorqueBox::Messaging::Queue</classname> to manage
                  the current instance of the queue.

                  <example>
                      <title>Queue instance management</title>

                      <para><programlisting>queue = TorqueBox::Messaging::Queue.new('/queues/vegetables')
queue.paused? # => true
queue.resume
queue.paused? # => false
queue.count_messages # => 300
queue.count_messages('vegetable = tomatoe') # => 30
queue.remove_messages('vegetable = tomatoe') # => 30
queue.count_messages # => 270
queue.stop</programlisting>
                      </para>
                  </example>

                  <table id="queue-instance-management-options">
                      <title>Queue instance management options</title>

                      <tgroup cols="3">
                          <colspec align="left" />

                          <thead>
                              <row>
                                  <entry>Method</entry>

                                  <entry>Params</entry>

                                  <entry>Description</entry>
                              </row>
                          </thead>

                          <tbody>
                              <row>
                                  <entry>stop</entry>

                                  <entry>None</entry>

                                  <entry>
                                      Stops and destroys the queue.
                                  </entry>
                              </row>

                              <row>
                                  <entry>paused?</entry>

                                  <entry>None</entry>

                                  <entry>
                                      Returns <parameter>true</parameter> if queue is pause, <parameter>false</parameter>
                                      otherwise.
                                  </entry>
                              </row>

                              <row>
                                  <entry>pause</entry>

                                  <entry>None</entry>

                                  <entry>
                                      Pauses the queue. Messages put into a queue will not be delivered even
                                      if there are connected consumers.
                                  </entry>
                              </row>

                              <row>
                                  <entry>resume</entry>

                                  <entry>None</entry>

                                  <entry>
                                      Resumes the queue.
                                  </entry>
                              </row>

                              <row>
                                  <entry>remove_messages</entry>

                                  <entry><parameter>filter</parameter></entry>

                                  <entry>
                                      Removes messages from the queue. The optional <parameter>filter</parameter>
                                      parameter allows to remove only selected messages by filtering them
                                      by the properties with a SQL92-like syntax. If no filter is set, all
                                      messages will be removed. This method returns the count of removed
                                      messages from the queue.
                                  </entry>
                              </row>

                              <row>
                                  <entry>count_messages</entry>

                                  <entry><parameter>filter</parameter></entry>

                                  <entry>
                                      Counts messages in the queue. The optional <parameter>filter</parameter>
                                      parameter allows to count only selected messages by filtering them
                                      by the properties with a SQL92-like syntax. If no filter is set, all
                                      messages will be counted.
                                  </entry>
                              </row>
                          </tbody>
                      </tgroup>
                  </table>
              </para>
          </section>

          <section id="managing-topic-instances">
              <title>Topic management</title>

              <para>
                  The <classname>TorqueBox::Messaging::Topic</classname> objects expose
                  only one method to manage the current instance of the topic.

                  <example>
                      <title>Topic instance management</title>

                      <para><programlisting>topic = TorqueBox::Messaging::Topic.new('/topics/vegetables')
topic.stop</programlisting>
                      </para>
                  </example>

                  <table id="topic-instance-management-options">
                      <title>Topic instance management options</title>

                      <tgroup cols="3">
                          <colspec align="left" />

                          <thead>
                              <row>
                                  <entry>Method</entry>

                                  <entry>Params</entry>

                                  <entry>Description</entry>
                              </row>
                          </thead>

                          <tbody>
                              <row>
                                  <entry>stop</entry>

                                  <entry>None</entry>

                                  <entry>
                                      Stops and destroys the topic.
                                  </entry>
                              </row>
                          </tbody>
                      </tgroup>
                  </table>
              </para>
          </section>
      </section>

      <section id="listing-destinations">
          <title>Listing and looking up destinations</title>

          <para>
              TorqueBox makes it easy to list and lookup any particular queue or topic
              deployed in the server. There are two class methods available in the
              <classname>TorqueBox::Messaging::Queue</classname> and
              <classname>TorqueBox::Messaging::Topic</classname> classes:
              <methodname>list</methodname> and <methodname>lookup</methodname>.
          </para>

          <para>
              The <methodname>list</methodname> method allows to list all queues
              (or topics) deployed in the server. It returns an array of
              <classname>TorqueBox::Messaging::Queue</classname> (or
              <classname>TorqueBox::Messaging::Topic</classname>) objects on which
              you can easily execute management methods mentioned above. If no destinations
              are available, empty array is returned.

              <example>
                  <title>Queue and Topic list</title>

                  <para><programlisting>TorqueBox::Messaging::Queue.list.each do |queue|
    queue.name # => '/queues/vegetables'
    queue.count_messages # => 300
    queue.remove_messages('foo = bar') # => 23
    queue.pause
end

TorqueBox::Messaging::Topic.list.each do |topic|
    topic.name # => '/topics/cars'
end</programlisting>
                  </para>
              </example>

          </para>

          <para>
              The <methodname>lookup</methodname> method allows to lookup a queue (or topic)
              by its name. If a particular queue (or topic) is available it returns a
              <classname>TorqueBox::Messaging::Queue</classname> (or
              <classname>TorqueBox::Messaging::Topic</classname>) object. If there is no
              destination found, <literal>nil</literal> is returned.

              <example>
                  <title>Queue and Topic lookup</title>

                  <para><programlisting>queue = TorqueBox::Messaging::Queue.lookup('/queues/vegetables')

if queue
    queue.count_messages # => 25
end

TorqueBox::Messaging::Topic.lookup('/topics/cars') # => [Topic: '/topics/cars']
TorqueBox::Messaging::Topic.lookup('/topics/doesntexist') # => nil</programlisting>
                  </para>
              </example>
          </para>
      </section>

    <section id="synchronous-messaging">
      <title>Synchronous Messaging</title>

      <para>
        The <methodname>publish</methodname> and
        <methodname>receive</methodname> methods and our higher-level
        messaging abstractions are designed for asynchronous
        communication and are recommended for most uses. However, if
        you do need to send a message and wait for a response,
        TorqueBox also provides a synchronous messaging abstraction.
      </para>

      <example>
        <title>Synchronous messaging</title>

        <para><programlisting>queue = TorqueBox::Messaging::Queue.new('/queues/foo')
Thread.new {
  queue.receive_and_publish(:timeout =&gt; 5000) { |message| message.upcase }
}
message = queue.publish_and_receive "ping", :timeout =&gt; 5000
# message equals "PING"
        </programlisting></para>
      </example>

      <para>
        You send a message with the
        <methodname>publish_and_receive</methodname> method which
        blocks until the <parameter>:timeout</parameter> elapses or a
        response is received. This method has a default
        <parameter>:timeout</parameter> of 10 seconds since you'll
        rarely want to wait indefinitely for a response. In a separate
        thread (likely TorqueBox Services - <xref linkend="services"
        />), you consume messages and publish responses with the
        <methodname>receive_and_publish</methodname> method. The
        return value of the block passed to this method is the message
        response. The options allowed in both these methods are a
        union of those from <methodname>publish</methodname> and
        <methodname>receive</methodname>. Synchronous messaging is
        only available with queues, not topics.
      </para>
    </section>

    <section id="message-encodings">
      <title>Message Encodings</title>

      <para>TorqueBox provides several different encoding serialization
      schemes for messaging, and allows you to override the default encoding
      for all of your messages, or override the encoding used on a per
      <methodname>publish</methodname> basis. Creating and registering your
      own encoding is trivial if you need an encoding scheme that is not
      provided out of the box.</para>

      <section id="built-in-message-encodings">
        <title>Built-In Encodings</title>

        <para>TorqueBox provides the following built-in encodings:
        <itemizedlist>
            <listitem>
              <para><parameter>:marshal</parameter> - The message in
              encoded/decoded via Marshal, and is transmitted as a binary
              message. This is the default encoding.</para>
            </listitem>

            <listitem>
              <para><parameter>:marshal_base64</parameter> - The message in
              encoded/decoded via Marshal, and is transmitted as a base64
              encoded text message. This was the encoding scheme used in
              TorqueBox 1.x.</para>
            </listitem>

            <listitem>
              <para><parameter>:json</parameter> - The message in
              encoded/decoded via JSON, and is transmitted as a text message.
              This encoding is limited, and should only be used for simple
              messages. This encoding is intended to provide interoperability
              with other languages. Any application that uses the :json
              encoding will need to provide the json gem via its Gemfile, or,
              if you are not using Bundler, the json gem must at least be
              installed.</para>
            </listitem>

            <listitem>
              <para><parameter>:clojure</parameter> - The message in
              encoded/decoded via the <filename>clj</filename>
              rubygem, and is transmitted as a text message.  This
              encoding is intended to provide interoperability with
              message producers and consumers written in Clojure. See
              <ulink url="http://immutant.org">the Immutant
              project</ulink> for more information.</para>
            </listitem>

            <listitem>
              <para><parameter>:text</parameter> - The message isn't
              encoded/decoded at all, and is passed straight through as a text
              message. The content of the message must be a string. This is
              useful for passing messages you can guarantee will always be
              strings, or you are doing your own application level
              encoding/decoding.</para>
            </listitem>
          </itemizedlist></para>

        <para>You can specify the encoding on a per-publish basis (see <xref
        linkend="messaging-producers" />), or set the default encoding
        globally (see <xref
        linkend="overriding-default-message-encoding" />).</para>
      </section>

      <section id="overriding-default-message-encoding">
        <title>Overriding The Default Encoding</title>

        <para>You can override the default encoding (:marshal) in your
        deployment descriptor. This default will be used for any of your
        publish calls if no encoding is specified at call time. This change
        will not affect any messages used by TorqueBox internally (to
        implement <link linkend="backgroundable">Backgroundable</link> for
        example).</para>

        <example>
          <title>Overriding the default message encoding</title>

          <para>Using the YAML syntax:<programlisting>application:
  ...
messaging:
  default_message_encoding: json</programlisting></para>

          <para>And via the DSL:<programlisting>TorqueBox.configure do
  ...
  options_for :messaging, :default_message_encoding =&gt; :json
end</programlisting></para>
        </example>
      </section>

      <section id="creating-your-own-message-encoding">
        <title>Creating Your Own Message Encoding</title>

        <para>To create your own message encoding, you need to create a
        subclass of <classname>TorqueBox::Messaging::Message</classname> that
        provides <methodname>encode</methodname> and
        <methodname>decode</methodname> methods, along with
        <methodname>ENCODING</methodname> and
        <methodname>JMS_TYPE</methodname> constants. Below is a simple
        annotated example of a custom YAML encoding.</para>

        <example>
          <title>Annotated custom YAML encoding example</title>

          <para><programlisting>require 'yaml'

module MyModule
  class YAMLMessage &lt; TorqueBox::Messaging::Message
    # a unique name for the encoding, stored with a published 
    # message so it can be properly decoded
    ENCODING = :yaml 

    # can also be :bytes for a binary message
    JMS_TYPE = :text 

    def encode(message)
      # @jms_message is the actual javax.jms.TextMessage
      @jms_message.text = YAML::dump(message) unless message.nil?
    end

    def decode
      YAML::load(@jms_message.text) unless @jms_message.text.nil?
    end
  end

  # this will register the class under the key given by its ENCODING
  TorqueBox::Messaging::Message.register_encoding(YAMLMessage)
end</programlisting></para>

          <para>Using our new encoding:<programlisting>#you'll need to require your encoding class anywhere you publish/receive 
require 'yaml_message'

data = [1, 2, 3]
some_queue.publish(data, :encoding =&gt; :yaml)
puts some_queue.receive # [1, 2, 3]</programlisting></para>
        </example>

        <para>For additional examples, see the message classes defined in the
        <ulink url="https://github.com/torquebox/torquebox/tree/2x-dev/gems/messaging/lib/torquebox/messaging">TorqueBox source</ulink>.</para>
      </section>
    </section>

    <section id="messaging-consumers">
      <title>Message Processors</title>

      <para>Message consumers may be implemented in Ruby and easily attached
      to destinations. A Ruby consumer may either interact at the lowest
      JMS-level, or take advantage of higher-level semantics.</para>

      <section id="low-level-message-consumption">
        <title>Low-level message consumption</title>

        <para>For the lowest-level implementation of a Ruby consumer, the
        class must simply implement <function>process!(msg)</function> which
        receives a <classname>javax.jms.Message</classname> as its parameter.
        Admittedly, this gets quite a lot of Java in your Ruby, but it's
        available if needed.</para>

        <para><example>
            <title>Low-level message consumer</title>

            <para><programlisting>class MyLowConsumer
  def process!(msg)
    # manipulate the javax.jms.Message here
  end
end</programlisting></para>
          </example></para>

        <para>If <function>process!</function> raises an exception, the
        message broker considers the message undelivered and will retry
        delivery up to some configurable limit (default is 10). If all of
        those attempts fail, the broker stores the message in a Dead Letter
        Queue (DLQ) that may be interrogated later.</para>
      </section>

      <section id="syntactic-sugar-for-consumers">
        <title>Syntactic sugar for message consumers</title>

        <para>Message consumers may extend
        <classname>TorqueBox::Messaging::MessageProcessor</classname> and
        implement an <function>on_message(body)</function> method which will
        receive the body of the JMS message.</para>

        <para><example>
            <title>MessageProcessor subclass</title>

            <para><programlisting>class MyConsumer &lt; TorqueBox::Messaging::MessageProcessor
  def on_message(body)
    # The body will be of whatever type was <link linkend="messaging-producers">published by the Producer</link>
    # the entire JMS message is available as a member variable called <function>message()</function>
  end
  def on_error(exception)
    # You may optionally override this to interrogate the exception. If you do, 
    # you're responsible for re-raising it to force a retry.
  end
end</programlisting></para>

            <para>There is an accessor for the actual JMS message that is set
            by TorqueBox prior to invoking <function>on_message</function>, so
            it's there if you need it.</para>
          </example></para>

        <para>Just like with <function>process!</function>, if
        <function>on_message</function> raises an exception, the message
        broker considers the message undelivered. You may trap the error by
        overriding <function>on_error</function>, at which point you decide
        whether to re-raise the exception to force a retry. That is the
        default behavior if you do not override the method.</para>
      </section>

      <section id="connecting-consumers-to-destinations">
        <title>Connecting Consumers to Destinations</title>

          <para>To connect consumers within a TorqueBox-deployed application,
          you need to add a messaging: section to your
          <filename>torquebox.yml</filename> (or external *-knob.yml
          descriptor), or add a <methodname>processor</methodname> directive
          to the destination definition if you are using the DSL (in
          <filename>torquebox.rb</filename>).</para>

          <para>If you are using a YAML descriptor, the messaging: section
          will contain the mappings from your destinations (topics and queues)
          to your consumers. The section is a YAML hash, the keys of which are
          your destination names, which should correspond to existing queues
          and topics. These destinations may be deployed through the same
          <filename>torquebox.yml</filename> or as long-lived
          destinations.</para>

          <para>If you are using a DSL descriptor, the consumers are not
          defined in a separate section, but as part of the queue/topic
          definition. If the destination is a long-lived destination (managed
          by another application), then you will need to tell TorqueBox not to
          try to create the destination by setting the
          <varname>create</varname> to false.</para>

          <example>
            <title>Messaging handlers in a deployment descriptor</title>

            <para>Using the YAML syntax:<programlisting>application:
  ..
queues:
  /queues/my_app_queue:

messaging:
  /queues/my_app_queue:     MyFooHandler
  /topics/long_lived_topic: MyBazHandler</programlisting></para>

            <para>And via the DSL:<programlisting>TorqueBox.configure do
  ...
  queue '/queues/my_app_queue' do
    processor MyFooHandler
  end

  topic '/topics/long_lived_topic' do
    create false
    processor MyBazHandler
  end
end</programlisting></para>

            <para>The classes MyFooHandler and MyBazHandler would correspond
            to files available on the load path:
            <filename>my_foo_handler.rb</filename> and
            <filename>my_baz_handler.rb</filename>, respectively. In a Rails
            app, these files would typically reside beneath
            <filename>lib/</filename> or
            <filename>app/models/</filename>.</para>
          </example>

          <para>The above example shows the simplest possible configuration,
          but it's possible to alter the behavior of your message processor
          using the following options:</para>

          <table id="task-message-processor-options">
            <title>Message processor options</title>

            <tgroup cols="3">
              <colspec align="left" />

              <thead>
                <row>
                  <entry>Option</entry>

                  <entry>Default</entry>

                  <entry>Description</entry>
                </row>
              </thead>

              <tbody>
                <row>
                  <entry><parameter>concurrency</parameter></entry>

                  <entry>1</entry>

                  <entry>May be used to throttle the throughput of
                  your processor. Processors are single-threaded, by
                  default, but you can increase this value to match
                  the number of concurrent messages you want to handle
                  at a time per server. Note that this value
                  determines the number of consumers connected to the
                  destination and thus you'll rarely want a
                  concurrency greater than 1 for topics since that
                  means you'll process duplicate messages. For queues
                  you'll often want this value higher than 1 so you
                  can process messages in parallel.</entry>
                </row>

                <row>
                  <entry><parameter>singleton</parameter></entry>

                  <entry>false</entry>

                  <entry>By default, message processors run on all
                  nodes in a cluster, enabling automatic load
                  balancing. Setting this to true results in a single,
                  HA processor, ensuring that only one node in a
                  cluster receives all messages from its associated
                  destination and, with concurrency set to 1, in the
                  same order they were published.</entry>
                </row>

                <row>
                  <entry><parameter>selector</parameter></entry>

                  <entry></entry>

                  <entry>May be used to filter the messages dispatched to your
                  consumer.</entry>
                </row>

                <row>
                  <entry><parameter>durable</parameter></entry>

                  <entry>false</entry>

                  <entry>Turns the processor into a durable subscriber. Once a
                  processor durably subscribes to a topic, if it disconnects
                  any messages sent will be saved and delivered once the
                  processor reconnects. If <parameter>true</parameter>, you must also
                  supply a <varname>client_id</varname> as well.
                  This setting only affects processors attached to topics, and 
                  is ignored for queue processors.</entry>
                </row>

                <row>
                  <entry><parameter>client_id</parameter></entry>

                  <entry></entry>

                  <entry>A string to uniquely indentify the connecting client.
                  Optional unless you are using the <varname>durable</varname>
                  option (above) on a <classname>Topic</classname>.</entry>
                </row>

                <row>
                  <entry><parameter>xa</parameter></entry>

                  <entry>false</entry>

                  <entry>By default, message processors do not
                  initiate a distributed transaction. Setting this to
                  true will automatically enlist the message
                  processor's receipt of the message and any
                  messaging, cache, or database access inside that
                  processor in single transaction.</entry>
                </row>

                <row>
                  <entry><parameter>config</parameter></entry>

                  <entry></entry>

                  <entry>Should contain a hash of data which will be passed to
                  your consumer's constructor,
                  <function>initialize(Hash)</function>.</entry>
                </row>
              </tbody>
            </tgroup>
          </table>

          <example>
            <title>Messaging configuration in a deployment descriptor with
            options set</title>

            <para>Using the YAML syntax:<programlisting>application:
  ...
messaging:
  /queues/foo:
    MyFooHandler:
      selector: "cost &gt; 30"
      concurrency: 2
      xa: false
      config:
        type: "premium"
        season: "fall"
  /topics/bar:
    MyBarHandler:
      durable: true
      xa: true
      client_id: my-awesome-client</programlisting></para>

            <para>And via the DSL:<programlisting>TorqueBox.configure do
  ...
  queue '/queues/foo' do
    processor MyFooHandler do 
      selector "cost &gt; 30"
      concurrency 2
      xa false
      config do
        type "premium"
        season "fall"
      end
    end
  end

  topic '/topics/bar' do
    processor MyBarHandler, :durable =&gt; true, :client_id =&gt; 'my-awesome-client', :xa =&gt; true
  end
end</programlisting></para>
          </example>

          <para>The YAML and DSL syntaxes enable the configuration to get
          fairly sophisticated, allowing you to, for example, map a single
          destination to multiple processors or re-use configuration options
          in multiple processors. You may never have a need for this much
          flexibility, but it's available if you do.</para>

          <example>
            <title>Advanced messaging configuration in a deployment
            descriptor</title>

            <para>Using the YAML syntax:<programlisting>application:
  ...

messaging:
  /topics/simple: SimpleHandler

  /topics/popular:
    - Handler
        concurrency: 5
    - Observer: &amp;defaults
        selector: "x &gt; 18"
        config:
          x: ex
          y: why
    - Processor

/queues/students:
    VerySimpleAnalyzer:
    YouthMonitor:
      selector: "y &lt; 18"
      config:
        h: ache
        i: eye
    LookAndFeel:
      &lt;&lt;: *defaults</programlisting></para>

            <para>Here we have <code>/topics/simple</code> mapped to a single
            processor of type <code>SimpleHandler</code> using a YAML
            <emphasis>string</emphasis>, <code>/topics/popular</code> mapped
            to three processors (<code>Handler</code>, <code>Observer</code>,
            <code>Processor</code>) using a YAML <emphasis>list</emphasis>,
            and <code>/queues/students</code> mapped to three more processors
            (<code>VerySimpleAnalyzer</code>, <code>YouthMonitor</code>,
            <code>LookAndFeel</code>) using a YAML <emphasis>hash</emphasis>
            where each key in the hash corresponds to the processor type. This
            example also takes advantage of YAML's ability to merge hash's:
            the <code>Observer</code> and <code>LookAndFeel</code> processors
            are configured identically.</para>

            <para>And via the DSL:<programlisting>TorqueBox.configure do
  ...
  topic '/topics/simple' do
    processor SimpleHandler
  end

  common_config = { :selector =&gt; "x &gt; 18", :config =&gt; { :x =&gt; 'ex', :y =&gt; 'why' } }

  topic '/topics/popular' do |topic| 
    topic.processor Handler, :concurrency =&gt; 5
    topic.processor Observer, common_config
    topic.processor Processor
  end

  queue '/queues/students' do |queue|
    queue.processor VerySimpleAnalyzer
    queue.processor YouthMonitor do 
      selector "y &lt; 18"
      config do
        h 'ache'
        i 'eye'
      end
    end
    queue.processor LookAndFeel, common_config
  end
end</programlisting></para>

            <para>Here we have the same configuration as the YAML example
            above, but expressed via the DSL. Note that we have to use the
            block argument form for our destinations that share
            <varname>common_config</varname>. This is due to the no-argument
            form using <methodname>instance_eval</methodname>, which does not
            allow you to access any variables defined outside of the
            block.</para>
          </example>
      </section>
    </section>

    <section id="backgroundable">
      <title><classname>Backgroundable</classname> Methods</title>

      <para>TorqueBox also provides <classname>Backgroundable</classname>
      methods. <classname>Backgroundable</classname> allows you to process any
      method on any class or object asynchronously. You can mark a method to always
      execute in the background, or send a method to the background on an ad
      hoc basis. Backgrounded methods return a <link
      linkend="messaging-futures">Future</link> object that can be used to
      monitor the status of the method invocation and retrieve the final
      return value. When transitioning from TorqueBox 1.x to 2.x, it is
      advisable to replace any <classname>Task</classname> implementation with
      usage of <classname>Backgroundable</classname>.</para>

      <section id="backgroundable-marshalling">
        <title>A note on receiver/argument marshalling</title>

        <para>We serialize the receiver and arguments using Marshal and
        include them in the message that gets enqueued. The message processors
        run in a separate ruby runtime from the application, which may be on a
        different machine if you have a cluster. The marshaling works well for
        basic ruby objects. It may not work as well for objects that expect a lot 
        of plumbing in place (ActionControllers, for example). If you are using
        instances with a backing store (ActiveRecord instances, for example), it's
        generally a better idea to send the id of the instance instead of the full
        instance, and to look it up from the backing store at the start of the
        backgrounded method's invocation.</para>
      </section>

      <section id="backgroundable-always-background">
        <title><function>always_background</function></title>

        <para><classname>Backgroundable</classname> provides the
        <function>always_background</function> class method that allows you to
        flag a class or instance method to always be executed in the background:</para>

        <example>
          <title>Having a method always execute in the background</title>

          <para><programlisting>class User &lt; ActiveRecord::Base
  always_background :send_signup_notification

  def self.send_signup_notification(user_id)
    ...
  end
end

# executes in the background, returning immediately
future_result = User.send_signup_notification(42)
  </programlisting>The <function>always_background</function> method can be
          called before or after the method being backgrounded is defined, and
          can take multiple method symbols: <function>always_background :foo,
          :bar</function>.</para>
        </example>

        <para>You can also call <function>always_background</function> from
        outside of the class definition if you prefer:</para>

        <example>
         <title>Alternative <function>always_background</function>
          usage</title>

          <para><programlisting>class User &lt; ActiveRecord::Base
  def self.send_signup_notification(user_id)
    ...
  end
end

User.always_background(:send_signup_notification)
  </programlisting></para>
        </example>

        <section id="backgroundable-instance-methods">
          <title>Using always_background with instance methods</title>
          <para><function>always_background</function> can be used to enable 
          backgrounding for class or instance methods, even in the same invocation:</para>

        <example>

          <para><programlisting>class User &lt; ActiveRecord::Base
  always_background :a_class_method, :an_instance_method

  def self.a_class_method
    ...
  end

  def an_instance_method
    ...
  end
end</programlisting></para>
        </example>

        <para>Even though you can background instance methods, we generally recommend 
        you use class methods for backgrounding where possible, especially if the backing
        store for an instance can change between when the backgrounded call is queued and
        when it is executed. See the example below for the preferred method for dealing
        with such instances (we'll use an <classname>ActiveRecord</classname> class for the
        example, but the same applies for any instance with a backing store):</para>

        <example>

          <para><programlisting>class User &lt; ActiveRecord::Base
  always_background :process_avatar_for

  def process_avatar
    ...
  end

  def self.process_avatar_for(id)
    # pull the user from the db, in case it has changed since this
    # call was backgrounded
    User.find(id).process_avatar
  end
end

user.avatar = some_file
User.process_avatar_for(user.id)</programlisting></para>
        </example>

        </section>
        
      </section>


      <section id="backgroundable-background">
        <title><function>background</function></title>

        <para>If you have not marked a method with
        <function>always_background</function>, you can background it at call
        time with the <function>background</function> method. A
        method called via <function>background</function> will also return a
        <link linkend="messaging-futures">Future</link> object that can be
        used to monitor the status of the method invocation and retrieve the
        final return value. <function>background</function> can be used with
        class or isntance methods.</para>

        <example>
          <title>Backgrounding a method ad hoc</title>

          <para><programlisting>class User &lt; ActiveRecord::Base
  def do_something
    ...
  end

  def self.do_something_else
    ...
  end
end

user_instance = User.find(id)

# executes in the background, returning immediately
future_result = user_instance.background.do_something

# executes in the foreground (this thread)
regular_result = user_instance.do_something

# executes in the background, returning immediately
future_result = User.background.do_something_else

# executes in the foreground (this thread)
regular_result = User.do_something_else</programlisting></para>
        </example>
        <para>The same <link
        linkend="backgroundable-instance-methods">caveats</link> listed above for 
        using <function>always_background</function>
        with instance methods apply to <function>background</function> as well.</para>
      </section>

      <section id="backgroundable-module">
        <title>The <classname>Backgroundable</classname> module</title>

        <para>To use <classname>Backgroundable</classname> methods in a class,
        you will need to include the
        <classname>TorqueBox::Messaging::Backgroundable</classname> module
        into the class:</para>

        <example>
          <title>Including the <classname>Backgroundable</classname>
          module</title>

          <para><programlisting>class User
  include TorqueBox::Messaging::Backgroundable
  ...
end
          </programlisting>Including <classname>Backgroundable</classname>
          provides both the <function>always_background</function> class
          method and <function>background</function> as both a class
          and an instance method.</para>
        </example>

        <para>If your appplication uses Rails and you use the rails template
        that ships with TorqueBox to create or update your application
        (<command>torquebox rails my_app</command>), you
        should have an initializer
        (<filename>RAILS_ROOT/config/initializers/active_record_backgroundable.rb</filename>)
        that already includes <classname>Backgroundable</classname> into
        <classname>ActiveRecord::Base</classname>.</para>
      </section>

      <section id="backgroundable-invocation-options">
        <title><classname>Backgroundable</classname> method invocation
        options</title>

        <para>The priority, time-to-live (TTL), transaction, and
        persistence options that are available when <link
        linkend="messaging-producers-options">publishing
        messages</link> are available to
        <classname>Backgroundable</classname> methods as well:</para>

        <example>
          <title>Passing options to <classname>Backgroundable</classname>
          methods</title>

          <para><programlisting>class Widget
  always_background :productize, :priority =&gt; :low
  def self.productize
    ...
  end

  def self.monetize
    ...
  end
end

Widget.background(:ttl =&gt; 1000, :persistent =&gt; false).monetize
</programlisting>The message options are passed as a
          <classname>Hash</classname> as the last argument to
          <function>always_background</function>, and as the only argument to
          <function>background</function>. Options passed to
          <function>always_background</function> affect every background
          invocation of the specified methods, while options passed to
          <function>background</function> affect only that particular
          invocation.</para>
        </example>

      </section>

      <section id="backgroundable-message-processor-options">
        <title><classname>Backgroundable</classname> message processor
        options</title>

        <para>All of the options <link
        linkend="task-message-processor-options">available to message
        processors</link> in a deployment descriptor are available to
        <classname>Backgroundable</classname> message processors, too,
        though possibly only the <varname>concurrency</varname> option
        is applicable. In addition to the processor options, you can
        also specify the durability of the underlying queue. This 
        <varname>durable</varname> option is different than the 
        <varname>durable</varname> option for topic processors, and
        instead controls the durability of the underlying queue. It 
        is <varname>true</varname> by default.</para>

        <example>
          <title>Backgroundable message processor options in a deployment
          descriptor</title>

          <para>Using the YAML syntax:<programlisting>application:
  ...
tasks:
  Backgroundable:
    concurrency: 2
    durable: false
</programlisting></para>

          <para>And via the DSL:<programlisting>TorqueBox.configure do
  ...
  options_for Backgroundable, :concurrency =&gt; 2, :durable =&gt; false
end</programlisting></para>
        </example>

        <para>By default, every application you deploy will have a queue for
        <classname>Backgroundable</classname> methods, even if you don't use
        it. To turn off the queue, set the <varname>concurrency</varname> to
        0.</para>
      </section>
    </section>

    <section id="messaging-futures">
      <title>Future Objects</title>

      <para>Methods backgrounded via <classname>Backgroundable</classname>
      return <classname>Future</classname> objects that allow you to monitor
      the progress of the asynchronous processing.</para>

      <table>
        <title>Future instance methods</title>

        <tgroup cols="2">
          <colspec align="left" />

          <thead>
            <row>
              <entry>Method</entry>

              <entry>Description</entry>
            </row>
          </thead>

          <tbody>
            <row>
              <entry>started?</entry>

              <entry>Returns <parameter>true</parameter> if the task
              processing has started.</entry>
            </row>

            <row>
              <entry>complete?</entry>

              <entry>Returns <parameter>true</parameter> if the task
              processing has completed without error. If
              <parameter>true</parameter>, The result is available via the
              <function>result</function> method.</entry>
            </row>

            <row>
              <entry>error?</entry>

              <entry>Returns <parameter>true</parameter> if an error occurred
              during the task processing. If <parameter>true</parameter>, The
              actual error is available via the <function>error</function>
              method.</entry>
            </row>

            <row>
              <entry>status</entry>

              <entry>Returns the last status message returned from the task.
              This will only have meaning if you signal status information
              from within your task. See the <link
              linkend="messaging-futures-status">status notifications</link>
              section for more details.</entry>
            </row>

            <row>
              <entry>status_changed?</entry>

              <entry>Returns true if the status has changed since you last
              called <function>status</function>. This will only have meaning
              if you signal status information from within your task. See the
              <link linkend="messaging-futures-status">status
              notifications</link> section for more details.</entry>
            </row>

            <row>
              <entry>all_statuses</entry>

              <entry>Returns an array of all the statuses received by the
              future, which may not include all of the statuses sent if the
              task completes before they are all received. This will only have
              meaning if you signal status information from within your task.
              See the <link linkend="messaging-futures-status">status
              notifications</link> section for more details.</entry>
            </row>

            <row>
              <entry>result</entry>

              <entry>Returns the result of the remote processing. This method
              takes a <parameter>timeout</parameter> (in milliseconds), and
              will block for that amount of time if processing has started but
              not completed, or up to twice that time if processing has yet to
              start. If no result is available after timing out, a
              <classname>TorqueBox::Messaging::TimeoutException</classname> is
              raised. The <parameter>timeout</parameter> defaults to 30
              seconds. The recommended pattern is to wait for
              <function>complete?</function> to return
              <parameter>true</parameter> before calling
              <function>result</function>.</entry>
            </row>

            <row>
              <entry>method_missing</entry>

              <entry>Delegates any missing methods to the
              <function>result</function>, using the default timeout.</entry>
            </row>

            <row>
              <entry>error</entry>

              <entry>Returns the remote error object if an error occurred
              during task processing.</entry>
            </row>
          </tbody>
        </tgroup>
      </table>

      <section id="messaging-futures-status">
        <title>Sending status notifications to the Future from within the
        task</title>

        <para>From within a task or backgrounded method invocation, you can
        send a status notification to the <classname>Future</classname> for
        this call by using the <function>future.status=</function> method. The
        status can be any marshalable object, and its semantics are defined by
        your application.</para>

        <para>Please note that the <function>future.status=</function> method
        is the only method available on the <classname>future</classname> object
        inside the task or backgrounded method since it is a
        <classname>FutureProxy</classname> instance.</para>

        <example>
          <title>Sending a status message</title>

          <para><programlisting>class Something
  include TorqueBox::Messaging::Backgroundable
  
  always_background :process_some_stuff
  ...
  def self.process_some_stuff
    stuff.each_with_index do |thing, index|
      thing.process_it
      # report the % complete
      future.status = (index * 100)/stuff_count
    end
  end
end

f = Something.process_some_stuff
# time passes
f.started? # =&gt; true
f.status   # =&gt; 22
# time passes
f.status   # =&gt; 87</programlisting></para>
        </example>
      </section>
    </section>
  </section>
</chapter>
