Creating Multiple Instances of a Monitor (Spawning)
You spawn a monitor instance by specifying the spawn
keyword followed by an action. When the correlator spawns a monitor instance, it does the following:
- Creates a monitor instance that is almost identical to the monitor instance that is spawning. The only difference is that the correlator does not clone any active listeners.
- Passes the current values of the monitor instance’s variables to the new monitor instance.
- Executes the named action in the new monitor instance.
By spawning, you can use a monitor as a template to create multiple monitor instances, and in this way you can scale your EPL application to handle a large number of events at one time.
Review the AddSensor event type definition
In this lesson, you will update your EPL program to monitor the temperature and pressure events for each sensor in the industrial process. In this tutorial’s first lesson, you created event type definitions for three input events, coming from the events/SensorTest.evt
file: Temperature
, Pressure
, and AddSensor
.
To review the data types and order of the AddSensor
fields:
-
Open the
eventdefinitions/SensorMonitorEvents.mon
event definition file. -
Note that the AddSensor events have the following fields:
sensorId
(string),targetTemperature
(float), andtargetPressure
(float). -
Close the file.
Create a listener for AddSensor events
-
Open the
monitors/SensorMonitor.mon
file. -
Create a new action, below the
onload()
action, and call itmonitorSensor
.action monitorSensor (string sensorId, float targetTemperature, float targetPressure) { }
-
Move the channel subscriptions and three listeners in the current action
onload()
construct into the newmonitorSensor
action. -
In the
onload()
action, create a new listener for allAddSensor
events and assign theAddSensor
events to thesensor
variable. For the listener action, specify spawningmonitorSensor
:on all AddSensor() as sensor { spawn monitorSensor(sensor.sensorId, sensor.targetTemperature, sensor.targetPressure); }
-
Save your changes.
Update the spawned listeners to handle all sensors
-
In the
SensorMonitor
monitor, remove the targetTemperature and targetPressure monitor-level variables as this information is now coming from the event file. -
In each of the listeners, update the code so that instead of looking for a hard-coded ID, it looks for the value of the current AddSensor event. Change all instances of
sensorId="S001"
tosensorId=sensorId
. This compares the event’sSensorId
to theSensorId
variable we pass as an argument.InfoEach spawned monitor instance will listen for only those events whose sensorsensorId
matches the value of thesensor
variable. -
Save your changes.
The contents of the SensorMonitor.mon
file should now look like this:
monitor SensorMonitor {
action onload () {
// Spawn a monitor instance for each sensor
on all AddSensor() as sensor {
spawn monitorSensor(sensor.sensorId, sensor.targetTemperature, sensor.targetPressure);
}
}
action monitorSensor (string sensorId, float targetTemperature, float targetPressure) {
monitor.subscribe("Factory1");
// Temperature high rule
on all Temperature (sensorId = sensorId, temperature >= targetTemperature * 1.10) as temperature {
print "TEMP_HIGH: " + temperature.toString();
}
// Pressure high rule
on all Pressure (sensorId = sensorId, pressure >= targetPressure * 1.10) as pressure {
print "PRESSURE_HIGH: " + pressure.toString();
}
// Temporal rule, temperature high followed by pressure high
on all Temperature (sensorId = sensorId, temperature >= targetTemperature * 1.02) as temperature ->
Pressure (sensorId = sensorId, pressure >= targetPressure * 1.05) as pressure within (3.0) {
print "TEMP_PRESSURE_RISE: " + temperature.toString() + " " + pressure.toString();
}
}
}
Save everything and run the project.
In the terminal, you should see messages for sensor S003, as well as S001.
You can import the completed solution for this lesson:
In the Apama Samples Git repository, navigate to the tutorials/EPL_Fundamentals_Completed
directory.
An alternative approach to handling multiple concerns (for example, multiple Sensor IDs in the SensorMonitor monitor) is to use a dictionary. A dictionary
is a data type that stores and retrieves data based on a key.
Often the dictionary approach to handling multiple concerns is preferred to spawning. This is particularly true when the spawning approach includes an unmatched event expression, which is vulnerable to maintenance issues if someone else loads a listener for a pattern that you expect to have no other matches.
There is also a lesson in this tutorial that shows you how to use a dictionary in your sample program: see Using a Dictionary and Conditional Logic.