- Index

< Previous |  | Next >

# Using Dynamic Variables

This topic discusses the use of dynamic variables in EventFlow applications.

A dynamic variable is a variable you can declare for a StreamBase module that can thereafter be referenced by name in expressions in operators and adapters in that module. In the declaration, you can link each dynamic variable to an input or output stream in the containing module. You can also define dynamic variables before creating a stream.

A dynamic variable's value is updated when a tuple is received on the linked input stream or when a tuple is emitted from the linked output stream. The scope of a dynamic variable is the containing module.

## Dynamic Variable Overview

The value stored in a dynamic variable is obtained from a value in a tuple enqueued to the application. This tuple can be one of the tuples submitted to the application for processing, or it can be a control tuple, submitted to the application for the sole purpose of changing the application's configuration. The distinguishing characteristic of a dynamic variable is that its value can change while the application runs.

For example, your application might maintain a threshold value that is compared to a field value in each tuple processed. If the tuple field value is less than the threshold value, your application performs one set of operations. If the tuple field value is greater than or equal to the threshold value, your application performs a different set of operations.

If you do not provide an updating expression, the initial value you supply for that dynamic variable is used at runtime. However, if you do not supply an expression or if your application has no reason to change the threshold value while it runs, there is no reason to create a dynamic variable, and you can hard-code the desired value into the application. But if you want to have the capability of changing the threshold value while the application runs, then use a dynamic variable.

StreamBase infers the data type of dynamic variables based on the initial value, so use an explicit initial value. For example, the initial values `100`, `100.0`, and `100L` declare variables of types int, double, and long, respectively. In some cases, you may need to use a casting function, such as int(), double(), or long() to cast the initial value to the desired data type.

If you associate a dynamic variable to an output stream, and then disable the output stream on the canvas, the dynamic variable no longer updates.

The icons for input and output streams that are used to update dynamic variables are shown with `(x)=` in the upper right of the icon.

### Legacy Dynamic Variables

As a consequence of inferring the variable's data type from its initial value, you might encounter a typecheck message when opening an application in Studio that was created with an earlier StreamBase release (where dynamic variables were scoped per operator, not per module). The typecheck message includes text similar to: `cannot convert expression `expr-name` of type double to type int`. Previous releases determined the data type of dynamic variables by testing the update expression. Now that the data type is determined from the initial value, you may need to use a casting function in the initial value expression to allow a migrated application to pass typechecking.

## Dynamic Variable Tutorial

The EventFlow tutorial in this section shows you how to define, initialize, and update a dynamic variable. The tutorial takes prices from an input stream and sends them to two output streams: one for prices above a certain threshold; another for prices below that threshold.

To split the prices, we use a Filter operator whose predicate compares each incoming price to the threshold, and we define the threshold as a dynamic variable. The application will have two input streams: one to accept a stream of price data, and a second input stream used to change the value of our threshold value as the application runs.

Follow these steps:

1. Create a new EventFlow application in StreamBase Studio, using File → New → StreamBase Project:

   1. Choose a name for the project, such as `dynvartutorial`.

   2. Select the StreamBase EventFlow™ Fragment project type.

   3. Click Next.

   4. On the next panel, specify a Group Id according to your site standards, or enter `com.example.sb`.

   5. Click Finish.

2. This opens an EventFlow module with the same name as your project, such as `dynvartutorial.sbapp`. With this new application open in the EventFlow Editor, first add an input stream that can be used to update the dynamic variable:

   1. Drag an input stream from the Palette to the canvas and name it `UpdateVariable`.

   2. Open the input stream's Properties view. In the Edit Schema tab, add a single field named `NewThreshold` with data type `double`.

   Note that while placing a stream on the canvas before creating a dynamic variable is normal practice, it is not a requirement. Updating streams do not need to be connected to any other component, but can be used on their own to update dynamic variables. In the event you do not want a dynamic variable to be updated by any stream, leave the input stream field empty.

3. Select the Dynamic Variables tab of the EventFlow Editor. Add a dynamic variable by clicking the plus button. Fill in the columns as follows:

   Variable Name | Updating Stream | Updating Expression | Initial Value
   --- | --- | --- | ---
   Threshold | UpdateVariable | NewThreshold | 100.0

   This defines a dynamic variable called `Threshold` whose initial value (`100.0`) is used when the application starts. After that, the value of Threshold is reset to the value of the `NewThreshold` field whenever a tuple arrives on the `UpdateVariable` stream.

   ### Tip

   If you use the same name for a dynamic variable and for its updating expression field, Studio issues a typecheck warning. You can use the same name in both places if you qualify the field name with `input.`fieldname`` to distinguish the field name from the variable name.

   You must do this because unqualified names in any expression are first resolved against the names of the module's dynamic variables, and only then against the names of fields in available streams. Using a qualified field name removes the equivocation and specifies that the updating expression is based on the field name, not the dynamic variable that happens to share the name.

4. Next, add another input stream to receive price data, and rename it `PricesIn`. In the Edit Schema tab, add a field named `Price` with data type `double`.

5. Drag a Filter operator from the Palette to the canvas, and connect the `PricesIn` stream to it.

6. In the Filter operator's Predicate Settings tab in its Properties view:

   1. Enable the Create output port for non-matching tuples option.

   2. For Output Port 1, enter this Predicate expression:

      `Price <= Threshold`

   This adds a second output port to the Filter operator, and sets up the operator to evaluate each arriving tuple. If the expression resolves to `true` (that is, if `Price` is less than or equal to the `Threshold` value), then output is emitted on output port 1. If the expression resolves to `false`, output is emitted on port 2.

7. Drag two output streams to the canvas. Name them `LowPricesOut` and `HighPricesOut`. Connect these streams to the top and bottom output ports, respectively, of the Filter operator.

8. Your application should now pass typechecking. Save the application.

9. Now run this application in Studio and enqueue values on the input stream in the Manual Input view, to observe what values get directed to which output streams. Then input a new threshold value on the `UpdateVariable` stream and confirm that the Filter's behavior has changed.

Any input or output stream can update a dynamic variable. A more advanced use of dynamic variables is to create an output stream at any point in your application, resulting in a kind of feedback. As an example, you could make the output stream of the Filter's second port be the updating stream, using an updating expression of `NewThreshold * 2`. This would double the threshold every time a value exceeded the threshold.

When defining a dynamic variable, your updating expression might need to refer to more than one field in the updating stream to build your expression. You can qualify such field names with `input.` instead of repeating the updating stream's name. Thus, for a dynamic variable that updates from the sum of two fields, `alpha` and `beta`, in an updating input stream named `UpdateVariable`, you can specify either of the following as your updating expression:

`UpdateVariable.alpha + UpdateVariable.beta`

`input.alpha + input.beta`

If the updating expression refers to a field with the same name as the dynamic variable, the field name in the updating expression must be qualified with the name of the updating stream to distinguish the field from the dynamic variable itself. For example, it is reasonable to have an expression `dynvar + 1` to increment the dynamic variable `dynvar` itself. However, if you intend to derive the expression value from the `UpdateVariable` stream's field named `dynvar`, then the expression must be `UpdateVariable.dynvar + 1`.

Back to Top ^