FIFO (First In First Out)
Introduction
FIFO (First In First Out) guarantees are not commonly made in the context of messaging. PilotFish’s eiPlatform supports limited FIFO functionality within the context of routes. However, FIFO functionality should be used with great care and only when necessary. This document details the benefits and drawbacks of FIFO functionality, how it compares with other products within the industry, and when PilotFish’s eiPlatform FIFO functionality should and should not be used.
What is FIFO?
PilotFish’s eiPlatform uses separate threads within a route to process messages between the listener and transport stages to improve performance by taking advantage of parallelism. The side effect of this performance improvement is that transactions processed in parallel may or may not complete in the order in which they started.
PilotFish’s FIFO functionality guarantees first in, first out ordering within the context of a route. This ordering is achieved through the use of a data structure, called a queue, that enforces ordering by restricting outbound processing to a single thread at the transport.
The Benefits and Drawbacks of FIFO
The obvious benefit of enforcing FIFO is that messages within a route exit the transport(s) in the same order in which they are received by a listener. However, the drawbacks are that performance suffers and additional memory overhead is required. Additional considerations also must be taken into account when enabling FIFO, such as: chaining FIFO routes, queueing between routes, and error handling.
As previously stated, FIFO guarantees message ordering within a single route. However, when routes are chained then ordering may no longer be guaranteed unless the next route in the chain also uses FIFO. As more routes use FIFO, the overall resource demand increases and performance erodes.
Queueing in between routes also creates an interesting problem when attempting to maintain the exact ordering of messages across more than one route. Most robust message queueing platforms do not guarantee ordering, since they are intended to be used in a distributed fashion and strict enforcement of ordering can severely hinder performance, which can ultimately cause a system to miss service targets. JMS (Java Message Service) is a standard for message queuing that does not guarantee strict ordering in all cases due to the architectural and performance limitations that would result [1]. However, some products that implement the JMS standard (e.g. HornetQ) can be configured for serial processing at the possible expense of performance [2].
Another implication of FIFO functionality is error handling. Without FIFO, error handling can be entirely within the context of a transaction. If a transaction succeeds or fails, then it alone succeeds or fails. However, in the context of FIFO, if a transaction for some reason is received by the listener, yet never processed by the target, it may prevent other transactions from processing. Therefore, error handling has another dimension of time. How long should a transaction be allowed to process before it is considered to be in an error state?
FIFO in the Industry
Many messaging products have limited support for FIFO processing. Products like Microsoft BizTalk and JBoss ESB support FIFO processing, but caution against its regular use due to the performance implications that accompany it [3][4]. Other products, like the former eGate from SeeBeyond and Sun Microsystems, promoted the use of JMS for queueing between components but also supported additional functionality for priority ordering and partial ordering [5].
When to Use FIFO
FIFO processing should only be enabled when absolutely necessary. Although there is no guarantee of the exact order in which messages will be delivered from a route without FIFO enabled, the performance impacts and the additional overhead required to support FIFO should not go without consideration.
FIFO may be necessary if messages are received in order in close succession where there exists a dependency relationship between two or more messages in that group. A common example of this behavior is financial transactions. If a sell order and a buy order are executed in close succession, the buy order shouldn’t fail because there are insufficient funds. In that case, and in similar cases, FIFO is needed. However, in most cases, where message delivery primarily depends on speed and reliability, FIFO is likely not required.
References
[1] Hapner, Mark, et al. “Java message service.” Sun Microsystems Inc., Santa Clara, CA
(2002).
[2] “HornetQ User Manual.” Red Hat Inc. 2011.
[3] “Ordered Delivery of Messages.” MSDN. Microsoft Inc. 2010. Oct. 21, 2014.
[4] T. Fox, J. Mesnil, A. Taylor, C. Suconic, H. Gao. “JBoss Enterprise Application Platform
4.3 Messaging User Guide.” Red Hat Inc. 2011. Oct. 21, 2014.
[5] “Sun SeeBeyond eGate Integrator JMS Reference Guide.” Sun Microsystems Inc. 2007.