Using Control Stream Features

The System Container

When a StreamBase Server sbd process starts up (with or without an application), a container named system is always added. There are several system streams within an sbd, as listed in The System Container. You can see the streams in a running application by issuing an sbc list command.

This page discusses features of the control stream in the system container that are of use when designing highly available StreamBase applications and for other specialized uses.

Connecting to the Control Stream

Container connections to the control stream from customer-written management modules should use the default asynchronous connection type. In StreamBase releases 7.0.2 and earlier, attempting to make a synchronous connection to the control stream resulted in an error from the server.

Synchronous connections to the control stream are allowed, but produce a warning message instead of an error. TIBCO strongly recommends making a synchronous connection to the system.control stream only under the direction of TIBCO StreamBase Technical Support or a TIBCO StreamBase field engineer.

Caution

Synchronous connections to the system.control stream can hamper the functioning of the system container or of StreamBase Server itself if a tuple sent over such a connection blocks, or takes a long time to be processed. Such connections can result in a Server deadlock in some situations, such as when a module receives notification of a STARTING event for container A and as a result tries to add container B in the same thread of execution. Use synchronous connections to the system.control stream with extreme caution.

The Control Stream Schema

Tuples are emitted from the control stream's output port in response to certain system-level events. These tuples have the following schema:

Field Type
subsystem string
id int
param0 string
param1 string
param2 string

The use and meanings of fields in the control stream schema differs according to which control stream subsystem sent the tuple. The subsystems are: HA, CONTAINER, and Heartbeat.

Control Stream Schema for the HA Subsystem

The control stream schema has the following meanings for tuples emitted from the HA subsystem:

Field Type Description
subsystem string String literal HA
id int

0 (zero)

param0 string

Either LEADER or NON_LEADER

param1 string Not currently used.
param2 string Not currently used.

Control Stream Schema for the CONTAINER Subsystem

The control stream schema has the following meanings for tuples emitted from the CONTAINER subsystem:

Field Type Description
subsystem string String literal CONTAINER
id int

Contains one of:

-100 for STARTING events
0 for START events
100 for STOPPING events
200 for STOPPED events
param0 string

Contains the name of the container whose start or stop event is being reported.

param1 string Contains one of STARTING, START, STOPPING, or STOPPED. The meanings of these event states are described in more detail in The Container Subsystem below.
param2 string Not currently used.

Control Stream Schema for the Heartbeat Subsystem

The control stream schema has the following meanings for tuples emitted from the Heartbeat subsystem:

Field Type Description
subsystem string String literal heartbeat
id int

Contains the heartbeat period in seconds.

param0 string

Contains the number of seconds in the current heartbeat event, converted to a string.

param1 string Not currently used.
param2 string Not currently used.

The Container Subsystem

The CONTAINER subsystem of the system container's control stream sends the event tuples described in the following table:

id Field Param1 Field Description
-100 STARTING

A request to start the specified container has been received by the Server, but the container has not completed startup. While the STARTING tuple is sent on the control stream, the container being added does not see this tuple, as it has not yet finished starting. Instead, the STARTING tuple is seen by other containers.

For example, add container X with a container connection to the control stream; container X itself does not see its own STARTING tuple. Now add container Y, also with a container connection to control; container Y also does not see its own STARTING tuple. However, container X does see container Y's STARTING tuple.

0 START The specified container has completed startup.
100 STOPPING A request to stop the specified container has been received by the Server, but the container has not completed stopping.
200 STOPPED The specified container has successfully stopped.

If the specified container is removed and re-added, another pair of event tuples are sent.

Note

The container START event is not guaranteed to be the first event processed by applications being started in the newly added container. In most cases, it is the first event, but not all cases.

Advanced Uses of the Container Subsystem

You can take advantage of the container START event to perform special processing on the startup of a container. The following StreamSQL example application demonstrates how to set a dynamic variable stating whether or not the START container event has been sent. The same functionality can be implemented in an EventFlow application as well.

-- starttuple.ssql
--
-- Create an input stream connected from the system container's
-- control stream. When this application is added, we need to ensure that
-- this control stream is connected to the system.control stream.
--
create input stream control(subsystem string, 
                            id int, 
                            param0 string,
                            param1 string,
                            param2 string);
--
-- Declare a dynamic variable named "GOT_START_TUPLE" which is initially set
-- to false. When we get a start tuple for this container, we change the 
-- value to true.
--
declare GOT_START_TUPLE boolean default false update from 
     (select true as start from control where subsystem = "CONTAINER" 
      and id = 0 and param0 = getContainer());
--
-- Create an input stream so that we can return the value of the
-- dynamic variable
--
create input stream CheckGotStartTupleInputStream (ping int);
--
-- The output for the dynamic variable query
--
create output stream GotStartTupleOutputStream as
   select GOT_START_TUPLE from CheckGotStartTupleInputStream;

Like the example above, this application must have a container connection from the system.control stream to its input stream, also named control. Use a command like the following to add this application into a container named starttuple:

sbadmin addContainer starttuple starttuple.ssql starttuple.control=system.control

The HA Subsystem

Whenever the leadership status of a StreamBase Server changes, an announcement tuple is sent on the control stream, with the param0 field containing either LEADER or NON_LEADER. When designing a highly available StreamBase application, you can monitor the system container's control stream to determine a server's current leadership status, and to react in some way if the status changes. For example, a monitoring application might add or remove a container, or dynamically enable or disable dequeuing or enqueuing for a container when the leadership status changes.

Advanced Uses of the HA Subsystem

The following StreamSQL example application demonstrates how to set and query a dynamic variable to the value of the current leadership status. The same functionality can be implemented in an EventFlow application as well.

-- leadership.ssql
--
-- Create an input stream connected from the system container's
-- control stream. When this application is added, we need to ensure that
-- this control stream is connected to the system.control stream.
--
create input stream control(subsystem string, 
                            id int, 
                            param0 string,
                            param1 string,
                            param2 string;
--
-- Declare a dynamic variable named "LEADER" which is initially set
-- to the value returned by the function getLeadershipStatus() and
-- is updated by the control stream
--
declare LEADER string default getLeadershipStatus() update from 
     (select param0 from control where subsystem = "HA" and id = 0);
--
-- Create an input stream so that we can return the value of the
-- dynamic variable
--
create input stream CheckLeaderInputStream (ping int);
--
-- The output for the dynamic variable query
--
create output stream IsLeaderOutputStream as
   select LEADER from CheckLeaderInputStream;

For this example application to work, it must have a container connection from the system container's control output stream to the input stream of this module. You can add this application to a container named leader with the following example command:

sbadmin addContainer leader leadership.ssql leader.control=system.control