Following is a model of what I am considering as my solution. Please comment at will. 1. Two interfaces of note. DataAccess which defines all the public methods of the Data class and each method throws Exceptions. RemoteDataAccess which extends java.rmi.Remote and the previously mentioned DataAccess. All methods of RemoteDataAccess will throw java.rmi.RemoteExceptions. 2. For the server there will be a ConnectionFactory object which gets bound to the registry. This only has one method that is called getConnection() which returns a DataAccess object. In the actual getConnection method I would use a statement something like: RemoteDataAccess accessObject = new RemoteDataServer(), and RemoteDataServer will extend UnicastRemoteObject while implementing RemoteDataAccess interface. Since RemoteDataAccess extends DataAccess this object can be returned from getConnection just fine. 3. Data can implement DataAccess directly for local mode. 4. For remote mode Client must look up the ConnectionFactory and do as previously described. 5. ConnectionFactory also has one instance of the Data class which is farmed out as a reference into the Constructor of each RemoteDataServer instance created and returned to the connecting Clients. 6. RemoteDataServer will wrap the functionality of the Data class (which it attained in as a reference during creation in the constructor remember) to allow for controlling access via multiple Clients, a.k.a. threads. 7. Data can directly implement DataAccess and function all alone since it doesn't have to control concurrency in local mode. 8. Data will contain an instance of a LockManager which will be used by the lock and unlock methods specified in the Data class. The LockManager will keep track of which records have been locked, but will not care who they were locked by. The connecting Client, represented by an instance of RemoteDataServer, will maintain a collection of which records it has locked. So far I have one major concern here, please offer comments. Let us say that Client A connects remotely. He locks record 1 and performs an starts operations. Before he can call unlock on record 1 he crashes, gets disconnected, or what have you and never gets to call unlock! So what happens now? Record 1 is locked with nobody out there to call unlock...any ideas for cleanup? I mean at this point we still have record 1 locked in the LockManager, and if someone tries a lock(-1) to shut down the database it will never succeed as record 1 no longer has a client to call unlock on him(or her). Or can I assume for the scope of this assignment my Client won't loose connection? Thanks Everyone! (P.S., please be brutal!)
Joined: Jan 11, 2001
One thing I forgot to mention. If I am thinking of all this correctly then the RemoteDataServer mentioned above will also implement Runnable and be placed in a Thread which is started just before it is returned by the getConnection method of the ConnectionFactory. Then, the only "tie" to the server the client has is in the thread on the server side. Okay, tear into it. Thanks, Jason
Well look into the Unreferenced interface for you problem with client A locking record 1. Can you justify your modifications to the data class. In local mode, won't it call lock and unlock, based on what you have? What will it do? Otherwise the model is basically exactly what I had, except for the LockManager, which I wish I had had. Mark
Mark, Which interface do you think is referenced ... you totally lost me on that one. I think the only interfaces I mentioned were Remote, DataAccess, RemoteDataAccess and Runnable, and I am using each of the four. Unless I misunderstood your comment. Modifications to Data class include giving it a LockManager to be used with the lock and unlock methods. However, Data will not call its own lock and unlock methods. Data will remain for only local access. The RemoteDataServer will serve as a wrapper around the data class and call its lock and unlock methods before accessing it. Does that explain any better?
If I am thinking of all this correctly then the RemoteDataServer mentioned above will also implement Runnable and be placed in a Thread which is started just before it is returned by the getConnection method of the ConnectionFactory.
I really wondering how do you implement that? what do you want the run() method do in the new thread? and what's the new thread's lifespan? Could you please put some code here? Is it the typical approach to have multiple threads to service the clients? Hope Mark could make some comments. Thanks in advance - James