This week's book giveaway is in the OCPJP forum. We're giving away four copies of OCA/OCP Java SE 7 Programmer I & II Study Guide and have Kathy Sierra & Bert Bates on-line! See this thread for details.
Woo Hoo! I've never used wait() and notifyAll() before and I'm pretty pleased. Lemme talk about this.
Major design considerations:
I chose Sockets over RMI because I am familiar with them. Also because my locking mechanism depends on the ability to easily know when the client rudely disconnects and I don't know if you can do that with RMI.
I chose to have the client lock and unlock.
Instead of WeakReferences I manage the locks in two places. Once on the very low level; ties rows with cookies. The thread managing the socket on the server also keeps track of every lock requested by the client.
If the DB interface allowed me to pass a client identifier with the lock() method call, then I would not have to manage the locks in two places.
my Data class implements the DB interface that requires long lock(int row) and void unlock(int row, long cookie)
I wrote a LockManager class that doesn't use weak references, but it has its own lock and unlock methods. This just takes some of the work out of the Data class.
In other words, Data.lock validates the row number and then calls LockManager.lock. Ditto for the unlock.
My biggest mistake was to synchronize both the Data.lock and LockManager.lock methods. It was like having a double layer, and the wait() and notify() only handle one layer. Once I removed synchronized from Data.lock everything ran smoothly. And synchronously, I might add.
When the server receives a lock request from the client, it stores the record/cookie in a map, and passes the lock request to the database.
When the server receives an unlock request from the client, it passes the unlock request to the database, and removes it from the map.
When the client dies, the server will know, and automatically unlock all its records.
I'm also passing the cookie to the client, which might seem like overhead, but actually helps keep the application transparent. It will make things easier when I need to write the abstraction where the client goes single-access.
Pretty exciting. Four days ago I had no clue how to do it. Thanks to everyone for your help! [ June 26, 2004: Message edited by: Robert Konigsberg ]
Originally posted by Robert Konigsberg: I chose Sockets over RMI because I am familiar with them. Also because my locking mechanism depends on the ability to easily know when the client rudely disconnects and I don't know if you can do that with RMI.
Yes, you can get notification that a client has rudely disconnected, however it is not an instantaneous notification - you can get the notification after the distributed garbage collector (DGC) runs after the lease on the RMI connection expires (by default this means you could be waiting 20 minutes for notification).
To do this, you need one RMI connection per client (not one connection for all clients). So you need some sort of RMI connection factory.
I know ... this is all a bit off topic for you, but just thought you might like to know.
No I appreciate knowing that. At least that means I can consider it next time.
In addition, I did find some interesting test cases that needed to be fleshed out. Such as:
1. Client A locks row 1. Before unlocking row 1, Client A locks row 1 again. Won't happen often, but if you accidentally forget to unlock... so I disallow that on the server side (ie not database) 2. Client A has lock on row 1. Clients B and C are waiting for row 2. Client B, disconnects prior to getting the lock. 3. On the lower database level there were some other tests. Can I include code which I am not submitting that relates to running my test cases?
author and jackaroo
Originally posted by Robert Konigsberg: No I appreciate knowing that. At least that means I can consider it next time.
"Next time"? How many times do you plan to do this assignment?
Originally posted by Robert Konigsberg: Can I include code which I am not submitting that relates to running my test cases?
You can, but there is not much point (IMHO). Your instructions probably tell you that you will not get extra credit for anything outside the requirements. (Worse, there is always the possibility that if you submit your tests, the examiner might spot an area you didnt test and pay extra attention to it).
Joined: Jun 23, 2004
Originally posted by Andrew Monkhouse: Hi Robert, You can, but there is not much point (IMHO). Your instructions probably tell you that you will not get extra credit for anything outside the requirements. (Worse, there is always the possibility that if you submit your tests, the examiner might spot an area you didnt test and pay extra attention to it). Regards, Andrew
What I mean is, on this list. I was hoping that one of my specific test functions would be useful for other people is all.
As for RMI, what I meant by next time was "next time I build a network server".
author and jackaroo