Some of the problems of a database system can be overcome if the clients interacting with different users directly exchange information with each other. Two kinds of tools have been developed to provide high-level support for communicating information among distributed clients:
Distributed RPC (Remote Procedure Call) systems
such as Cedar [Bir84], which allow a client to invoke procedures in remote clients and distributed constraint systems such as the Mercury attribute grammar system [Kai87], which allow programmers to define constraints among the data maintained by different distributed clients.
Figure: Distributed RPC and Constraint Systems
An application programmer can implement a multiuser application using either of these systems by creating a local client for each user of the application and using RPC/constraints to communicate information among the clients (Figure 8.4). Figure 8.5 outlines the structure of the program executed by a client of an RPC system.
Figure: An RPC Client
A distributed constraint system would be used similarly except that the implementation would be defined
declaratively instead of procedurally.
These distributed tools do not suffer from the drawback of polling-- distributed RPC systems explicitly inform a client of remote changes in which it is interested (by invoking appropriate procedures in the client) and distributed constraint systems automatically update the remote states. Moreover, these systems automatically convert between internal and external representations of data, thereby relieving programmers from the task of implementing this function. Furthermore, this code does not involve relational joins and can be generated at compile time.
Finally, these systems offer the advantage of flexible sharing and communication since a client can determine which parts of its state are shared with others and when changes to it are communicated to them.
On the other hand, they do not offer several other benefits of the database approach. They do not address efficient storage of data or querying of it. Moreover, they do not know which parts of the clients' state are shared data structures
and simply provide a high-level scheme for communicating information among the clients. As a result, these systems cannot automatically offer concurrency control or access control, which have to be implemented by the clients.
These drawbacks arise because these systems were designed to enable clients to share changes to related data and not different versions of the same data. We discuss later tools such as shared object systems designed to explicitly handle the (more restricted) latter case.
Another important drawback of these tools is that
they require a client interacting with a user to be aware of the identities of the clients interacting with other users and the parts of the local state in which the remote users are interested.
As a result, the programmer of a client must write code that establishes communication with other clients and determines which part of the local state should be transmitted to the other clients. More important, this code must be tediously changed if unanticipated kinds of clients and communication patterns are desired later.
In the next section, we discuss tools that allows clients to be unaware of these details.
Implementing the example user-interface: Consider implementation of the example user-interface using an RPC system. As in the previous section, each of the clients creates the two windows displayed on its user's workstation, processes input events generated by the workstation, and generates output requests for the workstation. The clients directly communicate among themselves changes to the shared data such as the semantic state of the edit windows and the complete state of the test windows.
They are not responsible for converting the internal representation of parse trees and other shared data structures to an external representation since the RPC system automates this task.
On the other hand, they manually ensure that their users make only authorized changes to edit procedures and other shared state. Moreover, they manually implement concurrency control and querys retrieving coverage information. Finally, each of the clients is aware of the identities of its peers and the state it shares with them.
As a result, the clients must be tediously changed if, for instance, their users decide that they wish to completely share the edit windows and such sharing was not anticipated when the clients were coded.
Distributed RPC and constraint systems differ mainly in the style of programming they offer--distributed RPC systems offer procedural programming while distributed constraint systems offer declarative programming. A comparison of these two styles of programming is beyond the scope of this paper.