Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Advanced CORBA Programming wit C++ - M. Henning, S. Vinoski.pdf
Скачиваний:
65
Добавлен:
24.05.2014
Размер:
5 Mб
Скачать

IT-SC book: Advanced CORBA® Programming with C++

)

{

CORBA::Boolean has_event;

CORBA::Any_var any = supplier->try_pull(has_event); if (has_event) {

CCS::TStatEvent * event_data; if (any >>= event_data) {

//Use values from the event data

//struct here (not shown).

}

}

}

The check_for_thermostat_event function takes a PullSupplier_ptr as an argument, so we pass our ProxyPullSupplier to it. Because ProxyPullSupplier is derived from PullSupplier, automatic widening occurs when we pass the supplier variable to check_for_thermostat_event. To avoid blocking our GUI event loop and preventing windowing updates, check_for_thermostat_event always performs a try_pull on the supplier. Unlike the pull method, try_pull will not block waiting for an event if none is available. After invoking try_pull, we check the value of the has_event Boolean out argument to see whether an event was actually returned. If this argument is true, we then attempt to extract a pointer to a CCS::TStatEvent struct from the returned CORBA::Any. If this succeeds, our code can access the event data via the extracted structure pointer. Otherwise, the event data is not of the type we expect, and we ignore it.

20.7 Choosing an Event Model

In Section 20.4 we define the following four event delivery models: canonical push model

canonical pull model hybrid push/pull model hybrid pull/push model

When you develop an application that uses the Event Service, you must choose the model that is most appropriate for it. Your choice is affected not only by the characteristics of these models but also by the nature of your application and by issues related to event channel implementation.

20.7.1 Event Channel Implementation

Ultimately, much of the robustness and performance of an event-based system depends on the implementation of the event channel. The OMG Event Service Specification does not define requirements for key event channel characteristics, instead leaving design choices for each event channel implementation to those who create it. Although this approach makes the specification very flexible in terms of the environments it can support, it also means that the quality of service provided by event channels varies widely.

821

IT-SC book: Advanced CORBA® Programming with C++

One key characteristic of an event channel is throughput. If your application handles high rates of event delivery, you should evaluate your event channel implementation to determine how quickly it can deliver events. If we ignore the effects of multiple suppliers and consumers, the time required for an event channel to receive an event and push it out is mostly dependent on how efficiently the underlying ORB handles the IDL any type. Different ORBs use different techniques to marshal and unmarshal the any type, and some techniques are much more efficient than others. Some ORBs are highly tuned for any handling, but others do only an adequate job in this regard. We advise you to carefully measure the efficiency of your event channel before deploying a high-volume event-based production system on it.

The number of consumers and suppliers connected to an event channel can also influence its throughput. When an event arrives, the event channel must make that event available to each consumer that is connected. Delivery to each push consumer requires a separate CORBA request invocation from the event channel to the consumer; for pull consumers, the channel must buffer the event until the consumer requests it. Also, the more suppliers that are connected, the more events there are to receive and transmit to the consumers. Unless the event channel uses proprietary multicast protocols, which some of them do, there is simply no way around this limitation.

Although we speak of suppliers and consumers as being "connected" to the event channel, we do not mean to imply that these are necessarily network connections. Because operating systems impose limits on the number of open network connections a process can have, a quality event channel implementation must be able to handle more consumers and suppliers than it has network connections. For push suppliers and pull consumers, the event channel acts as a server, and this means that it can perform an orderly shutdown of one of these clients if it wants to reuse that connection for another supplier or consumer. Such a shutdown is transparent to the client ORB, which attempts to establish a new connection when it needs to push or pull a new event. For pull suppliers and push consumers, the event channel acts as a client, so in the extreme case it can open a network connection, send the request, and then immediately close the connection. Establishing and reestablishing connections in the ways described here can be costly, so be sure that the underlying operating system can support the necessary number of connections to your event channel.

Event channel implementations vary in what they store persistently. Most of them at least remember connection information so that consumer and supplier connections can be transparently restored if the event channel is stopped and restarted. Some implementations also persistently store event data that has not yet been pushed to or pulled from particular consumers. This is especially important for pull consumers that do not pull events very frequently.

Event channel implementations also must be able to deal with suppliers and consumers that are not well behaved. A pull supplier or push consumer that crashes should not cause the event channel to hang indefinitely waiting for a response. That would prevent other suppliers and consumers from getting their events handled in a timely manner. A quality

822

IT-SC book: Advanced CORBA® Programming with C++

event channel implementation allows characteristics, such as time-outs and the number of retries, to be configured through either a configuration subsystem, environment variables, or start-up options.

20.7.2 Push Model Considerations

Suppliers usually use the push model, primarily because it allows them to avoid the buffering needed when supporting the pull model. In some sense it is also the more natural and efficient of the two models. Suppliers usually want to notify all interested parties of an event as soon as it occurs, and the push model allows them to do that. Its efficiency arises from the fact that it avoids the overhead of polling.

A push supplier need not implement any CORBA objects unless it wants to be explicitly notified when disconnection occurs. This is ideal for applications that cannot support server functionality, perhaps for licensing, deployment, or security reasons. Unlike a push supplier, however, an application hosting a push consumer must be able to act as a server and receive events as they are generated.

20.7.3 Pull Model Considerations

Because this model relies entirely on polling for event delivery, it suffers from the problem of having to buffer events. For consumers that pull events infrequently, pull suppliers whose event buffers fill up must discard events. Choosing which events to discard depends entirely on the application. Some pull suppliers might want to discard the oldest events first, whereas others might stop accepting events after their buffers have filled. Still others might keep only the first one of several events that arrive within a certain timeframe, based on the likelihood that the second and subsequent events are duplicates of the first one.

Because this model relies on polling, excessive network traffic can be a problem if pull consumers poll for events frequently. To avoid polling, a pull consumer can invoke the blocking PullSupplier::pull operation rather than use the non-blocking try_pull. This approach reduces the amount of network traffic. However, for pull suppliers that are hosted by thread-per-request servers, it can result in the creation of a large number of threads in the server to handle these requests. Moreover, if the event data are not readily available in the pull supplier, each blocking pull request will require its thread to exist until the supplier has an event, using even more application resources. If the server uses a fixed-size thread pool, this situation could result in all available threads being blocked because of pull requests.

This model does not require pull consumers to act as servers, so it is suitable for use with pure clients that consume events.

20.8 Event Service Limitations

823

IT-SC book: Advanced CORBA® Programming with C++

Using an implementation of the Event Service can off-load the complicated task of reliable event delivery with multiple consumers and suppliers, but the OMG Event Service is not without limitations. Some of these limitations are explained in the following sections.

20.8.1 Multiple Suppliers

Because multiple suppliers can connect to an event channel, consumers may end up receiving far more events than they are interested in. This is because event channels deliver all events to all consumers; each consumer receives all events from all suppliers connected to the same event channel. Fortunately, type-safe extraction of event data from the IDL any type helps prevent consumers from acting on events that were not intended for them. However, it is a waste of resources for the event channel to send all events to all consumers only to have some of them discard the event data. The event channel may have to persistently store such events before they can be delivered and then use time and network connections in performing the deliveries. The network bandwidth required to transmit the events is also wasted.

You can alleviate this problem by setting up separate event channels for each type of event so that consumers that want to receive events from multiple sources can register with multiple event channels. Minimizing the number of event suppliers connected to each channel is also helpful, especially if there is only a single supplier per channel.

20.8.2 Lack of Reliability

When you design event-based applications, it is extremely important to keep in mind that event channels are fundamentally unreliable. Their lack of reliability stems from the difficulty of providing end-to-end guaranteed delivery in a service in which the channel has no way to throttle the supplier. If a supplier pushes so many events that the event channel cannot keep up with delivering all of them to its consumers, the event channel has no choice except to drop some of the events.

20.8.3 Lack of Filtering

Even if an event channel has only a single supplier connected to it, clients may still receive events in which they have no interest. This is because event channels pass events from their suppliers to their consumers without attempting to interpret event data in any way.

If an event channel could somehow filter events for each consumer, it could avoid the costs associated with sending unwanted events. Fortunately, the OMG has adopted the Notification Service [26], which supplies not only event filtering features but also structured event types and various degrees of control over the quality of service that an event channel provides. Furthermore, its interfaces inherit from the Event Service interfaces we describe in this chapter, allowing you to introduce a Notification Service

824