Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

The following depicts the usage of a SimpleConsumer. As always, bolded text should be adapted for your particular needs and error handling has been omitted. ACS/LGPL/CommonSoftware/acsexmpl/ws/src/acsexmplClientFridgeNC.cpp:

Code Block
languagecpp
titleACS/LGPL/CommonSoftware/acsexmpl/ws/src/acsexmplClientFridgeNC.cpp
linenumberstrue
#include "acsexmplFridgeC.h"
//…
//-----------------------------------------------------------------------------
void myHandlerFunction(FRIDGE::temperatureDataBlockEvent joe, void *other)
{
    ACS_SHORT_LOG((LM_INFO, "::myHandlerFunction(...): %f is the tempdiff.",
    joe.absoluteDiff));
}
//-----------------------------------------------------------------------------
//…

nc::SimpleConsumer<FRIDGE::temperatureDataBlockEvent> {}simpConsumer_p{*} = 0;
ACS_NEW_SIMPLE_CONSUMER(simpConsumer_p,
						FRIDGE::temperatureDataBlockEvent,
						FRIDGE::CHANNELNAME_FRIDGE,
						myHandlerFunction,
						(void *)0);

simpConsumer_p->consumerReady();

ACE_Time_Value time(150);
client.run(time);
simpConsumer_p->disconnect(); simpConsumer_p=0;

//…

1

The client header stub generated by the IDL compiler is used to insert and extract user-defined IDL structures to and from CORBA Any's.

4-8

myHandlerFunction is a void function designed to manipulate one type of IDL struct/event, a temperatureDataBlockEvent. Each time a temperatureDataBlockEvent event is received, SimpleConsumer will call this function.

4

Handler functions must not return any value and shall take in two parameters: the user-defined IDL structure defining ICD events and a void * whose value will always be identical to the void * on line 17.

6-7

Do something useful with the event.

12-17

A SimpleConsumer instance is created. Note that the ACS_NEW_SIMPLE_CONSUMER macro must be used to do this!

12

Create a SimpleConsumer pointer using the event type FRIDGE::temperatureDataBlockEvent for the templated parameter.

13

simpConsumer_p is a pointer to an unallocated SimpleConsumer.

14

The second parameter is the type of event to be received (i.e., a user-defined IDL struct). SimpleConsumers are only capable of receiving and processing a single type.

15

The name of the channel we will subscribe too. In this case it's the "fridge" channel.

16

This function will be invoked each time an event is received.

17

A void * that will be sent to the handler function (line 4) each time an event is received. It can very useful to pass in an object for the void * which will perform some operation on the event from the handler function.

18

Tell the channel we are ready to begin consuming events.

20-22

Run this example for 150 seconds and then disconnect the consumer from the channel.

22

Disconnect from the channel to prevent remote memory leaks from occurring. Do not delete the Consumer!

...

The following depicts the full implementation of a Supplier which publishes one event and then disconnects from the channel. As always, bolded text should be adapted for your particular needs and error handling has been omitted.

Code Block
languagepy
titleACS/LGPL/CommonSoftware/acspyexmpl/src/acspyexmplFridgeNCSupplier.py
linenumberstrue
#!/usr/bin/env python

...


#------------------------------------------------------------------------------

...


import FRIDGE

...


from Acspy.Nc.Supplier import Supplier

...


#------------------------------------------------------------------------------

...


g = Supplier(FRIDGE.CHANNELNAME_FRIDGE)

...


h = FRIDGE.temperatureDataBlockEvent(3.7, FRIDGE.ATREF)

...


g.publishEvent(h)

...


g.disconnect()

...


#------------------------------------------------------------------------------

3

FRIDGE is the CORBA stub module generated by the IDL compiler. It contains the user-defined IDL structure this script is designed to publish as well as the channel's name.

6

This supplier will publish events to the "fridge" channel. Within a component, a second parameter (i.e., self) would also have to be passed.

7

Create an instance of the user-defined IDL structure to be published.

8

Publish the IDL structure created on line 7.

9

Disconnect from the notification channel.

...

Python Consumer

A Python consumer is by far the easiest to use of the ACS-supported CORBA language mappings.

...

...

Example

The following depicts the full implementation of a Consumer. As always, bolded text should be adapted for your particular needs and error handling has been omitted.
ACS/LGPL/CommonSoftware/acspyexmpl/src/acspyexmplFridgeNCConsumer.py



Code Block
languagepy
titleACS/LGPL/CommonSoftware/acspyexmpl/src/acspyexmplFridgeNCConsumer.py
linenumberstrue
#!/usr/bin/env python

...


from time import sleep

...


import FRIDGE

...


from Acspy.Nc.Consumer import Consumer

...


#------------------------------------------------------------------------------

...


def fridgeDataHandler(some_param):

...


    tempDiff = some_param.absoluteDiff

...


    print 'The temperature difference is', tempDiff

...


    return
#------------------------------------------------------------------------------

...


g = Consumer(FRIDGE.CHANNELNAME_FRIDGE)

...


g.addSubscription(FRIDGE.temperatureDataBlockEvent, fridgeDataHandler)

...


g.consumerReady()

...


sleep(50)

...


g.disconnect()

...


#---------------------------------------------------------------------------

3

FRIDGE is the CORBA stub module generated by the IDL compiler. It contains the user-defined IDL structure this script is designed to process as well as the channel's name.

6-9

We must define a function which is capable of manipulating FRIDGE.temperatureDataBlockEvent's. This function will be invoked each time an event is received from the notification channel by registering it with the consumer (line 12). Take note that someParam will always be an instance of FRIDGE.temperatureDataBlockEvent.

11

Create an instance of Consumer connecting to the "fridge" channel.

12

Subscribe to FRIDGE.temperatureDataBlockEvent events and inform the consumer it needs to invoke fridgeDataHandler each time a temperatureDataBlockEvent event is received.

13

Let the channel know we are ready to start processing events.

14

Give suppliers time to publish events…

15

Disconnect from the channel.

...

Java Supplier

Java suppliers and consumer need to be run from the context of a component or ACS Java client.

...

Example

The following shows an example publishing one event and then disconnecting from the channel. Bold text needs to be adapted for your particular needs and error handling has been omitted.


Code Block
languagejava
titleACS/LGPL/CommonSoftware/jcontexmpl/src/alma/demo/EventSupplierImpl/EventSupplierImpl.java

...

linenumberstrue
//…

...


import alma.acs.nc.SimpleSupplier;

...


import alma.FRIDGE.temperatureDataBlockEvent;

...


import alma.FRIDGE.TemperatureStatus;

...


//…

...


SimpleSupplier m_supplier = null;

...


m_supplier = new SimpleSupplier(alma.FRIDGE.CHANNELNAME_FRIDGE.value, m_containerServices);

...



temperatureDataBlockEvent t_block = new temperatureDataBlockEvent(3.14F,

...


																TemperatureStatus.ATREF);

...



m_supplier.publishEvent(t_block);

...


m_supplier.disconnect();

1 & 5

Normally suppliers will be contained within components. This example assumes nothing about whether it's operating under the context of a component, client, etc.

2

Import the SimpleSupplier class used to publish events.

3-4

CORBA Stub classes generated by the IDL to Java compiler. These define the event to be published.

6

The SimpleSupplier variable to be used.

7

The first parameter of SimpleSupplier's constructor is the name of the channel events will be published on. A ContainerServices object is required as the second parameter to gain access to the ORB.

9-10

Create an instance of the IDL structure to publish.

12

Publish the event.

13

Disconnect from the channel.

...

Java Consumer

...

Example

What follows is a trivial consumer that processes one event and then disconnects from the channel.
ACS/LGPL/CommonSoftware/jcontexmpl/src/alma/demo/EventConsumerImpl/EventConsumerImpl.java:



Code Block
languagejava
titleACS/LGPL/CommonSoftware/jcontexmpl/src/alma/demo/EventConsumerImpl/EventConsumerImpl.java
linenumberstrue
import alma.acs.nc.Consumer;

...


//…

...


private Consumer m_consumer = null;

...


//…

...


public void receive(alma.FRIDGE.temperatureDataBlockEvent joe)

...


{

...


	System.out.println("The temp difference is:" + joe.absoluteDiff);

...


}

...


//…

...


m_consumer = new Consumer(alma.FRIDGE.CHANNELNAME_FRIDGE.value, m_containerServices);

...


m_consumer.addSubscription(alma.FRIDGE.temperatureDataBlockEvent.class, this);

...


m_consumer.consumerReady();

...


m_consumer.disconnect();

1

The location of the Consumer class in Java.

5-8

We define a "receive" method designed to process the particular type of event we are interested in. Please note that it must be named "receive" and it does not matter which class this method is implemented in. In this example, it was defined in the component implementation to keep things simple.

10-11

The constructor must subscribe to a specific channel providing a reference to a ContainerServices object (line 10) and then add a subscription for a specific type of event (line 11). On line 11, the 2nd parameter to addSubscription must be an object implementing receive(temperatureDataBlockEvent someEvent).

12

consumerReady must be invoked to start receiving events.

13

Failure to disconnect from the channel causes remote memory leaks!

...

...

Java Wrapper Classes for the Notification Channel

The following describes a set of Supplier and Consumer subclasses contributed by the Scheduling subsystem designed primarily for simulating CORBA Notification Channels entirely within Java virtual machines.

...

Package/Namespace

alma.acs.nc

...

...

Terminology

Publisher is equivalent to Supplier.
Receiver is equivalent to Consumer.

...

...

Classes

  • Receiver – The Receiver interface allows one to attach and detach objects to a notification channel that receive events published on that channel.
  • Publisher – The Publisher interface allows one to publish events to a notification channel that already exists.
  • NotificationChannel – The NotificationChannel interface is merely a combination of both the Receiver and Publisher.
  • AbstractNotificationChannel – The AbstractNotificationChannel class forms the base class from which Local and CORBA Notification Channel classes are extended. It implements the NotificationChannel interface.
  • CorbaNotificationChannel – The CorbaNotificationChannel class implements the notification channel concepts using a CORBA-based approach that employs the CORBA notification services.
  • CorbaPublisher – The CorbaPublisher class implements those methods needed to craft a publisher that publishes events to a CORBA notification channel. It is an extension of the ACS 3.0 Supplier class and uses CORBA structured events.
  • CorbaReceiver – The CorbaReceiver class implements those methods needed to craft an object that receives and processes events from a CORBA notification channel. It is an extension of the ACS 3.0 Supplier class and is intended for use within a CorbaNotificationChannel, in conjunction with the attach and detach methods.
  • EventReceiver – The EventReceiver object is a helper class used internally in implementations of CORBA and Local Receivers. It is merely a pair – an event type name and the receiver object used to process that event.
  • LocalNotificationChannel – The LocalNotificationChannel class implements the notification channel concepts for the case in which multiple threads within the same Java virtual machine wish to publish and receive events.
  • LocalReceiver – The LocalReceiver class is an internal class used by the LocalNotificationChannel. Only its Receiver methods are public. Such an object is created by static methods in the LocalNotificationChannel class.

...

The Local Notification Channel

The concept of a local notification channel has been previously mentioned. The LocalNotificationChannel class implements all the methods required to publish and receive events. In fact, after being created, application code that publishes or receives events see no difference between the two. The restriction is that the LocalNotificationChannel usage is restricted to channels, publishers and receivers that exist within the same Java virtual machine. Of course, the LocalNotificationChannel does not use CORBA, which is the whole point.
NOTE: For the local notification channel your application has to be running on one JVM. Otherwise channels will not find each other!

...

Do they work with Python and C++?

Yes! The examples below have been tested with Python and C++ suppliers. Likewise, FridgePublisher has been tested with a python consumer and a C++ consumer.

...

...

Examples

...

...

CORBA Publisher

  • See ACS/LGPL/CommonSoftware/jcontnc/test/alma/demo/test/AbstractNC/NCPublisherImpl.java

...

CORBA Receiver

  • See ACS/LGPL/CommonSoftware/jcontnc/test/alma/demo/test/AbstractNC/

...

  • NCReceiverImpl.java

Local Publisher

  • See ACS/LGPL/CommonSoftware/jcontnc/test/alma/demo/test/LocalNC/TestLocalNC.java

...

...

Local Receiver

  • See ACS/LGPL/CommonSoftware/jcontnc/test/alma/demo/test/TestNCReceiver/TestReceiver.java

...

...


...

Deployment Information

...

Channel Properties and the ACS CDB

When using the ACS Notification Channel framework, there is nothing special required from the developer aside from issuing the usual ACS startup command(s) which in turn start the CORBA services. However, for those wishing to modify the Quality of Service and Administrative properties for a channel, they can do the following:

  1. For a given channel, "xyz", create $ACS_CDB/CDB/MACI/Channels/xyz/xyz.xml which validates against $ACSROOT/config/CDB/schemas/EventChannel.xsd. The EventChannel.xsd XML schema defines all Quality of Service and Admin properties (described in the Notification Serverice Properties section of this document) applicable to the type of channels the ACS API creates.
  2. Start (or restart) all of ACS.
  3. The first time a supplier or consumer object tries to access the "xyz" channel it will be created using the properties you specified in the ACS CDB. The only special thing to note here is that because the implementation of the Notification Service we use does not support all properties, the API may reject some of your specifications although no exceptions will be thrown. See the known problems sections for details.

...

Debugging Functionality

Quite often it seems to be the case that there is confusion about whether events have been received or even sent for that matter. In as such, the EventChannel.xsd schema now provides an extra attribute, IntegrationLogs, having nothing to do with properties of the channel. When this Boolean value is set to true, a log is sent out each time an event is published or consumed. Be careful though as logs are also events and using this mechanism instantly doubles the overhead being placed on the CORBA Notification Service. It is likely that this debugging functionality will be removed to improve performance someday but for the time being it should prove to be an invaluable too.

...

Event Handler Timeouts

Overloading the CORBA notification service with enormous amounts of events and consumer objects that take too long processing the events can cause serious performance issues or even the corruption of the notification service process itself. To help deal with this, ACS has introduced a new optional sequence of XML elements, Events:, within the main _EventChannel element of EventChannel.xsd. By setting the "MaxProcessTime" attribute of this new element, one can make the ACS NC API(s) emit warning messages whenever an event handler method or function takes too long processing an event. Even if you choose not to use the CDB to set this, by default these messages are sent if the handler takes more than two seconds to process an event.
As an all too brief example, let's say you are the developer sending the events and know the frequency of a particular type of event, IDL:/alma/FRIDGE/FridgeTemperatureDataBlockEvent:1.0, will be shorter than the two second maximum ACS automatically sets. Assume this frequency is once per second. It should then be obvious that any consumers receiving these events need to process them within one second or risk having the event being added to a queue somewhere thereby eventually eating up all available memory. What you can do to be made aware of this problem at run-time is to add the following XML element to the XML described in the section 15.1:

Code Block
languagexml
<Events>

...


<_ Name="FridgeTemperatureDataBlockEvent" MaxProcessTime="1.0"/>

...


</Events> 

The only other piece of advice is that any number of these "_" elements can appear within the "Events" element.

...

Event Browser

ACS provides a graphical user interface which provides some high-level information about events being sent, number of consumers, etc.:

This GUI is started by running "acseventbrowser" from the command-line after Manager is up and running.

...

...

Known Problems

  • Not all Quality of Service and Administrative Properties Work

...

  • : This is the price we pay for using free software. Specifically the following have not been implemented by TAO: EventReliability, ConnectionReliability, StopTime, StartTime, and PriorityOrder.
  • Event Browser does not see all events

...

  • : The cause of this that we've seen is that when supplying events, developers forget to set fields of the IDL structure (particularly enumeration fields). There is an SPR on this and we've submitted bug reports to the various ORB vendors. No progress seems to have been made at this point.
  • Event Filtering does not work on so-called "ALMA events"

...

  • : The TAO Notify Service does not support event filtering on user-defined IDL structures even though the CORBA Extended Trader Constraint Language (a.k.a. event filtering language) specifies it should.
  • For the most up-to-date information on known Notification Channel problems, check the ALMA Software Engineering Software Problem Report (SPR) system.

...

Appendix

Your best source of information is from the code itself (i.e., Doxygen). Other than that, here are the locations (in CVS) of all examples in this document:
ACS/LGPL/CommonSoftware/acsexmpl/ws/idl/acsexmplFridge.midl
ACS/LGPL/CommonSoftware/acsexmpl/ws/include/acsexmplFridgeImpl.h
ACS/LGPL/CommonSoftware/acsexmpl/ws/src/acsexmplFridgeImpl.cpp
ACS/LGPL/CommonSoftware/acsexmpl/ws/src/acsexmplClientFridgeNC.cpp
ACS/LGPL/CommonSoftware/acspyexmpl/src/*.py
ACS/LGPL/CommonSoftware/jcontexmpl/src/alma/demo/Event*
Links to the Doxygen, Javadoc, and Pydoc generated documentation can be found on the ACS webpage.