5 Event Service
5.1 Introduction
The CORBA Event Service provides a flexible model for asynchronous, decoupled communication between objects. This chapter outlines communication models and the roles and relationships of key components in the COS Event Service. It shows a simple example of use of this service.
5.2 Event Service Components
There are five components in the OMG COS Event Service architecture. These are described below:
Figure 1: Event Service Components
- Suppliers and Consumers: Consumers are the ultimate targets of events generated by Suppliers. Consumers and Suppliers can both play active and passive roles. There could be two types of consumers and suppliers: push or pull. A Push Supplier object can actively push an event to a passive Push Consumer object. Likewise, a Pull supplier object can passively wait for a Pull Consumer object to actively pull an event from it.
- Event Channel: The central abstraction in the COS Event Service is the Event Channel which plays the role of a mediator between Consumers and Suppliers. Consumers and Suppliers register their interest with the Event Channel. It can provide many-to-many communication. The channel consumes events from one or more suppliers, and supplies events to one or more consumers. An event channel can support Consumers and Suppliers using different communication models.
- Proxy Suppliers and Proxy Consumers: Proxy Suppliers act as middlemen between Consumers and the Event Channel. A Proxy Supplier is similar to a normal Supplier, but includes an additional method for connecting a Consumer to the Proxy Supplier. Likewise, Proxy Consumers act as middlemen between Suppliers and the Event Channel. A Proxy Consumer is similar to a normal Consumer, but includes an additional method for connecting a Supplier to the Proxy Consumer.
- Consumer and Supplier Administrations: Consumer Administration acts as a factory for creating Proxy Suppliers. Supplier Administration acts as a factory for creating Proxy Consumers.
5.3 Event Service Communication Models
There are four general models of component collaboration in the OMG COS Event Service architecture. The following describes these models: (Please note that proxies were not shown in the diagrams for simplicity).
Figure 2: Event Service Communication Models
- The Canonical Push Model: The canonical Push model shown in Figure 2(A)allows the Suppliers of events to initiate the transfer of event data to Consumers. In this model, Suppliers are active initiators and Consumers are the passive targets of the requests. Event Channels play the role of
Notifier
. Thus, active Suppliers use Event Channels to push data passive Consumers that have registered with the Event Channels.- The Canonical Pull Model: The canonical Pull model shown in Figure 2(B) allows Consumers to request events from Suppliers. In this model, Consumers are active initiators and Suppliers are the passive targets of the pull requests. Event Channel plays the role of
Procurer
since they procure events on behalf of Consumers. Thus, active Consumers can explicitly pull data from passive Suppliers via the Event Channels.- The Hybrid Push/Pull Model: The Push/Pull model shown in Figure 2(C) is a hybrid that allows Consumers to request events queued at an Event Channel by Suppliers. In this model, both Suppliers and Consumers are active initiators of the requests. Event Channels play the role of
Queue
. Thus, active Consumers can explicitly pull data deposited by active Suppliers via the Event Channels.- The Hybrid Pull/Push Model: The Pull/Push model shown in Figure 2(D) is another hybrid that allows the Channel to pull events from Suppliers and push them to Consumers. In this model, Suppliers are passive targets of pull requests and Consumers are passive targets of pushes. Event Channels play the role of
Intelligent Agent
. Thus, active Event Channels can pull data from passive Suppliers and push that data to passive Consumers.5.4 Creating Event Channel
Event Channel could be created using
EventChannelFactory
interface which is implemented inOrberEventChannel_EventChannelFactory_impl.erl
.-module('OrberEventChannel_EventChannelFacotyr_impl'). -include_lib("orber/include/corba.hrl"). -export([init/1, terminate/2, create_event_channel/1]). init(Env) -> {ok, []}. terminate(From, Reason) -> ok. create_event_channel(State) -> {corba:create('OrberEventChannelAdmin_EventChannel', "IDL:OrberEventChannel/EventChannel:1.0"), State}.To start the factory server one needs to make a call to
corba:create/2
which could look like this:-module(event_channel_factory). -include_lib("orber/include/corba.hrl"). -include_lib("orber/COSS/CosNaming/CosNaming.hrl"). -include_lib("orber/COSS/CosNaming/lname.hrl"). -export([start/0]). start() -> ECFok = corba:create('OrberEventChannel_EventChannelFactory', "IDL:OrberEventChannel/EventChannelFactory:1.0"), NS = corba:resolve_initial_references("NameService"), NC = lname_component:set_id(lname_component:create(), "EventChannelFactory"), N = lname:insert_component(lname:create(), 1, NC), 'CosNaming_NamingContext':bind(NS, N, ECFok).Now Event Channel Factory is created and registered in the COS Naming service and could be found by Consumers and Suppliers.
5.5 Using Event Service
This section shows an example of usage of Event Service in order to decouple communication between a measurements collector and a safety controller.
5.5.1 Using the Consumer interface for safety controller
The safety controller plays the role of a push Consumer. It is interested in the data provided by measurements collector, which plays the role of a push Supplier. Safety controller is responsible for the action to be taken in case if some measurements exceed the safety limits.
First, safety controller creates itself and then obtains an
EventChannel
object reference using Event Channel factory, as follows:// The safety controller creates a push consumer object MyPushConsumer = my_push_consumer_srv:create(), // Event channel created through Event Channel Factory // Event Channel Factory obtained from the COS Naming Service (not shown) // Event Channel registered in the COS Naming Service (not shown) EventChannel = 'OrberEventChannel_EventChannelFactory':create(ECFactory),This code assumes that the
MyPushConsumer
supports thePushConsumer
interface and implements the appropriate safety controller logic. Next, the safety controller connects itself to theEventChannel
:// first step: obtain ConsumerAdmin object reference ConsumerAdmin = 'CosEventChannelAdmin_EventChannel':for_consumers(EventChannel), // obtain ProxyPushSupplier from the ConsumerAdmin object PPhS = 'CosEventChannelAdmin_ConsumerAdmin':obtain_push_supplier(ConsumerAdmin), // second step: connect our PushConsumer to the ProxyPushSupplier 'CosEventChannelAdmin_ProxyPushSupplier':connect_push_consumer(PPhS, MyPushConsumer)When an event arrives in the Event Channel, it will invoke the
push
operation on the registeredPushConsumer
object reference.5.5.2 Using Supplier interface for measurements collector
Measurements collector sends data containing information about current measurement of the system to the event channel in order to keep safety controller informed of any changes.
As with the safety controller, the measurements collector Supplier needs an object reference for an
EventChannel
and an object reference for a PushSupplier to connect to the channel. This accomplished as follows:// measurements collector creates a PushSupplier MyPushSupplier = my_push_supplier_srv:create(), // EventChannel obtained from the Naming Service (not shown) EventChannel = //... // obtain SupplierAdmiin object reference SupplierAdmin = 'CosEventChannelAdmin_EventChannel':for_suppliers(EventChannel), // obtain ProxyPushConsumer from SupplierAdmin object PPhC = 'CosEventChannelAdmin_SupplierAdmin':obtain_push_consumer(SupplierAdmin), // connect our PushSupplier to the ProxyPushConsumer 'CosEventChannelAdmin_ProxyPushConsumer':connect_push_supplier(PPhC, MyPushSupplier),Once the Consumer and the Supplier registration code get executed, both the safety controller and the measurements collector are connected to the Event Channel. At this point, safety controller will automatically receive measurements data that are pushed by the measurements collector.
5.5.3 Exchanging and processing event data
The events exchanged between Supplier and Consumer must always be specified in OMG IDL so that they can be stored into an
any
. The event data sent by the measurements collector could be as follows:record(measurements, {temperature, pressure, water_level}).In order to push an event, the measurements collector must create and initialise this record, put it into
CORBA::any
, and callpush
on the Event Channel PushConsumer interface:// create some data EventRecord = #measurements{temperature = 150, pressure = 100, water_level = 200}, EventData = {{tk_struct, SomeIFRId, measurements, [{temperature,tk_double}, {pressure, tk_double}, {water_level, tk_float}]}, EventRecord}, // push the event to Consumer 'CosEventChannelAdmin_ProxyPushConsumer':push(PPhC, EventData),Once the Event Channel receives an event from the measurements collector, it pushes the event data to the Consumer by invoking the
push
operation on registeredPushConsumer
object reference.The implementation of the safety controller Consumer
push
could look like this:push(Data) -> { if Data#measurements.temperature > 300 -> // some logic to set alarm ; Data#measurements.water_level < 50 -> // some logic to get more water ; ......etc end. }