Hi, This question concerns specifying a unique client identifier "the hard way." At least, a harder way for me, since I don't understand the basics of RMI enough to handle this concept. In this example, for clarity, we will not even use a ConnectionFactory. We will use raw client code like this:
I have seen it written here that Data as given to the client as a remote object can be used to uniquely identify that client to the server. Is this the basic coding idea (although I don't understand it yet)?
The basic major part I don't understand, is how is it guaranteed that the client's line of code:
ensures that a unique instance of data was created on the server side for this one line of client code? For it was my impression that the underlying Sun provided server can instantiate one or more Data objects on the server at its pleasure, and can multithread any given instance of Data that is on the server, and how many Data's there are on the server and whether any particular instance of Data is multi-threaded is transparent to us as server-side developers (thus, we need to make sure Data is thread safe). Thanks, Javini Javono
I think you are setting traps for yourself, Javini, and while you are aware of it, you still somehow fall the victim of those traps. Bind a connection factory to the registry, look it up, and get the actual connection from the factory. That will get you a nice looking certification.
Hi Eugene, and thanks for your response: Bind a connection factory to the registry, look it up, and get the actual connection from the factory. That will get you a nice looking certification.
I do not fully understand the mechanics of this, although I certainly believe that what you say is true. So I will get out my toy server and experiment. But here may I present an outline of my understanding of what you are proposing: 1. There will be at least two remote objects: "ConnectionFactory" and "Data". That is, we know "Data" will be a remote object in this design, and when you say "bind a connection factory" that essentially implies that "ConnectionFactory" will also be a remote object. 2. Remote object "ConnectionFactory" will return the client a reference to remote object "Data". 3. And, the part I don't understand quite yet, "Data" will at the same time be unique among all clients when it is passed in as an argument. Or, if not "Data" itself, then some other important object can be had that will function as a unique client identifier. Also, I take it that the RMI binding or re-binding of "ConnectionFactory" and "Data" only occurs once; and, this is done by the server sub-application. "look it up" you write; so clearly the client looks up the "ConnectionFactory". "and get the actual connection from the factory": here you mean, get "Data", which is a remote object? "That will get you a nice looking certification." This part I don't see yet. We'll start on the server side:
Our design goals, are to give the server something unique about the client. Furthermore, this uniqueClientObject will be an object reference, such that when the client dies, this object reference dies with it, and thus we can tie this into weak references, a WeakHashMap (to be used for record locking), and finally, when the uniqueClientObject dies (i.e., the reference vanishes because the client died), if the client had locked a record, then automatically the record will, after a delay in time of some amount, be unlocked. If I'm not mistaken, don't we know that Data must be offered as a remote object from the server? Even if we decide that the ConnectionFactor will supply the method to the client. So, the client looks like this:
But, this is the code I previously posted, or at least very similar. So, what are some of the concepts: 1. We know that for every client we want a uniquely bound remote Data object. This is the trick I'm not sure how to do.
2. That way, for every client there is a unique DataImpl object on the server which implements Unreferenced (or whatever the exact interface is called). Thus, for each client, when that client's DataImpl is unreferenced, we receive a signal that our client has died. 3. Now, how all this ties into weak references, WeakHashMaps, and unlocking a record from a dead client, I'm not sure yet, nor is this under discussion right at this time, but this is the ultimate goal. So, let's take a look at the connection factory to see if it can help us. In our first draft of the connection factory, it will be similar to code the client had hard-coded, but this code is on the server-side:
So, since all I've done is move the client code into the above method, I've gained nothing yet. Or, to say it another way, I don't see your "trick" yet. The next server code is the same as above but written in "English" since I don't know the trick to say it in Java:
If the above "English" is correct, then somehow we need to leverage the fact that our ConnectionFactorImpl is a remote object; that is, that our connection factory exists on the server. So, as an initial guess, theoretically, the connection factory could say something like this: data = new Data(); return data; But, then I'd have to do more study or experimenting to see the implications of this. Maybe this is it; maybe there is no "lookup" of Data at all. Maybe only ConnectionFactory is the only remote object "lookup" in the system. Though the system has two remote objects served from the server: ConnectionFactoryImpl and DataImpl. This looks promising. I'll have to investigate further tomorrow. This looks promising because the client will be operating on a remote object, but one passed directly to it from a method instead of obtaining it from the rmi directory as a lookup. In fact, I'd go so far as to say that it is the solution. This is a little weird though; doesn't this change the paradigm on the server with respect to Data (as long as Data has no static methods and varaibles? For now the client can use Data in an un-threadsafe manner? Which is fine, I guess, one less thing to worry about. But these lasts thoughts have just arrived and need more time. Thanks very much for your clues, Javini Javono [ February 05, 2004: Message edited by: Javini Javono ]
Hi Javini, You are very close. You can obviously see the issues, you just have a few steps further to go. Your suspicion is right - your first example (data = (IndependentDataInterface) Naming.lookup(url + "RmiBoundDataImpl");) will not guarantee a unique instance of Data for each client. And if you do use a connection factory, then each client will get a unique object on the server side which can be used to identify the client. If that unique object has it's own instance of Data, then within Data's lock methods, you will be able to use the instance of Data to identify the client. But in that later case, there is no point in having any of the methods of Data synchronized (at a method level) since only one thread will ever be running them. So you either need to synchronize within the methods themselves on a common object, or you need to call methods in a single instance of some helper class which can then be synchronized. Regards, Andrew