Experiments with 50+ active users suggest a number of enhancements in the server infrastructure that are needed before we can have a "production" environment:
- Use of non-blocking i/o rather than individual threads blocking on sockets.
- Fixed thread provisioning. Currently there are as many as four active threads per client connection. This presents serious scalability limitations.
- Better support for specialized
Change behavior when executed on master replicas. This is currently done by detecting the first execution of a change, but federation (and other de-centralization approaches) may break that.
- Support for shared serialization. Serializing complex
Change objects multiple times for transmission to multiple clients is wasteful.
- Better support for outgoing queue management. Currently all
Change objects are enqueued for all active clients. The decision to actually send a Change is made by the queue based on whether or not the client has previously requested the changed object. This can waste considerable memory when the server is under load, particularly in cases where client connection termination is determined through TCP timeouts.
- A good example of where this is needed is cleanup of vector clocks in the shared text editor. This is currently done with synchronous client-side calls to
isClientAlive(...). These are slow when the server is under load, and since cleanup occurs on the first modification, appear to "lock up" the client.
- Remove remaining traces of RMI support. This will also be a good excuse to eliminate some RMI-inspired class names.
- Remove or fix incomplete ideas like brute-force search and ServerIntializedObjects. The latter could at least be generalized a bit more. (Brute-force search was eliminated in Feb 04)
- Handle concurrent access to outgoing queues without cloning. Currently, the list of outgoing data queues is cloned for each outgoing message. This is insanely inefficient.
- Messaging classes should be consolodated into a separate package and used in the both the old and new implementations. This will facilitate concurrent development, and will also allow old and new clients and servers to be used together. (Since non-blocking I/O only works with JDK 1.4+, we will probably want to maintain the current, thread-intensive server classes until 1.3 is a bit more obsolete.)
- Synchronization should be cleaned up and eliminated where possible. For example, it might be possible to hash incoming messages across queues based on object id, so that we could guarantee that each object would only be accessed by a single thread.
|