Working with channels in C++ plug-ins
In a C++ correlator plug-in, you can send an event to a particular channel, subscribe to receive events sent to particular channels, receive events sent on subscribed channels, and unsubscribe from subscribed channels.
There is currently no support for channels in correlator plug-ins written in C.
Sending events to particular channels
To send an event to a particular channel, call the AP_CorrelatorInterface.sendEventTo()method:
virtual void sendEventTo(const char *event, const char *targetChannel, const AP_Context &source)
event — For the event to send, specify a string in the format described in
Event file format.
targetChannel — Specify the name of the channel you want to send the event to.
&source — Specify the context that this plug-in call is running in. This is the
AP_Context object that was passed to the plug-in method or event handler method. If this method is called from a background thread then that thread passes an
AP_Context::NoContext() object to this method. Specify that object as the source context.
An event that is passed to the sendEventTo() method is delivered to any contexts, receivers, and plug-in event handlers that are subscribed to the specified channel.
Defining an event handler class for receiving events
To receive events sent to channels, derive an event handler class from AP_EventHandlerInterface and implement the handleEvent() method:
virtual void handleEvent(const AP_BlockingAwareContext &ctx, const char *event, const char *channel)
ctx — Context in which this execution of the event handler is happening.
event — An event being received. The event must be represented as a string in the format described in
Event file format.
channel — The channel on which the event was received.
Store each reference to an event handler instance in the AP_EventHandlerInterface::ptr_t smart pointer. When the last reference to a particular event handler is dropped then that instance is deleted.
Subscribing event handlers to channels
After you create an event handler class, you use event handler objects to subscribe to receive events sent on one or more channels. Each event handler object can receive events from multiple channels and you can specify the same event handler in multiple subscriptions. If you subscribe to receive events from the same channel more than once the duplicate subscriptions are ignored. When an event handler is subscribed to one or more channels its handleEvent() method is called once for each event that is sent to any subscribed channel.
There are several overloadings of the AP_CorrelatorInterface.subscribe() method:
To use an initializer list to subscribe an event handler object to one or more channels:
void subscribe(const AP_EventHandlerInterface::ptr_t &handler, std::initializer_list<const char *> channels);
This overloading is not supported on SUSE Linux Enterprise Server 11.
This overloading uses smart pointers for reference counting. Use the following format to call it:
correlator->subscribe(AP_EventHandlerInterface::ptr_t(new MyHandlerType()), { "channel one", "channel two" });
handler — Specify the handler to subscribe.
channels — Specify one or more channels that you want to receive events from.
To use an iterator pair or an array of
char* values to subscribe an event handler object to one or more channels:
template<typename ITER>
void subscribe(const AP_EventHandlerInterface::ptr_t &handler, const ITER &start, const ITER &end);
This overloading uses smart pointers for reference counting. Use the following format to call it:
correlator->subscribe(AP_EventHandlerInterface::ptr_t(new
MyHandlerType()), channels.begin(), channels.end());
handler — Specify the handler to subscribe.
start — The iterator to start from.
end — The iterator to end at.
The iterators must resolve to values that can be cast to const char* values. Alternatively, you can use an array of char* values in place of the iterators.
To subscribe an event handler object to a single channel:
template<typename T>
void unsubscribe(const AP_EventHandlerInterface::ptr_t &handler, const T &channel);
This overloading uses smart pointers for reference counting. Use the following format to call this method:
correlator->subscribe(AP_EventHandlerInterface::ptr_t(new
MyHandlerType()), "channel one");
handler — Specify the handler to subscribe.
channel — Specify the channel to subscribe to. The value you specify must be a value that can be cast to char*.
Unsubscribing event handlers from channels
Several overloadings of the AP_CorrelatorInterface.unsubscribe() method let you cancel one, multiple, or all channel subscriptions. If the result of an unsubscribe() method is that the event handler has no subscriptions, and if there are no references to that event handler, then the event handler object is deleted.
To use an initializer list to unsubscribe an event handler object from one or more channels:
void unsubscribe(const AP_EventHandlerInterface::ptr_t &handler, std::initializer_list<const char *> channels);
This overloading is not supported on SUSE Linux Enterprise Server 11.
This overloading uses smart pointers for reference counting. Use the following format to call it:
correlator->unsubscribe(my_handler, { "channel one", "channel two" });
handler — Specify the handler to unsubscribe.
channels — Specify a list of channels for which to cancel subscriptions.
To use an iterator pair or an array of
char* values to unsubscribe an event handler object from one or more channels:
template<typename ITER>
void unsubscribe(const AP_EventHandlerInterface::ptr_t &handler, const ITER &start, const ITER &end);
This overloading uses smart pointers for reference counting. Use the following format to it:
correlator->unsubscribe(my_handler, channels.begin(), channels.end());
handler — Specify the handler to unsubscribe.
start — The iterator to start from.
end — The iterator to end at.
The iterators must resolve to values that can be cast to const char* values. Alternatively, you can use an array of char* values in place of the iterators.
To unsubscribe an event handler object from a single channel:
template<typename T>
void unsubscribe(const AP_EventHandlerInterface::ptr_t &handler, const T &channel);
handler — Specify the handler to unsubscribe.
channels — Specify the channel to unsubscribe from. The value you specify must be a value that can be cast to char*.
To unsubscribe an event handler object from all channels it is subscribed to:
virtual void unsubscribe(const AP_EventHandlerInterface::ptr_t &handler);
handler — Specify the handler to unsubscribe. If there are no other references to this event handler, it is deleted.
Notes for writing C++ plug-ins that use channels
Ordering
When an event is sent to some contexts and some plug-ins the order the order in which those contexts and plug-ins process the event is unpredictable.
Events sent on a particular channel maintain their order on the event handler that receives them. However, there is no ordering with regard to other components that might be subscribed to the same channel and so receive and operate on the same events.
There is no ordering of events sent on different channels and received by the same event handler.
Blocking
As with plug-in method calls, methods on event handlers may be blocking or nonblocking. If a plug-in is declared as nonblocking then the correlator will assume that all its event handlers are also nonblocking. You can call the
AP_BlockingAwareContext.pluginMethodBlocking() method to declare that an event handler is actually blocking, despite the overall plug-in nonblocking setting. Event handlers must not perform any potentially blocking operations if the plug-in is nonblocking without calling
pluginMethodBlocking(). See
Working with blocking behavior in C++ plug-ins.
Exceptions
If a handler throws an exception it is reported in the correlator log file and then discarded.
Plug-in lifetime
If all monitors that reference a plug-in have terminated or have been removed by the engine_delete utility, then the plug-in and any event handlers that belong to the plug-in are removed from the correlator. If an event handler callback is in progress, then the delete operation blocks until the event handler has completed. At that point, references to the handler are dropped so that the plug-in can be unloaded.
C++ plug-in samples that use channels
C++ code samples that use channels in plug-ins are in the subscribe_plugin file in the apama_install_dir\samples\correlator_plugin\cpp folder.