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

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

CORBA does not have a built-in mechanism that lets a server detect when a client loses interest in an object. In particular, CORBA does not provide automatic distributed garbage collection. If you require such a mechanism, you must implement it yourself (we discuss some options for doing this in Chapter 12).

18.8 Pitfalls in the Naming Service

Following are some pitfalls you may encounter when using the Naming Service. You should avoid these snares because they compromise portability. (Different implementations of the Naming Service may have different behavior.)

Nil references As mentioned on page 787, the OMG Naming Service permits you to advertise a nil reference even though it is rather pointless. You should make it a habit never to advertise nil references. However, you cannot rely on other developers exercising the same diligence, so when you resolve a name, it is good practice to test whether the reference returned by resolve is nil.

Transient references You should advertise only persistent references in the Naming Service. If you advertise transient references and your server shuts down, the bindings created by the server will dangle and make life difficult for clients.

Unusual names The Naming Service specification places no restrictions on the characters that can be contained in a name component, and it even permits the empty string as a legal value of the id and kind fields. Despite this, you should restrict yourself to simple names composed of printable characters and should avoid metacharacters such as "*," "?,""/," "," and "'" because some implementations have problems handling such characters correctly. In addition, if you avoid metacharacters it is easier to use command-line tools to administer the service.

Orphaned contexts Take care when destroying a context. You must both destroy the context and unbind it from its parent context. Failure to destroy the context leaves an orphaned context, and failure to unbind the context leaves a dangling binding. Be careful to use the correct name for rebind, and avoid using rebind_context.

Iterator pileup If you iterate over a naming context, make sure that you call destroy when you are finished with the iterator. This practice makes life easier for the server because you are not tying up server-side resources for longer than necessary. If you create an iterator, use it promptly. This minimizes the likelihood of having your iterator destroyed if the server encounters a resource shortage.

Iterator lifetime Although the specification does not require this, most implementations of the Naming Service are likely to use a POA with the TRANSIENT policy for iterators. This means that you cannot expect iterator references to survive shut-down of the Naming Service.

699

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

Implementation limits Many implementations of the Naming Service have restrictions on the length of a name component or the number of bindings per context. If you expect to be able to store a name component containing a 1MB id field, you may well stretch the implementation beyond its design limits. Similarly, if you create a million bindings in the same context, you may exceed an implementation limit or end up with very poor performance.

Another aspect worth examining is the scalability of the service. Some implementations give very good performance even if you have millions of bindings stored in the service, whereas others bog down and perform poorly when there are more than a few thousand bindings. If you need your Naming Service to store large numbers of references, inquire with the vendor to see whether the implementation meets your needs.

Intervendor federation If you federate Naming Services from different vendors, you must check that all services can store all the names you use. If one vendor places limits on the characters that may occur in a name component or on the maximum length of a component, you may encounter interoperability problems between the implementations.

18.9 The Names Library

The OMG Naming Service specification also describes a Names Library. The interface to the Names Library (expressed in pseudo-IDL) allows you to treat names as programming language objects. However, name objects are implemented as library code and cannot be sent over the wire, so their use is limited to the local address space.

The Names Library adds almost no value to the functionality of the basic Naming Service IDL, so we do not show its use (see [21] for the complete definition). Also, not all vendors provide an implementation of the Names Library, so you should probably avoid using it.[7]

[7]The revised Naming Service will most likely drop the Names Library.

18.10Naming Service Tools

Vendors usually provide a number of tools with their Naming Service. Typically, these tools include one or more clients that allow you to manipulate the naming graph from the command line. Such tools are useful for system administration and for use in installation scripts. Some vendors also provide tools that allow you to locate and rebind orphaned contexts and to detect dangling bindings. In addition, some vendors provide a tool that allows you to manipulate a naming graph via a graphical user interface that is similar to a file manager.

Naming Service tools are not required or specified by CORBA, so we do not cover them here. However, you should take a close look at the level of tool support if you decide to buy a Naming Service. As is typical for infrastructure software, the tools provided by your vendor can be as important as the infrastructure itself.

700

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

18.11 What to Advertise

Clearly, the Naming Service allows you advertise your application objects. The question is, which objects should you advertise? For example, for the climate control system you could simply advertise the controller object, or you could also choose to create a binding for each thermometer and thermostat. Either approach can be useful, and each has its advantages and disadvantages.

Advertising only the controller has the advantage of simplicity—there is less code to write. In addition, if the CCS server never talks to the Naming Service, performance will be better.

Advertising all devices in the Naming Service has the advantage that you need not provide collection manager operations, such as list and find. On the other hand, if you implement these operations yourself, they will likely be faster than the Naming Service because clients must communicate only with the CCS server instead of having to contact two servers. In addition, you can use efficient data structures for the implementation of list and find to make these operations very fast. However, the list and find operations are non-standard, whereas you can assume that all CORBA clients will be familiar with the Naming Service.

If you advertise all thermometers and thermostats in the Naming Service, you have a convenient way for clients to locate devices via a standard interface. If you have a very large number of devices, you can take advantage of a hierarchical context structure to provide various namespaces for different devices. If you require such a hierarchical arrangement, the Naming Service is probably a better choice than writing custom collection manager operations yourself. The additional development effort is rarely worth it.

The major drawback of advertising everything is the potential maintenance problem. If the CCS server crashes at the wrong moment, it may leave a binding to an already destroyed device in the Naming Service. Conversely, if the Naming Service crashes, the CCS server can no longer create or remove bindings. In that case, it is probably best for the CCS server to deny service; it should not allow clients to create or destroy devices until the Naming Service becomes available again. (Otherwise, any inconsistencies between which devices exist and which devices are advertised will become worse.)

Which option you choose for your applications depends on your requirements. Clearly, you can achieve the best reliability and performance by using the Naming Service as little as possible. Against this, you must consider the cost of providing equivalent functionality yourself.

Most applications advertise only a few key objects in the Naming Service and use customized collection manager operations (such as find) for other application objects. This design minimizes dependence on the Naming Service and avoids the problems that can be caused by dangling bindings, and that in turn simplifies error recovery.

701

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

One way to deal with dangling bindings is to write your clients so that they unbind dangling references. When a client receives an object reference from the service, it invokes a ping operation on the object (see page 255). If the operation raises OBJECT_NOT_EXIST, the client removes the binding. You can also periodically ping objects that are bound into the Naming Service by using a separate client program written especially for that purpose (some vendors provide a tool that does this).

As almost always in distributed systems design, there are no hard and fast rules, only guidelines. Ultimately, you must make your own decision depending on your requirements.

18.12 When to Advertise

Exactly when to add and remove advertisements for your objects again depends on which objects you advertise. If you advertise only a few key objects, it is typically easiest to do it once only during installation and configuration of your software. For added safety, you can also provide a simple tool that re-creates the bindings for an installed application, thereby enabling recovery from corruption of or loss of the Naming Service.

If you advertise all your objects, it is typically best to link the creation and removal of bindings to the life cycle operations for the objects. For example, in the climate control system, the factories for thermometers and thermostats can also take care of advertising each object in the Naming Service, and the remove operation can call unbind to ensure that the name for an object disappears from the Naming Service when the object is destroyed. However, if you care about robustness, this approach also requires an errorhandling strategy to deal with a non-functional Naming Service. (Typically, it is easiest to raise an exception and deny service if a factory or remove operation cannot reach the Naming Service.)

18.13 Federated Naming

Each binding in the Naming Service is provided by an IOR, so you can easily create a federated service. A federated service provides a single logical service to clients but consists of a number of physical servers, possibly in different remote locations. Federated services offer a number of advantages.

Each server in a federation provides a subset of the complete graph. This arrangement improves reliability because if a single server fails, only bindings in the failed server become inaccessible. The portions of the graph maintained by other servers in the federation are still visible to clients.

Servers in a federation share the processing load of the logical service. This improves performance because different servers can work in parallel to resolve bindings on behalf of different clients.

702

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

Federated servers spread the persistent storage for the graph over a number of machines, and that improves scalability.

Federation of a service permits you to maintain distinct administrative domains while still providing a single logical service. For example, all the names for objects in each part of an organization can be stored locally in each organization's Naming Service, but the names for objects in all parts of the organization are visible to clients.

To federate servers, you must get a reference to the initial naming context of one server across to another server. The question is, how do you achieve this? If the two servers are in different administrative domains and if no references exist from one domain into other, you cannot use a remote CORBA call to copy a reference from one domain into the other. The answer is that at least once, you must copy a stringified reference for an initial naming context across domains by out-of-band means, such as e-mail. After you have created the first binding from one Naming Service to another, further references become available across domains via the now federated Naming Service.[8]

[8] The revised Naming Service will allow you to configure one ORB domain to access another domain's Naming Service without the need to exchange stringified references. Instead, knowledge of a machine name in the target domain will be sufficient.

18.13.1 Fully Connected Federation Structure

Figure 18.8 shows one way to provide a federated Naming Service. Assume that our famous Acme Corporation has branches in three states: California, Colorado, and Massachusetts. Each branch runs its own Naming Service, but clients want uniform names for all Acme objects regardless of their location.

Figure 18.8 Fully connected federation structure with uniform names.

With the configuration in Figure 18.8, each server's initial naming context contains a binding named with that server's location. In addition, each server contains bindings to its

703

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

neighbors that are labeled with the neighbors' locations. The net effect is that the same name denotes the same object, regardless of which initial naming context is used.

Such a fully connected federation structure has the advantage that it provides uniform names to all clients. The major drawback is that it is difficult to administer: every time you add a new server, you must update all other servers in the federation. If there are more than five or so servers, maintenance becomes difficult because the number of crosslinks at the top level grows as O(n2).

18.13.2 Hierarchical Federation Structure

An alternative to a fully connected federation is to put servers into a hierarchical structure, as shown in Figure 18.9. A hierarchical structure is easier to maintain because you need to add only two bindings when you add a new server to the federation regardless of how many servers already exist in the federation.

Figure 18.9 Hierarchical naming structure.

In such a hierarchical structure, clients can still use the same name to denote the same object everywhere. However, clients must resolve names via the initial naming context of the root server and not via the initial naming context of their local server. This requirement can create a scalability problem because in a large federation, the root server can become a performance bottleneck. Hierarchical structures are also less resilient to failure than fully connected structures: if the root server fails, clients can no longer resolve names.

There is also the question of how clients get the initial naming context of the root server. In Figure 18.9, we have added parent bindings to the initial naming context of each

704

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

regional server. Clients can use this binding to locate the root and then use root-relative names for all objects.

Despite their slightly worse reliability and performance, hierarchical federation structures are used more often than fully connected structures. In part, this stems from the fact that hierarchical structures do not suffer the maintenance problems of fully connected structures. In addition, many real-world naming systems are naturally hierarchical.

Telephone numbers are a classic example of hierarchical naming. You can model naming in such a hierarchy by installing naming servers at each level of the hierarchy, as shown in Figure 18.10. We show a path through the hierarchy corresponding to the number 1-999-123-4567.

Figure 18.10 Hierarchical structure modeling telephone exchanges.

In such a structure, each server's initial naming context also contains a parent binding up to the initial naming context of the next-higher server. We use doubleheaded arrows to show these bindings in Figure 18.10. In the downward direction, each binding is labeled with a number, whereas in the upward direction, each binding has the label parent.

When a subscriber dials a local number, the client uses the initial naming context of its local server to resolve it. If the number is not local, the client navigates via the parent bindings up to the server at the appropriate level and then uses the initial naming context of that server to resolve the number. The advantage of this arrangement is that local calls cause activity only in local servers, and only non-local calls involve servers higher up in the hierarchy. This improves both performance and fault tolerance. Servers at higher levels in the hierarchy are less likely to form a performance bottleneck, and failure of a high-level server does not prevent resolving of bindings for local calls.

18.13.3 Hybrid Structures

There is nothing to prevent you from arranging federated servers into topologies other than fully connected or tree structures. In fact, any arrangement of servers is allowed (you even can include loops in the federation structure). This flexibility is a major advantage

705