Optimize Network Round-Trips

A common problem in designing distributed applications is an excessive number of network round-trips between components on different machines. On the Internet, each of these round-trips incurs a delay of typically 1 second, often significantly more. Even over a fast local network, round-trip times are typically measured in milliseconds—orders of magnitude above the cost of local operations.

A common technique for reducing the number of network round trips is to bundle multiple method calls into a single method invocation (batching or boxcarring). DCOM uses this technique extensively for tasks such as connecting to an object or creating a new object and querying its functionality (see section 0). The disadvantage of this technique for general components is that the programming model changes significantly between the local and the remote case.

Example: A database component provides a method for enumerating the results of a query either row by row or several rows at a time. In the local case, a developer can simply use this method to add the rows one by one to a list box. In the remote case, this approach would incur a network round trip for each row enumerated. Using the method in a batched fashion requires the developer to allocate a buffer large enough to hold all the rows in the query and retrieve them in one call, then adding them to the list box one by one. Because the programming model has changed significantly, the developer has to make design compromises so the application will work efficiently in a distributed environment.

DCOM makes it easy for component designers to perform batching without requiring the clients to use a batching-style API. DCOM's marshaling mechanism lets the component inject code on the client side, called a "proxy object," that can intercept multiple method calls and bundle them into a single remote procedure call:

Example: The developer of the previous example continues to enumerate the methods one by one, since that is the way the application's logic requires it. (The list box API requires this.) However, the first call for enumerating the query result arrives in the application-specific proxy object, which retrieves all the rows (or a reasonable "batch" of rows) and caches them in the proxy object. Subsequent calls then come from this cache without additional network round trips. The developer continues with a simple programming model, yet the overall application is optimized.

Figure 10 - The component model: Client-side caching

DCOM also allows efficient referrals from one component to the other. If a component holds a reference to another component on a separate machine, it can pass this reference to a client running on a third machine (refer the client to another component running on another machine). When the client uses this reference, it communicates directly with the second component. DCOM short-circuits these references and lets the original component and machine get out of the picture entirely. This enables custom directory services that can return references to a wide range of remote components:

Example 1: A chess application can allow players who are waiting for a partner to register themselves with a chess directory service. Other players can browse or query the list of waiting players. When a player chooses a partner, the chess directory service returns a reference to the partner's client component. DCOM automatically connects the two players; the directory service is not involved in any further transactions.

Example 2: A "broker" component keeps track of a pool of 20 server machines running identical components. It measures the current load on the servers and detects when servers are added or removed. When a client needs a component, it connects to the "broker" component, which returns a reference to a component on the server with the lowest load. DCOM automatically connects the client to the server; the "broker" component then gets completely out of the way.

Figure 11 - Referral

If necessary, DCOM even allows components to plug in arbitrary custom protocols that use means outside of the DCOM mechanism. The component can use custom marshaling to inject an arbitrary proxy object into the client process, which can then use any arbitrary protocol to talk back to the component.

Example 1: A server-side component might be using an ODBC connection to talk to an SQL Server database. When a client retrieves this object, it may be more efficient to have the client machine communicate directly with the SQL Server™ database (using ODBC) instead of using DCOM to communicate with the server machine, which in turn communicates with the SQL Server database. With DCOM's custom marshaling, the database component can basically copy itself onto the client machine and connect itself to the SQL Server without the client ever noticing that it is connected not to the database component on the server anymore, but to a local copy of the same database component.

Example 2: A trading system needs two kinds of communication mechanisms: a secure, authenticated channel from clients to a central system, which is used for placing and revoking orders, and a distribution channel, which disseminates order information simultaneously to all connected clients. While the client/server channel is handled efficiently and easily using today's DCOM secure and synchronous connections, the broadcast channel might require a more sophisticated mechanism using multicast technologies to accommodate large numbers of listeners. DCOM allows this custom protocol ("reliable broadcast") to be plugged seamlessly into the application architecture: a data sink component can encapsulate this protocol and make it completely transparent to both client and server. For small installations with few users, standard DCOM point-to-point protocols can be used, while larger customer sites would use the sophisticated custom broadcast protocol. If DCOM provides a standard multicast transport in the future, the application can migrate seamlessly to the new protocol.

Figure 12 - Replacing DCOM with custom protocols

DCOM provides a multitude of ways to "tweak" the actual network protocol and network traffic without changing the way that clients perceive the component: client-side caching, referrals and replacing the network transport when necessary are but a few techniques that are possible.