Colab [Stef87] offers an approach to implementing multiuser applications that combines features of the three previous tools. Like a database system, it supports the notion of data that can be shared by multiple clients and replicated on multiple sites. However, unlike the former, it knows about the clients sharing the data and replicates the data in the address spaces of these clients. Like a distributed system, it provides mechanisms to automatically notify a client of remote changes to the shared state stored in its address space. Moreover, like a message server, it allows a client to be unaware of the identities of the other clients sharing data with it.
In Colab, the clients interacting with the users of a multiuser application execute the same application program. Colab offers a programmer the abstraction of an association to implement the application program. An association is an object declared in an application program whose state can be shared among the clients executing the program. In each one of these clients, a representation of the object called an associate is created. An association can define special methods called broadcast methods that are invoked on all of its associates (Figure 8.8). An application program can ensure that a particular part of the state of an association is shared by declaring methods that change that part as broadcast methods. Figure 8.9 shows the structure of an application program executed by a Colab client.
Figure: Colab Associates. Input entered by user A invokes a broadcast method in both associates. Each broadcast method invokes a local method to display the output to its user.
Figure: A Colab Client
Implementing the example user interface: The example is implemented using Colab by writing a single Colab program, which is executed by clients interacting with both users. The program consists of a set of Colab objects, which encapsulate both semantic state such as procedures and user-interface state such as scrollbar positions. Methods that change shared state such as scrollbars of test windows are made broadcast methods.
Colab combines benefits of all three tools described above.
By replicating the clients, it allows users to view the output of their clients without encountering network delays. Moreover, it does not suffer from the drawback of polling since methods are explicitly invoked in clients to inform them of changes to shared state. In addition, it is built on top of an RPC mechanism and thus allows programmers to define a single representation of objects and automatically converts between this representation and the network representation. Finally, it requires application programmers to be aware of very few details of sharing since they are responsible only for specifying which methods in the original single-user program are broadcast methods. Colab takes care of the details of starting and terminating clients at the workstations of users and broadcasting messages to them.
Colab also has its drawbacks. The task of selecting broadcast method can be non-trivial since the programmers must carefully identify which methods modify the shared state and ensure that a broadcast method invoked in a client does not invoke other broadcast methods.
Programmers who have used Colab report that this task was simple for the applications they developed [Stef87]. However, Colab applications support sharing of (almost) the complete state of the clients executing a Colab multiuser program. It is not clear if this task would be as simple if less sharing was to be supported.
Moreover, Colab fixes the sharing among the different clients at compile time. As a result, it does not allow, for instance, the two users of the example application to couple the scrollbars of their edit windows while modifying shared procedures and later uncouple them while modifying private procedures. It also does not support the notion of a ``multicast method''-- a method invoked in a subset of the clients executing the multiuser program. Thus, it does not allow the two users of the example application to share the scrollbars of their test windows without requiring the other users to also do so. Furthermore, it does not support the concept of user-controlled transactions-- remote invocations of a broadcast method occur as soon as the local invocation occurs.
Thus, the Colab example implementation above does not exactly implement the example user-interface of Figure 8.1, since the user-interface requires that changes made by users to private procedures be made immediately on their screens but at commitment time on the screens of other users. Colab also has the drawback of the replicated window architecture discussed later.
Finally, it also does not offer concurrency control or access control, which have to implemented by application programmers.
Some of the these drawbacks arise because Colab was designed to support only WYSIWIS interaction. Colab programmers found that in these applications the communication overhead is so high that it may not be possible to add concurrency control overhead without making the response times of the applications unacceptable. Moreover, Colab users found that in these applications, it is less useful to implement concurrency control since each user is aware of all the actions of the other users and can immediately take corrective actions in response to conflicts [Stef87]. We discuss below tools explicitly designed to support looser collaboration and concurrency control.
None of the tools discussed so far is bound to any single-user tool. This can be considered an advantage since the collaborative applications they support are free to use the single-user tools that best support their interaction functions. For instance, a Colab application is free to choose a window system, a toolkit, or a UIMS to process its input and display its output. Nonetheless, much of the recent work in multiuser tools has focussed on
developing multiuser tools that are extensions of existing single-user tools and allow sharing of the state maintained by their basis.
There are two main reasons for taking this approach:
Other approaches such as the Colab approach (which allow sharing of only the client data) either do not allow sharing of this state (if the state is inaccessible to the client) or require that the client become more interaction aware by loading this state into its data structures.
In [Dew93b] we give general principles of designing a multiuser tool using this approach. In the remainder of the paper, we discuss and compare specific multiuser tools that have been developed using this approach.