[Erlang Systems]

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:

e_s_components
Figure 1: Event Service Components

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).

e_s_models
Figure 2: Event Service Communication Models

5.4 Creating Event Channel

Event Channel could be created using EventChannelFactory interface which is implemented in OrberEventChannel_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 the PushConsumer interface and implements the appropriate safety controller logic. Next, the safety controller connects itself to the EventChannel:

// 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 registered PushConsumer 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 call push 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 registered PushConsumer 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.
}
      

Copyright © 1991-97 Ericsson Telecom AB