aspose file tools*
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes RMI server threading? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Certification » Developer Certification (SCJD/OCMJD)
Bookmark "RMI server threading?" Watch "RMI server threading?" New topic
Author

RMI server threading?

Nicole Gustavson
Greenhorn

Joined: Jan 06, 2003
Posts: 12
Howdy y'all! What a helpful forum!
As a newbie to RMI, I was wondering if someone could help me with threading the server.
1) Given that some RMI implementations are pre-threaded, do I need to make server requests explicitly threaded?
2) With sockets & serialization, threading the server is straightforward, you can just pass the socket to the new thread and the new thread sends results to the client over the socket. But how do you do this with RMI?
For example, how would I make this method threaded?

Or am I looking at this all wrong? Any advice would be appreciated. Thank y'all!
- Nicole
Sai Prasad
Ranch Hand

Joined: Feb 25, 2002
Posts: 560
Nicole,
As you mentioned, RMI runtime spawns a thread for every request. It is not guaranteed to spawn a unique thread for a client for subsequent calls.
You probably have to make criteriaFind() thread safe. Before that you need to find a way to identify a client between calls. Search for ConnectionFactory in this forum. Hint: You will create and keep one unique remote object with public methods defined in the Data class in the server side for every client.
Nicole Gustavson
Greenhorn

Joined: Jan 06, 2003
Posts: 12
Thanks Sai. I don't think that was really the question I wanted to ask though. I wanted to ask how to actually implement the threading (i.e. make requests threaded in case the RMI server didn't do it for you), but then I learned how to do a search on this forum ( ) so finally gleaned the correct answers which are:
1) don't do it, and
2) don't do it.
I should've known that something that seems that hard is probably not a good idea.
As for keeping track of client ID's, I decided not to do that. I'm taking the lazy way out and trusting the client. I wrote it; ipso facto, it's trustworthy.
Thank you, I do appreciate your assistance and the helpful posts of others on this forum.
Peter den Haan
author
Ranch Hand

Joined: Apr 20, 2000
Posts: 3252
Originally posted by Nicole Gustavson:
As for keeping track of client ID's, I decided not to do that. I'm taking the lazy way out and trusting the client.
So what are you going to do about the javadoc for Data.unlock()?
- Peter
Nicole Gustavson
Greenhorn

Joined: Jan 06, 2003
Posts: 12
You know, Peter, that's a very good question, because the requirements and the javadoc for unlock() do state:
"If an attempt is made to unlock a record that has not been locked by this connection, then no action is be taken."
and
"Ignored if the caller does not have a current lock on the requested record."
However, my interpretation of these requirements was "if there's no lock on the record, the unlock() method just does nothing instead of throwing a RecordNotLockedException or taking some other action."
The way my client is written, there will never be an unlock() call without a corresponding lock() call. So, the only way unlock() would be called without lock() is in the case of malicious hacking. You could take the approach that guarding against malicious hacking is a requirement because of the above statements. However, to me, it just seems silly to guard against malicious hacking in an application that doesn't even have a login screen.
In response to your question, I am changing the javadoc to be more specific about the action of the unlock() method, and I am also documenting the reasons behind my decision in my design document.
Thanks for raising that very valid concern, and I welcome any further comments.
- Nicole
Peter den Haan
author
Ranch Hand

Joined: Apr 20, 2000
Posts: 3252
Originally posted by Nicole Gustavson:
However, my interpretation of these requirements was "if there's no lock on the record, the unlock() method just does nothing instead of throwing a RecordNotLockedException or taking some other action."
Still with you.
The way my client is written, there will never be an unlock() call without a corresponding lock() call. So, the only way unlock() would be called without lock() is in the case of malicious hacking. [...]
You lost me. Four remarks.
First, the javadoc documents the contract the Data class adheres to. You change the contract, so you are right in changing the javadoc and documenting your decision. Be aware though that you are essentially ignoring a requirement, so pay attention to the documentation.
Second, you are only sure that the client has been written in that way if you went through a mathematical proof that this is the case. I would submit that the complexity of the system is such that this proof is impossible. In simple terms, your client may well have bugs.
Third, how you have written the client is irrelevant anyway. Your FBN client is not the only client code for the Data class. You know this, otherwise you would have deleted the add() and delete() methods and one of the constructors on the grounds that you don't use them anyway. Another telltale sign is that the Data class isn't FBN-specific in any way. The Data class is reusable, as is hopefully the rest of your database server code, and you have no direct control over how it is used. Trusting client code to always play by the book, especially in subtler issues such as proper cleanup in exception handling, is bad practice IMHO.
Fourth, you may experience client crashes or network problems between a lock() and its corresponding unlock() call. Not tracking client identity makes recovery difficult. This is admittedly not very important, because you can easily put up a convincing argument that recovery from such situations is well outside the scope of the assignment.
- Peter
[ January 08, 2003: Message edited by: Peter den Haan ]
Nicole Gustavson
Greenhorn

Joined: Jan 06, 2003
Posts: 12
Okay Peter, you've convinced me I have to include client identification in my project, and that my original interpretation of the requirements was lacking. This is mainly because, as you say, a crashed client is an everyday occurrence that really has to be dealt with. Regardless of whether it helps me get a better score or not (I think it will), I'm glad to learn a few more things about RMI.
Now could you (or anyone else who's willing) review my proposed server design? It differs from most I have read about, so I'd appreciate any input.
public interface RemoteDataFactory extends Remote
public class RemoteDataFactoryImpl extends UnicastRemoteObject
public interface RemoteData extends Remote, Unreferenced
public class RemoteDataImpl extends UnicastRemoteObject
Clients get their own instance of RemoteData via the RemoteDataFactory.
There is a Locker class which performs locking, and synchronization of lock and unlock methods.
The Data object has an instance of the Locker class, which it delegates lock and unlock calls to.
The RemoteDataImpl delegates calls to the Data object. RemoteDataImpl maintains a list of records currently locked by this connection. The lock() method first calls Data.lock(), then adds the record to the list. The unlock() method checks this list before deciding to perform Data.unlock(). When unreferenced, RemoteDataImpl will unlock all locks in the list.
The benefits of this solution, as I see it, are:
- Data class lock and unlock methods perform as advertised, and can be reused if other non-RMI remote connection methods are implemented
- Because Data performs the locking, it is able to first check if the record is a valid one, and throw the exception mentioned in the javadocs, "@exception IOException If the record position is invalid." (Well, I actually changed it to DatabaseException, but at least it does throw an exception as advertised.)
- lock and unlock method signatures need not be changed
- Locker class is well encapsulated and has well-defined responsibility, in the sense that it is not coupled with RMI.
- Locks will be dropped if client disconnects, crashes, etc.
The disadvantage is that you are maintaining a list of locks in two different classes. However, the lists are different and serve two entirely different purposes, so I don't really think it's a duplication. Can you let me know of any other disadvantages?
I have heard others mention that locking should not fall within the responsibility of the Data class, but unfortunately, it's already in the class interface, so I don't see any harm in including an actual implementation and making the Data class do what its methods and javadocs say it does. Comments?
Another question, does RemoteDataImpl need to extend UnicastRemoteObject if it's not being registered with RMIRegistry?
Thanks so much for any feedback! It makes me better, and hopefully others will find this discussion useful.
- Nicole.
pascal auderset
Greenhorn

Joined: Aug 21, 2002
Posts: 15
Hello Nicole
I have more or less the same design ... You can read my design in the Post "Data class".
Just a question to you: Do you change the Data class to package visibility?
Pascal
Nicole Gustavson
Greenhorn

Joined: Jan 06, 2003
Posts: 12
Hi Pascal,
No, my client instantiates Data directly in local mode, so I didn't make it package visibility. I'm not worried about locking in local mode, so I didn't feel I needed to put a wrapper around Data.
Hope that answers your question.
- Nicole.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: RMI server threading?