Container Connections

This topic discusses how to establish and maintain connections between streams in different application modules running in different containers. See Container Overview for an introduction to StreamBase containers.

Types of Container Connections

The following types of connections between containers are available.

Stream-to-Stream

In this configuration, you set up an application's input stream in one container to receive tuples from an output stream of another application or module in another container, possibly running on another StreamBase Server.

Stream-to-stream connections can be of two types:

  • Asynchronous. In the default form of stream-to-stream container connection, the flow of tuples is set to run asynchronously, with a queue automatically set up by StreamBase to manage the flow through the connection.

  • Synchronous. You can optionally specify low latency, direct connections between container streams without the benefit of queue management. This option offers a possible latency improvement for certain circumstances. In general, asynchronous connections improve throughput, and synchronous connections improve latency. See Synchronous Container Connections.

JMS Container Connections

JMS container connections are connections from container streams to and from your site's Java Message Service (JMS) infrastructure.

In this configuration, you set up one StreamBase Server to send tuples to a JMS server, and another StreamBase Server to receive those tuples from the JMS server. This feature allows you to use the reliable delivery feature of JMS to ensure delivery of StreamBase tuples between applications and containers. See Connecting Container Streams Through JMS.

CSV File Container Connections

In this configuration, you connect a container's output stream to a URI that specifies the absolute path to a CSV file. All tuples sent on this port are then written to the specified file. You can also connect the CSV file's URI to an input stream; in this case, the input stream is read from the CSV file. See Connecting Container Streams To a CSV File.

Specifying Container Connections

StreamBase provides several methods of specifying a connection between containers. Some methods are interactive (for testing and management of containers on running servers), while some methods specify that the connection is made immediately when the enclosing server starts (or when the enclosing container on that server starts). However, all methods are equally effective. Use the method that works best for your application and its stage of development or deployment, but only specify one method per connection for a given run of StreamBase Server. For example, do not specify a connection between containers A and B in both the Run Configuration dialog and in the Advanced tab of a stream.

Each container connection must be specified only once for each connected pair of containers. Do not specify a container connection in the output stream of the sending container and again in the input stream of the receiving container. You can specify the connection in either the sending or receiving container to the same effect. Do not specify the container connection in both places.

The methods of specifying container connections are:

Studio: Connections in Stream Advanced Tabs

In StreamBase Studio, in the Advanced tab of the Properties view for either an input stream or output stream, use the Container connection field to specify a StreamBase expression that resolves to the qualified name of a stream in another container. A qualified stream name follows this syntax:

container-name.stream-name

When using the Advanced tab for an output stream, you are already in the source stream, so you only need to specify the qualified name of the destination stream. Similarly, in the Advanced tab for an input stream, you are in the destination stream, and only need to specify the qualified name of the source stream.

You must express the container-qualified stream name as a StreamBase expression. To express a fixed, known container and stream name, enclose the qualified name in single or double quotes to render the name as an expression. You can also write an expression with variables, field names, and expression language functions that resolves to a qualified container and stream name based on other criteria upstream in your application.

Specify each container connection only once, in either the sending or the receiving stream. Do not specify the container connection in both places.

The following example shows an input stream specifying a connection to the control stream in the system container. This example is taken from the primary HA sample, High Availability Sample.

When you use the Advanced tab to specify a container connection, the connection is stored as part of the EventFlow XML definition of the module, and thus travels with the module. As long as the container names are the same, the same connection will be made whether the module is run in Studio or at the command prompt with the sbd command.

There are restrictions on the order in which you start connected containers, both at the command line and in Studio. See Container Start Order Issues for details.

Studio: Connections in Launch Configuration Dialogs

You can specify both containers and container connections in the Containers tab of Run Configuration dialog (and the Debug and Trace Configuration dialogs).

In the following illustration, running the main application would start two containers: default and sideplay. You must select a line in the top table to add or edit connections for the selected container. The blue highlighting shows that the sideplay container is selected, and it has one connection.

See The Containers Tab for further details on setting up container connections as part of a launch configuration, including information on controlling container start order.

When you specify container connections with the Run Configuration dialog, the connection is stored with the launch configuration for use in Studio only, and not as part of the EventFlow XML. To specify the same containers and connections for running the same application at the command prompt, you must re-specify the container and connections in the server configuration file or with another method.

Connections in the Server Configuration File

You can specify container names and container connections in the server configuration file, for running your application at the command prompt with the sbd command. Use the container attribute of the application element to name your containers. Use the container-connection element to specify the destination and source of container connections, using the container-qualified name of the streams. For example:

<runtime>
  <application file="primary.sbapp" container="A" enqueue="ENABLED" dequeue="ENABLED"/>
  <application file="secondary.sbapp" container="B" enqueue="ENABLED" dequeue="DISABLED">
    <container-connection dest="B.InputStream1" source="A.OutputStream1"/>
    <container-connection dest="B.InputStream2" source="A.InputStream2"/>
  </application>
</runtime>

The order in which you list application elements in the configuration file is significant, as discussed in Container Start Order Issues. See <runtime> for more on the child elements of the runtime element in the server configuration file.

Interactive or Scripted Connections with sbadmin

When you use the sbadmin addContainer or sbadmin modifyContainer commands, either at the command prompt or in a script, you can specify a container connection at the same time. The syntax is:

sbadmin addContainer container-name application.[sbapp|ssql|sbar] connection1 connection2 ...

The following example cascades tuples through three applications, each running in its own container, A, B, and C:

sbadmin addContainer A preprocess.sbapp
sbadmin addContainer B mainprocess.sbapp B.InputMain=A.OutputPre
sbadmin addContainer C postprocess.sbapp C.InputPost=B.OutputMain

A tuple enqueued into container A has the following itinerary:

  • Processed by preprocess.sbapp in container A.

  • Exits container A through output stream OutputPre.

  • Queued to container B's input stream InputMain.

  • Processed by mainprocess.sbapp in container B.

  • Exits container B through output stream OutputMain.

  • Queued to container C's input stream InputPost.

  • Processed by postprocess.sbapp in container C.

The syntax for expressing container connections with sbadmin is always in the order destination=source, much like an assignment statement in many programming languages:

dest-container.instream=source-container.outstream

See the sbadmin reference page for more on the sbadmin command and its options.

Interactive Connections with StreamBase Manager

When using StreamBase Manager to monitor a running application (either in the SB Manager perspective or when run as a standalone utility), you can use it to:

  • Add a container and optional container connection to a running server.

  • Remove a container from a running server.

  • Pause, resume, or shut down the application running in a container on a running server.

To do so, select a server name in the Servers view on the left, and open the tree to select an entry in the Containers tree. Right-click and select options from the context menu, as described in Context Menu Actions for Servers and Context Menu Actions for Containers.

Syntax for Expressing Container Connections

To specify a container connection, you must specify both source and destination stream names, and you must qualify the stream names with their container names. The following syntax is explicitly required when using the sbadmin command, and is expressed in other ways with the other container connection methods:

dest-container.instream=source-container.outstream

If the incoming or outgoing stream is in a module called by a top-level application in a container, then you must specify the module name as well:

dest-container.moduleA.instream=source-container.outstream
dest-container.instream=source-container.moduleB.outstream
dest-container.moduleA.instream=source-container.moduleB.outstream

If the source container is running on a remote StreamBase Server (or if the server is running on a different port on the same host), specify a full StreamBase URI enclosed in parentheses:

dest-container.instream=(sb://remotesbhost:9955/app3.outstream)
dest-container.instream=(sb://localhost:10001/default.outstream6)

You can use a StreamBase URI for the receiving container, as well. For example:

(sb://remotehost:8855/app2.instream)=source-container.outstream
(sb://localhost:10001/default.instream4)=source-containter.outstream

You can use the same syntax for remote hosts in both the dest and source attributes in the server configuration file:

<runtime>
  <application file="primary.sbapp" container="A" />
  <application file="secondary.sbapp" container="B">
    <container-connection dest="B.InputStream1" source="(sb://remotesbhost:9955/app3.outstream)"/>
    <container-connection dest="B.InputStream2" source="A.InputStream2"/>
  </application>
</runtime>

The remote host syntax also works in the Advanced tab of input and output streams, but not when using the Run Configuration dialog in Studio or StreamBase Manager.

You can also specify a JMS server or a CSV file as either source or destination stream. See Connecting Container Streams Through JMS or Connecting Container Streams To a CSV File for the syntax of those connection types.

How the Server Makes Container Connections

With a valid container connection specified, when the module containing the connection starts, the hosting server locates the specified container and stream, and makes the connection. As the application runs, tuples exiting one container's output stream are consumed by the specified input stream in the other container.

The schema of both sides of a container connection must match, as described in Schema Matching for Container Connections.

If the hosting server cannot make the container connection for any reason, it stops and writes an error message to the console. The likely reason for a failure to make a container connection is a failure to locate the specified container or the specified input stream in the application running in that container. In this case, check the spelling of your container connection specification.

When a container is removed, the input or output to any dependent container disappears. The dependent container continues to function, but its input or output is removed.

Using Container Connections to Share a Stream

Stream-to-stream container connections are not limited to one container on each side of the connection. That is, you can configure:

  • Two or more containers to share the same input stream.

  • Two or more containers to share the same output stream.

When input and output streams are shared, the streams are still owned by the original container. This means that any input or output to the shared stream ultimately needs to go through the original container. When tuples are passed between asynchronous container connections, they are passed using the same queuing mechanism used between parallel modules. This means that the tuple is queued for the other containers. When the tuple is queued, the original container must wait for the tuple to be pushed onto the queue, but will not be blocked by the processing of the tuple (which is done in another thread). Because of the queuing architecture, there is no guarantee of the order of tuples when they are shared between multiple containers.

In the following example, containers A and B share the stream A.InputStream1. When a tuple is enqueued into A.InputStream1 the tuple is first passed to all containers that share that stream (in this case, container B) and then it is processed to completion by itself.

sbadmin addContainer A app.sbapp
sbadmin addContainer B app.sbapp B.InputStream1=A.InputStream1

Nothing prevents you from enqueuing directly to an input stream in container B while that stream also receives input from an upstream connection from container A. Because upstream tuples are queued, any input directly into container B is randomly interleaved with input from container A.

Container Start Order Issues

The use of container connections imposes some restrictions on the startup order of containers. In general, the rule is: the container that holds the receiving end of a container connection must start first.

Specifying Container Start Order

If you start the StreamBase Server process, sbd, and at the same time specify a top-level application name to start (either with the -f option or in the server configuration file), then the server exhibits the following behavior:

  • The server loads the top-level application module into a container named default (or into another container name you have specified).

  • The server starts any specified secondary containers in the order specified, and starts the application you specified to run in each.

  • If any secondary containers specify connections to streams in other containers, the container connection is made at the time the container is started. Therefore, the container on the other end of the connection must already be up and running, or the connection attempt will fail.

It is also possible to start the sbd server without specifying any top-level primary application. In this case, you can arrange for your containers to start in any order. This allows you to start secondary containers first, and then start the container for the primary application last. This configuration allows you to specify your container connections in the top-level module itself, because the secondary modules are all running when the top-level application starts.

You can control container start order in the following ways:

Launch Configuration dialog

In Studio, in the Containers tab of the launch configuration dialog, use the Move Up and Move Down buttons to arrange your containers in the desired start order, top to bottom.

Configuration file

Containers specified in the server configuration file are started in the order of their application elements in the file.

For example, If your configuration file specifies modules to start in containers A and B in that order, then the application element for container B can specify container connections to container A. This is because the server starts and runs container A before container B starts. By contrast, container A cannot specify a connection to container B, as long as the containers start in A-B order.

<runtime>
  <application file="primary.sbapp" container="A" enqueue="ENABLED" dequeue="ENABLED"/>
  <application file="secondary.sbapp" container="B" enqueue="ENABLED" dequeue="DISABLED">
    <container-connection dest="B.InputStream1" source="A.OutputStream1"/>
    <container-connection dest="B.InputStream2" source="A.InputStream2"/>
  </application>
</runtime>
Using sbadmin commands

Containers specified with sbadmin commands at the command prompt or in scripts are started in the order of the commands, and in the order of arguments to any one sbadmin command.

In the following example for UNIX, the sbd server is started without specifying a top-level application, and containers are added in A-B-C sequence:

sbd -b
sbadmin addContainer A preprocess.sbapp
sbadmin addContainer B mainprocess.sbapp B.InputMain=A.OutputPre
sbadmin addContainer C postprocess.sbapp C.InputPost=B.OutputMain

Because of the way Windows launches processes, you must specify at least one argument when specifying sbd without an application argument. You can specify a port number for this purpose, even if you only re-specify the default port. Run the following commands at a StreamBase Command Prompt on Windows:

sbd -p 10000
sbadmin addContainer A preprocess.sbapp
sbadmin addContainer B mainprocess.sbapp B.InputMain=A.OutputPre
sbadmin addContainer C postprocess.sbapp C.InputPost=B.OutputMain

Running Connected Containers in Studio

StreamBase Studio imposes additional restrictions on running or debugging modules with container connections:

  • Studio always starts its primary application in a container named default.

  • You cannot use the launch configuration's Containers tab to specify a container connection for streams in the primary application. However, you can instead:

    • Use the launch configuration Containers tab to specify the same connection from the point of view of the other container in the connection.

    • Specify the same connection in the Advanced tab of an input or output stream in the primary application.

Even with these restrictions, it is possible to use Studio to run or debug a pair of modules with a container connection between them, as long as the following conditions are met:

  • Use the Containers tab of the Run Configuration dialog to load your secondary module into a separate container, and give the separate container a name.

  • Specify the container connection in one of two ways, but not both:

    • In the Advanced tab of the Properties view of a stream in either the primary or secondary module, OR

    • In the Run Configuration dialog, for the secondary module only

  • If necessary for your container connection, use the Move Up and Move Down buttons in the Containers tab to make sure the container that holds the receiving end of the connection starts first.

Schema Matching for Container Connections

The schemas of the outgoing and incoming streams in a container connection must match. Schema matching is enforced in two different ways for different cases:

For Container Connections on the Same Server

For stream-to-stream connections between containers running on the same StreamBase Server, the connected streams must have equivalent schemas. That is, the connected streams must share exactly the same field names, field types, sizes, and field positions between the two streams. If the two streams share the same field types, sizes, and names, but are in different order, StreamBase cannot map the streams together.

Tip

To make sure your input and output stream schemas exactly match, use a named schema in one module and use the imported schemas feature of the Definitions tab in the EventFlow Editor of the other module. Assign the same named schema to both streams.

For Container Connections Between Servers

For stream-to-stream connections between containers running on separate StreamBase Servers, fields in the outgoing stream are matched by name against fields in the incoming stream. Fields whose names match must have the same data type in both streams. Any fields in the outgoing schema whose names don't match the incoming schema are not streamed. Any fields in the incoming schema whose names don't match anything in the incoming schema are set to null.

For example, consider an outgoing stream with schema (a int, b (x int, y int, z int)). This stream is connected to an incoming stream with schema (b (y int, z int), c int). The incoming stream does not see fields a or b.x. Fields b.y and b.z are passed from incoming to outgoing, and field c in the incoming stream is set to null.

Dynamic Container Connections

Use sbadmin modifyContainer to dynamically add or remove a container connection from an existing container while StreamBase Server is running:

sbadmin modifyContainer container-name [addConnection | removeConnection] 
    connection-expression1 connection-expression2 ...

Synchronous Container Connections

By default, connections between containers are set up to run asynchronously, with a queue to manage the flow of tuples through the connection.

StreamBase also supports synchronous container connections, which are low latency, direct connections between containers, and do not have queue management. An application might use a synchronous container connection to improve response time of the communication between HA monitoring applications in clustered and high-availability StreamBase design patterns.

Specify a synchronous container connection with the sbadmin command by using := (colon-equals) instead of = (equals) in your container connection assignment statement. For example:

sbadmin addContainer A app1.sbapp
sbadmin addContainer B app2.sbapp
sbadmin modifyContainer addConnection B.incoming:=A.outgoing

You can also specify a synchronous container connection in the server configuration file by adding the synchronicity attribute to the container-connection element that specifies your connection:

...
    <container-connection dest="B.InputStream1" source="A.OutputStream1"
       synchronicity="synchronous" />
...

Caution

Synchronous container connections do not automatically improve the speed of your application. It is even possible to inadvertently degrade your application's speed; for example, by setting up a synchronous connection to a container that blocks.

To determine whether a synchronous container connection will improve your application, you must test your application with and without the synchronous setting, using a test input stream that emulates the actual conditions your application will face in production. Use the Rules of StreamBase Execution Order in the Execution Order and Concurrency page as general guidelines to help decide whether to use synchronous container connections.

StreamBase detects and prevents any attempt to make a synchronous container connection to:

  • Any stream in the system container

  • An endpoint that would cause a loop in processing

Remote Container Connection Parameters

When using a StreamBase URI as part of a stream-to-stream container connection string to specify that one side of the container connection is on a remote StreamBase Server, you can optionally specify URI parameters as part of the remote URI.

The URI parameters you can specify for connections to remote servers depend on which side of the connection is remote. There are two cases:

  • If the URI for the remote server is on the right of the equals sign, then the remote server is the source of the container connection. For example:

    boxA.instream1=("sb://remotehost:9900/boxB.outstr4")
    

    In this case, you can specify one parameter for the connection:

    • reconnect-interval

  • If the URI for the remote server is on the left of the equals sign, then the remote server is the destination of the container connection. For example:

    ("sb://remotehost:9900/boxC.instr2")=boxD.outstr6
    

    In this case, you can specify up to five parameters for the connection:

    • enqueue-buffer-size

    • enqueue-flush-interval

    • max-enqueue-buffer-size

    • reconnect-interval

    • filter-expression

These parameters have the same meanings for container connections as the similarly named property of the StreamBase to StreamBase adapters described in StreamBase to StreamBase Output Adapter and StreamBase to StreamBase Input Adapter.

Container Connection Parameter SB to SB Adapter Property Default Value Units Description
enqueue-buffer-size Enqueue buffer size 100 tuples The numbers of tuples to enqueue before tuples are sent to the connected application.

For a low-latency application, set the buffer size to zero.

enqueue-flush-interval Enqueue flush interval 100 milliseconds The flush interval of the enqueue buffer in milliseconds.

For a low-latency application, set the flush interval to a small non-zero number. Do not set it to zero, which causes the adapter to perform a busy loop and consume excessive CPU cycles.

max-enqueue-buffer-size Max enqueue buffer size 1000 tuples The maximum size of the enqueue buffer before tuples are dropped. Enter –1 to disable this setting.
reconnect-interval Reconnect Interval 10 milliseconds The period, in milliseconds, that the container connection waits between reconnection attempts after the connected application fails or no compatible stream is present. Set this parameter to zero to disable reconnection. When reconnection is disabled, the connected application must be started first and must have a compatible output stream from which the upstream application can read.

Note

When specifying a reconnection interval as part of a container connection to a remote host, specify the interval value in milliseconds. (When specifying the reconnection interval in the StreamBase to StreamBase Output adapter, the value is in seconds.)

filter-expression Filtered Subscribe Expression None None Specify a simple StreamBase expression such as symbol=IBM to serve as a filter for tuples. Because the expression is part of a URL, you must escape the equals sign of the expression, plus any spaces and URL reserved characters using standard URL encoding. For example, append the following to a remote connection URI: ;filter-expression=symbol%3DIBM

Append one or more container connection parameters to a StreamBase URI, each preceded by a semicolon. For example, to specify non-default buffer sizes for a destination connection, use a container connection string like the following:

("sb://remotehost:9900/boxC.instr2;enqueue-buffer-size=300;max-enqueue-buffer-size=2000")=boxD.outstr6

See StreamBase to StreamBase Output Adapter for a discussion of these property settings.