Cullen Programming

JAVA Pipelines


Pipeline Stalls


With multistream pipelines you may see a new kind of error: a stall. A stall occurs when the dispatcher cannot run any of the stages because every stage is waiting for some other stage to perform some function. Usually stalls are caused by stages that read multiple input streams in a particular order or that need records to be available on more than one stream at the same time. A stall occurs when the preceding stages do not deliver records in the order needed or do not provide multiple records concurrently.

When a stall occurs, the pipe processing is deadlocked.

What can you do when a pipeline stalls? First, look at any stages that have multiple input streams. Of these stages, identify any stages that need records in a particular order (such as FANIN) or that need more than one record at a time (such as SPECS and OVERLAY).

Next, analyze the pipeline to see what order the records are being delivered to these stages. You need to look at the stages that are supplying records. It helps to draw a map of the pipeline. Look for earlier stages that have secondary outputs connected. These stages often deliver records in a particular order and that order is not what the stage combining the streams needs.

After finding the problem, you can either change the order of delivery of the records, or you can change the stage combining the streams to match the supplied order.

A common stall is shown in Figure 1. There may be many other stages between FANOUT and FANIN, but in many cases these other stages don't matter. It is the FANOUT/FANIN combination that causes the problem. FANIN needs to read all the records of one stream before reading the next. FANOUT, however, writes one record to each of its output streams.


(example 1:)    < test.data | a: fanout | b: fanin | console ? a: | b:

Figure 1. Example Stall Involving a Stage that Needs Records in Order


FANOUT writes a record on its output stream 0. FANIN reads this record. Then FANOUT tries to write a copy of the record on its output stream 1. It waits for FANIN to read the record, but FANIN is waiting for FANOUT to write another record on stream 0. FANIN will not read from its input stream 1 until input stream 0 is empty. The pipeline is stalled.

Figure 2 shows one way to fix the stall. A BUFFER stage is added. BUFFER doesn't write any records to its output stream until it has read all the records in its input stream. So, when FANOUT writes a record to its output stream 0, FANIN reads that record. When it writes to stream 1, the BUFFER stage reads the record. After FANOUT writes its last record to stream 1, BUFFER writes the records to its output stream. Because FANIN has, by this time, processed all the records in its input stream 0, it can now process the records supplied by BUFFER on stream 1.


(example 2:)    < test.data | a: fanout | b: fanin | console ? a: | buffer | b:

Figure 2. Fixing a Stall with a BUFFER Stage

You can also fix the stall by replacing the BUFFER stage in Figure 1 with another built-in stage called ELASTIC. The ELASTIC stage works like BUFFER. However, ELASTIC reads only as many records into a buffer as necessary to prevent a stall (Figure 3).


(example 3:)    < test.data | a: fanout | b: fanin | console ? a: | elastic | b:

Figure 3. Fixing a Stall with an ELASTIC Stage

   Another solution is to substitute FANINANY for FANIN.  FANINANY does not
   care about the order in which records are delivered to it.  Of course, the
   order of records flowing out of FANINANY is not the same order that FANIN
   would have provided.  So, FANINANY might not be an acceptable solution.

The following terms, are trademarks or registered trademarks of IBM Corporation:
   IBM
   OS/2
   VM
   NetRexx
   CMS


For more information about using pipelines, see the IBM CMS Pipelines Reference and Pipelines User's Guide at the IBM website .

[Return to Index]

[Return to Cullen Programming Home Page]