wood burning stoves*
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes Does this guarantee a unique client? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Developer Certification (SCJD/OCMJD)
Bookmark "Does this guarantee a unique client?" Watch "Does this guarantee a unique client?" New topic
Author

Does this guarantee a unique client?

John Smith
Ranch Hand

Joined: Oct 08, 2001
Posts: 2937
If I have the following implementation of the remote interface, and the client calls getConnection() method of this class which returns another remote object, does the hashCode() of that remote object (dbImpl.HashCode()) guarantee a unique number?
Thanks,
Eugene Kononov.
Sai Prasad
Ranch Hand

Joined: Feb 25, 2002
Posts: 560
yes. But why do you like to use the hashCode()? Just curious.
John Smith
Ranch Hand

Joined: Oct 08, 2001
Posts: 2937

yes. But why do you like to use the hashCode()?

I plan to use it in the locks Collection to identify a client. What are the other alternatives?
Thanks,
Eugene.
Sai Prasad
Ranch Hand

Joined: Feb 25, 2002
Posts: 560
You could use the DBServerImpl instance itself as the key in the Collection. Let the VM takes care of comparing the hash code values.
John Smith
Ranch Hand

Joined: Oct 08, 2001
Posts: 2937

You could use the DBServerImpl instance itself as the key in the Collection.

Right. I just wanted to see a more readable value in the locks collection.
Eugene Kononov.
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17249
    
    6

The object itself guarantees a unique client.
You could have the DBServer have it's own HashSet to keep track of the locks that the client has, and let the unlock() call pass through to the Data classes unlock method only if the record number is in the DBServer's HashSet.
Not knowing your DBServer interface, i might have questions where the above isn't quite correct, and things will need to be moved to the ConnectionFactoryImpl class.
Mark


Perfect World Programming, LLC - Two Laptop Bag - Tube Organizer
How to Ask Questions the Smart Way FAQ
Sam Jason
Greenhorn

Joined: Apr 09, 2002
Posts: 6
The object itself guarantees a unique client.

Mark:
what did you mean "the object itself guarantees a unique client"? does it define a new lock method on the server side, say lock(int record, Object clientObject), and in the client side invokes lock(3, this) to lock the the third record?
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17249
    
    6

Hi fssxing, Boy do I have a lot for you
Ok well first start with the JavaRanch Naming Policy.

"Fssxing"-
Welcome to the JavaRanch! Please adjust your displayed name to meet the
JavaRanch Naming Policy.
You can change it
here.
Thanks! and welcome to the JavaRanch!

Ok now with that done, here are your answers.
First the DBServer object in Eugene's example is a Remote object, so when the client calls getConnection a new instance of it is made and used only for that one client. Hence it is unique to the client. Now I myself called the DBServer object RemoteDataAccess, but that is just symantics.(no not the virus checker software).
Second The object passes DBServer, on my submission has lock(int record) method, this passes the call to the LockManager. I suggest using a LockManager even though in my submission I didn't, but wish I had. LockManager handles all the locking for all the clients, but the DBServer keeps track of records that that client has locked, so that when you call unlock, you can check it to make sure that it has the lock in the first place.
Mark
John Smith
Ranch Hand

Joined: Oct 08, 2001
Posts: 2937
Mark Spritzler posted:

LockManager handles all the locking for all the clients, but the DBServer keeps track of records that that client has locked, so that when you call unlock, you can check it to make sure that it has the lock in the first place.

Mark,
It sounds as you suggest that I should be doing the "lock" check in two places. Is that neccessary? In my design, I do not modify the signature of the lock() (1st requirement), I do ensure that if some client calls unlock() for the record that was locked by someone else it will not have effect (2nd requirement), the client can call lock() and unlock() (3rd requirement), and my check for locks is in one place (simple design). Here is what I have:
The object bound to RMI is the ConnectionFactory:

Once the client gets a reference to it, it calls the getConnection() method that returns another remote object DBServerImpl. DBServerImpl has:

and implements all public methods of Data such as in:

The lock() method of Data uses Lock manager:

synchronized public void unlock(int record) {
RecordLockManager.unlock(record, this);
//System.out.println("unlock() called from " + this.hashCode());
}

where "this" is a unique (I hope) object for every client (because it is part of unique DBServerImpl.
Finally, my lock manager is:

public class RecordLockManager {
private static HashMap locks = new HashMap();
public static void lock(int recNum, Object client) throws InterruptedException {
synchronized(locks) {
Integer record = new Integer(recNum);
while (locks.containsKey(record))
locks.wait();
locks.put(record, client);
//System.out.println("client " + client + " locked record " + recNum);
}
}
public static void unlock(int recNum, Object client) {
synchronized(locks) {
Integer record = new Integer(recNum);
if (locks.containsKey(record) && locks.get(record) == client) {
locks.remove(new Integer(recNum));
System.out.println("client " + client + " unlocked record " + recNum);
} else {
System.out.println("****** client " + client + " tried to unlock record " + recNum);
}
locks.notifyAll();
}
}
}

This entire thing works very well, and I tested it by spawning 50 threads from my GUI each trying to modify the same record multiple times. However, I have not tested it as a client/server yet, and I am questioning my use of static methods in the LockManager and whether my LockManager will actually be on the server.
Thanks for your comments,
Eugene Kononov.
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17249
    
    6

that's true, and I did no tchang ethe signature of the lock method anywhere myself.
I also didn't use a LockManager(which I should have). In the LockManager you are passing a reference to the Connection Object, which is fine. In my submission that was not passed. I just had the Connection object have a HashSet with a set of the locks that client has. If it is in there then the client can pass the call to the Data class and unlock the record.

Mark
John Smith
Ranch Hand

Joined: Oct 08, 2001
Posts: 2937
Mark Spritzler posted:

In the LockManager you are passing a reference to the Connection Object, which is fine.

Actually, I am passing a reference to Data, which is wrapped inside the Connection Object:

It still guarantees uniqueness, does it not?
Thanks again,
Eugene Kononov.
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17249
    
    6

But you DBServer is the Connection Object, not the Data class Object, which is just a reference in the Connection Object. The Connection Object is the unique Client ID.
If you are passing the Data reference it would be the same as all the other clients. Each client does not have it's own Data Object, but a reference to the one and only instance of Data.
Does that make sense?
Mark
John Smith
Ranch Hand

Joined: Oct 08, 2001
Posts: 2937
Mark posted:

If you are passing the Data reference it would be the same as all the other clients. Each client does not have it's own Data Object, but a reference to the one and only instance of Data.

Yes, that does make sense. I am not doing it right.
Thanks again,
Eugene.
Chiji Nwankwo
Ranch Hand

Joined: Jun 21, 2002
Posts: 56
Hi Everyone,
I have read through this thread and have come across a design decision which I find a bit confusing. Why is a ConnectionFactory required to return a new DBServer type, which is unique to every client? And secondly, if every client has its own DBServer type, why do we need to handle concurrency in a lock manager? Maybe I am reading the whole thing wrong, but my understanding is that if every client has its own DBServer there will never be any contention between clients. I thought that the DBServer should be registered in the registry and every client will get a reference to the same object stored in the registry.
I hope this make some sense.
Please comment, put me straight if I am totally off point.
Regards,
Chiji


SCJP, SCJD, SCWCD<br />"Meekness is not weakness, but power under control"
John Smith
Ranch Hand

Joined: Oct 08, 2001
Posts: 2937

Maybe I am reading the whole thing wrong, but my understanding is that if every client has its own DBServer there will never be any contention between clients.

Every client has its own connection object, but all of them wrap the same instance of Data (and possible the same instance of LockManager, if you use one.). So the contention is over the Data (or, more precicely, over the records in the database).
Eugene.
Chiji Nwankwo
Ranch Hand

Joined: Jun 21, 2002
Posts: 56
Thanks for you response. I can now see the light and understand what you mean.
Assuming I had a Factory that returned DBServer objects would my DBServerImpl still need to extend UnicastRemoteObject, since I not registering the DBServer object with the rmi registry?
Thanks
Chiji
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17249
    
    6

Yes it will still extend UnicastRemoteObject.
Mark
Chiji Nwankwo
Ranch Hand

Joined: Jun 21, 2002
Posts: 56
Hi,
In my assignment I have a connection object which is unique to each connection. This connection object is made up of a clientId and a serverId. This is the code I use to create the client and server ids:

Where the client is what I refer to as a remote data client and the server is the remote object that has been created as a result of the connection made by the remote data client.
It is my aim to make the Connection object as unique as possible, which is why I am using the toString and hashCode methods. The Connection object also has its own hashCode method which adds the hashCodes of the two ids and multiplies this by some arbitrary value.
When the remote data client registers itself with the remote object, it passes its id as a paramater to the remote object.
The connection object which is returned to the client is stored on the client and passed back to the remote object when a records needs to be locked or unlocked.
I am very open to critism at this point.
Thanks
Chiji
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17249
    
    6

If your connection object is unique to each client, then just pass that object to the server when you call lock and unlock. It will handle all the hashcode stuff for you.
Mark
Charles Miller
Greenhorn

Joined: Jun 28, 2002
Posts: 19
I used the connection object in my LockManager based on the fact that each remote client gets its connection object from a connection broker and each call to the broker generates a new object, hence uniqueness.
 
It is sorta covered in the JavaRanch Style Guide.
 
subject: Does this guarantee a unique client?
 
Similar Threads
Locking/Unlocking, -- Am I Done Or I Don't Understand Requirements?
FBN: Closing the database in Network mode.
Initial design review
NX: RMI and thread safe
NX: URLy Bird 1.3.1 Connection Factory Design