<?xml version="1.0" encoding="UTF-8"?>
<section xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="delayer"
    xmlns:xlink="http://www.w3.org/1999/xlink">
  <title>Delayer</title>

  <section id="delayer-introduction">
    <title>Introduction</title>
    <para>
      A Delayer is a simple endpoint that allows a Message flow to be delayed by a certain interval. When
      a Message is delayed, the original sender will not block. Instead, the delayed Messages will be
      scheduled with an instance of <interfacename>java.util.concurrent.ScheduledExecutorService</interfacename>
      to be sent to the output channel after the delay has passed. This approach is scalable even for
      rather long delays, since it does not result in a large number of blocked sender Threads. On the
      contrary, in the typical case a thread pool will be used for the actual execution of releasing the
      Messages. Below you will find several examples of configuring a Delayer.
    </para>
  </section>

  <section id="delayer-namespace">
    <title>Configuring Delayer</title>
    <para>
      The &lt;delayer&gt; element is used to delay the Message flow between two Message Channels.
      As with the other endpoints, you can provide the "input-channel" and "output-channel" attributes,
      but the delayer also requires at least the 'default-delay' attribute with the number of milliseconds
      that each Message should be delayed.
      <programlisting language="xml"><![CDATA[ <delayer input-channel="input" default-delay="3000" output-channel="output"/>]]></programlisting>
      If you need per-Message determination of the delay, then you can also provide the name of a header
      within the 'delay-header-name' attribute:
      <programlisting language="xml"><![CDATA[ <delayer input-channel="input" output-channel="output"
          default-delay="3000" delay-header-name="delay"/>]]></programlisting>
      In the example above the 3 second delay would only apply in the case that the header value is
      not present for a given inbound Message. If you only want to apply a delay to Messages that have
      an explicit header value, then you can set the 'default-delay' to 0. For any Message that has a
      delay of 0 (or less), the Message will be sent directly. In fact, if there is not a positive delay
      value for a Message, it will be sent to the output channel on the calling Thread.
      <tip>
        The delay handler actually supports header values that represent an interval in milliseconds (any
        Object whose <methodname>toString()</methodname> method produces a value that can be parsed into a
        Long) as well as <classname>java.util.Date</classname> instances representing an absolute time.
        In the former case, the milliseconds will be counted from the current time (e.g. a value of 5000
        would delay the Message for at least 5 seconds from the time it is received by the Delayer). In
        the latter case, with an actual Date instance, the Message will not be released until that Date
        occurs. In either case, a value that equates to a non-positive delay, or a Date in the past, will
        not result in any delay. Instead, it will be sent directly to the output channel in the original
        sender's Thread.
      </tip>
    </para>
    <para>
      The delayer delegates to an instance of Spring's <interfacename>TaskScheduler</interfacename> abstraction.
      The default scheduler used by the delayer is a <classname>ThreadPoolTaskScheduler</classname> instance with a pool size of 1.
      If you want to delegate to a different scheduler, you can provide a reference through the delayer element's
      'scheduler' attribute:
      <programlisting language="xml"><![CDATA[ <delayer input-channel="input" output-channel="output"
          default-delay="0" delay-header-name="delay"
          scheduler="exampleTaskScheduler"/>

 <task:scheduler id="exampleTaskScheduler" pool-size="3"/>]]></programlisting>
    </para>
  </section>

</section>
