• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • Liutauras Vilda
  • Jeanne Boyarsky
  • paul wheaton
Sheriffs:
  • Ron McLeod
  • Devaka Cooray
  • Henry Wong
Saloon Keepers:
  • Tim Holloway
  • Stephan van Hulst
  • Carey Brown
  • Tim Moores
  • Mikalai Zaikin
Bartenders:
  • Frits Walraven

Does this guarantee a unique client?

 
Ranch Hand
Posts: 2937
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Ranch Hand
Posts: 560
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
yes. But why do you like to use the hashCode()? Just curious.
 
John Smith
Ranch Hand
Posts: 2937
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


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
Posts: 560
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 2937
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


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.
 
ranger
Posts: 17347
11
Mac IntelliJ IDE Spring
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
 
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 17347
11
Mac IntelliJ IDE Spring
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 2937
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 17347
11
Mac IntelliJ IDE Spring
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 2937
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 17347
11
Mac IntelliJ IDE Spring
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 2937
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Ranch Hand
Posts: 56
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
 
John Smith
Ranch Hand
Posts: 2937
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


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
Posts: 56
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 17347
11
Mac IntelliJ IDE Spring
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yes it will still extend UnicastRemoteObject.
Mark
 
Chiji Nwankwo
Ranch Hand
Posts: 56
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 17347
11
Mac IntelliJ IDE Spring
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
 
Greenhorn
Posts: 19
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Now I am super curious what sports would be like if we allowed drugs and tiny ads.
Gift giving made easy with the permaculture playing cards
https://coderanch.com/t/777758/Gift-giving-easy-permaculture-playing
reply
    Bookmark Topic Watch Topic
  • New Topic