White Paper: CORBA Applications In GNOME


< Prev Contents Next >

CORBA For You

When introduced to CORBA and the advantages that it can bring to programs, two different reactions are common. The first common reaction is to dismiss it altogether as a buzzword or a bloat-producing phenomenon. This objection can be valid. CORBA can be misused to produced bloated software. CORBA definitely is not the silver bullet that will reduce software development and maintainance time to zero. The problem with this view is that it invalidates all the benefits of CORBA—its network transparency, programming language independence, and standardization.

On the other hand are those who take up the CORBA cause as if it were the end to all means. Some software projects have taken to exposing the C++ string classes via CORBA. This view is equally dangerous, because it is bound to make unnecessary demands on resources, and stands to add a fair amount of bloat and slowdown to the application for no good reason.

How, then, should a developer approach CORBA use in the small to medium size programs that are common in the free software world, what are the mistakes that CORBA utilizers sometimes make, and how can CORBA be used effectively in applications?

Possible Steps to Determining an Application CORBA Interface

  1. Determine Usefulness to Others.

    Your nethack client may be the most wonderful program on the face of the earth, but unless it implements functionality that many other applications can make use of, then you probably do not need to "CORBAize" it.

    Coordination with other applications is a common reason for creating a CORBA interface to a program. The GNOME panel exports its ability to hold applets via the GNOME::Panel CORBA interface, and similarly, each applet allows the panel to talk to it via the GNOME::Applet interface.

    Another common reason for creating a CORBA interface to a program is to allow control from scripts. Nethack players may very well want to be able to write perl scripts that

  2. Write it out.

    Once you understand what interface you want your application to offer to the world, codify its data types and operations into an IDL file.

  3. Genericize.

    Look at the set of operations and data types just defined, and see if any of them are specific to your implementation. If they are, try to rework the interface so that it could comfortably be implemented by other programs of the same genre. Also try to split functionality

    Take this example of a possible interface to a text editor:

    interface MyEditor {
      typedef long FileID;
      FileID open_file(in string filename);
      void close_file(in FileID fid);
      void save_file(in FileID fid);
    };
          

    This interface has no editor-specific functionality; it could just as well be called the ``FileManipulator'' interface and be used by a spreadsheet.

  4. Normalize.

    Often people will create an interface that contains implicit objects. In the above ``MyEditor'' example, the ``FileID'' data type is acting as an object handle, even though it is just an integer.

    Given this information, we could rework the ``MyEditor'' interface to come up with the following IDL:

    interface ManipulatedFile {
      void close();
      void save();
    };
    interface FileManipulator {
      ManipulatedFile
       open_file(in string filename);
      ManipulatedFile new_file();
    };
          

    This process may be viewed as similar to the process of normalizing relational databases.

  5. Optimize.

    Have others review your design. Use your knowledge of how CORBA is implemented, your good judgment as a software developer, and the information below to improve on your original design. Look at the existing GNOME CORBA interfaces, and see if using one of them would be more advantageous.

Common CORBA Mistakes
Confusing CORBA with program-local object systems. A useful analogy here would be ``Store strings inside string objects provided by the programming languages. Consider allowing access to catalogues of guitar strings via CORBA objects.'' For single-language objects that do not hold data that specifically needs to be accessed from other programs, CORBA object servers hold no advantage over traditional object implementations in shared libraries. For data that of and by itself can be useful to other programs, CORBA object servers are a good way of making this availability happen.

Confusion implementing with sub-classing. The common method of providing a new implementation of a given programming language object is to subclass that object and write new routines to override the inherited operation implementations. CORBA inheritance is for interfaces only.

Sub-classing an object just to denote a new implementation makes for a confusing class hierarchy. It also introduces the possible problem of handling implementation-specific extensions, which counteract the whole idea of having a generic interface.

Providing a new implementation of an existing interface does not require inheritance on the CORBA level. The flip side of this, of course, is that implementation inheritance in CORBA is not standardized, normally requiring the object implementor to re-implement all the operations on an object.

Confusing CORBA operation invocations with function calls. They look like normal function calls. They act like normal function calls. Beware! They often are much slower than normal function calls. If you find your application doing a tight loop with a CORBA operation on data elements, instead try modeling your data structures so that one operation invocation can process all the data. Remember, it can take as long to perform thousand loop iterations of a local function call as it can to perform a single operation invocation on a remote object.

Utilizing CORBA Effectively
Keep interface exposition at a high level. Not only does exposing low-level interfaces cause increased dependence upon the internal organization of a software system, but it also means you have to put more code into exporting your interfaces, introducing the risk for more bugs and increasing bloat.

Take advantage of the ``object by value'' concept. The basic premise of the ``object by value'' concept is to transport the data to the program where it is needed and perform data manipulations there. For example, instead of a spreadsheet client making repeated calls on a remote spreadsheet object to have it change the colors of cells, the object-by-value approach would be for the client to request all relevant spreadsheet data in an agreed-upon format (such as XML), manipulate that data, and send it back to the spreadsheet object server. The CORBA 2.3 specification includes a built-in ``value'' type to make using OBV much easier.

Use 'oneway' operations if you can. This is one of the few tips that can greatly increase the speed of some CORBA operation invocations without any real cost. For CORBA operations that do not return any values and do not raise any exceptions, specifying the 'oneway' keyword in the IDL declaration will mean the ORB will not have to await a reply from the remote end before returning control to the calling program. Given the high latency of network links (relative to that of a intra-process function call), 'oneway' operations can increase speed dramatically in a good ORB.

Mix other IPC mechanisms as appropriate. CORBA is not the ultimate IPC mechanism. For programs that need to share large amounts of data efficiently, shared memory systems (system-local or network-wide) can be much more efficient. Real-time synchronization can often better be accomplished via semaphores and message queues. A good example is the GNU Image Manipulation Program, which controls plug-ins via pipes, but shares the actual image data via shared memory. (In the future the GIMP may switch to using CORBA for plug-in control, but image data will still be exported via shared memory).


< Prev Contents Next >