Previous Table of Contents Next


2.2.1. Common Pitfalls of Developing Communication Software

Developers of communication software confront recurring challenges that are largely independent of specific application requirements. For instance, applications such as network file systems, electronic mail routers, remote login daemons, and Web servers all perform tasks related to connection establishment and service initialization, event demultiplexing and event handler dispatching, interprocess communication and shared memory management, static and dynamic component configuration, concurrency and synchronization, and persistence. Traditionally, these tasks have been implemented in an ad hoc manner using native operating system (OS) application programming interfaces (APIs)—such as the Win32 or POSIX—that are written in C.

Unfortunately, OS APIs do not represent an effective way to develop communication software. The following list details common problems associated with programming applications using OS APIs:

  Excessive low-level details. Developers must have detailed knowledge of low-level OS details, which diverts their attention from the strategic application-related semantics and structure of their programs. For instance, developers must carefully track which error codes are returned by each system call to handle OS-specific problems in their applications.
  Continuous reinvention of incompatible higher-level programming abstractions. The common remedy for the excessive level of detail with OS APIs involves defining higher-level programming abstractions. However, these abstractions are typically reinvented in an ad hoc manner by each developer or project; this hampers productivity and creates incompatible components throughout projects in large software organizations.
  High potential for errors. Low-level OS APIs are error-prone due to their lack of type-safety. For example, endpoints of communication in the Socket API are represented as untyped handles that increase the potential for subtle programming mistakes and runtime errors (Schmidt, Harrison, & Al-Shaer, 1995).
  Steep learning curve. Due to the excessive level of detail, the effort required to master OS-level APIs is very great. For instance, it is hard to learn how to program the thread cancellation mechanisms correctly in POSIX Pthreads applications.
  Inability to scale up. OS APIs define basic interfaces that do not scale up gracefully as applications grow in size and complexity. For instance, Win32 processes contain a limit of 64 thread local storage (TLS) keys, which is inadequate for large-scale application servers that utilize many DLLs and thread local objects.
  Lack of portability. Low-level OS APIs are notoriously nonportable, even across releases of the same operating system. For instance, implementations of the WinSock socket API on different versions of Windows NT possess incompatible timing-related bugs that occur sporadically when performing non-blocking connections.

It is possible to alleviate some of these problems by using higher-level distributed object computing (DOC) toolkits such as CORBA, DCOM, and Java RMI. However, this is only a partial solution, for the following reasons:

  Lack of portability. DOC toolkits are not widely portable. For instance, the Basic Object Adapter component in the CORBA 2.0 specification is woefully underspecified, which means that servers written in CORBA are not portable among ORB products from different vendors.
  Lack of features. DOC toolkits focus primarily on communication and therefore do not cover other key issues associated with developing distributed applications. For instance, DOC toolkits do not specify important aspects of high-performance and real-time distributed server development, such as shared memory, asynchronous I/O, multithreading, and synchronization (Schmidt et al., 1997).
  Lack of performance. Conventional DOC toolkits incur significant throughput and latency overhead. These overheads stem from excessive data copying, non-optimized presentation-layer conversions, internal message buffering strategies that produce non-uniform behavior for different message sizes, inefficient demultiplexing algorithms, long chains of intra-ORB virtual method calls, and lack of integration with underlying real-time OS and network QoS mechanisms.


Previous Table of Contents Next