Disconnected of the server

Hello friends

I need to do that a client who receives a remote interface,

can become disconnected, that is to say, to close the connection with the remote object, when he wants, something like that:

MyRemoteInterface remote = (MyRemoteInterface ) Naming.lookup("rmi://localhost/MyRemoteInterface ");

...

.

.

....

remote.closeConexionFromRemoteObject();

I want that really the reference and the resources are released...

you know like, or you think that it is possible to do it?

Message was edited by:

DaleGro

[612 byte] By [DaleGroa] at [2007-11-26 16:35:55]
# 1

> I need to do that a client who receives a remote interface,

> can become disconnected, that is to say, to close the

> connection with the remote object

There is no connection at all until you use the remote reference for an RMI call, or until DGC kicks in. A connection formed for either purpose is closed after 15 seconds of idleness.

> I want that really the reference and the resources

> are released...

Just throw away the reference (i.e. the remote stub), let it be garbage-collected locally. Nothing else is required.

ejpa at 2007-7-8 23:00:48 > top of Java-index,Core,Core APIs...
# 2

Well there is a logical connection between the client and the server as soon as the reference is returned to the client. And it will remain until the server clears it.

In my code the client can call a method, close on the server. THis will cause the server to unexport the remote interface immediately. Now that I think about it, how can you unexport a remote interface while its being used, LOL. Oh well, its working...

Also, the remote interface is unexported when the DGC runs. Which I guess is also silly since if the GC is runnin it means basically its already unexported, or at least unexporting.

Basically, let the DGC do the unexporting. (closing of logical connection)

_dnoyeBa at 2007-7-8 23:00:48 > top of Java-index,Core,Core APIs...
# 3

> Well there is a logical connection between the client

> and the server as soon as the reference is returned

> to the client.

No there isn't, not until the client calls a remote method or a DGC dirty call occurs. The server has no idea of the existence of the client until one of those happens, and even after that it only knows that there is at least one client out there. You can't describe that as a 'logical connection'.

> And it will remain until the server clears it.

Until the client clears it automatically via DGC.clean(), or the server is unexported.

> In my code the client can call a method, close on the

> server. THis will cause the server to unexport the

> remote interface immediately. Now that I think about

> it, how can you unexport a remote interface while its

> being used, LOL. Oh well, its working...

UnicastRemoteObject.unexportObject() with force=true will do that, no problems at all. But that remote-close pattern assumes there is only one client for the server. Not the usual case.

> Also, the remote interface is unexported when the DGC runs.

The remote object is unexported by DGC.

> Which I guess is also silly since if the GC is

> runnin it means basically its already unexported, or

> at least unexporting.

Not silly at all unless you think DGC == GC. DGC is different from local GC and precedes it in time.

ejpa at 2007-7-8 23:00:48 > top of Java-index,Core,Core APIs...
# 4

> > Well there is a logical connection between the

> client

> > and the server as soon as the reference is

> returned

> > to the client.

>

> No there isn't, not until the client calls a remote

> method or a DGC dirty call occurs. The server has no

> idea of the existence of the client until one of

> those happens, and even after that it only knows that

> there is at least one client out there. You can't

> describe that as a 'logical connection'.

I thought when the server exported an object and the client requests that object, at that point the client has a reference to something that will one day be eligible for DGC. WHich I consider a logical connection.

But I think I see what you are saying. By server you mean the object that was registered in the registry(which I think is correct and Ill be more careful with my terminology). So I agree that simply getting the object from the registry does not cause any connection.

>

> > And it will remain until the server clears it.

>

> Until the client clears it automatically via

> DGC.clean(), or the server is unexported.

If the connection drops, it will remain exported until the DGC on the server JVM is run right?

>

> > In my code the client can call a method, close on

> the

> > server. THis will cause the server to unexport

> the

> > remote interface immediately. Now that I think

> about

> > it, how can you unexport a remote interface while

> its

> > being used, LOL. Oh well, its working...

>

> UnicastRemoteObject.unexportObject() with force=true

> will do that, no problems at all. But that

> remote-close pattern assumes there is only one client

> for the server. Not the usual case.

Yes, once again I mixed my terms. My clients call the server and obtain another object, and they use that 2nd object for all their business. And when they are done they close the 2nd object. But the "server" which was registred with the registry, remains.

>

> > Also, the remote interface is unexported when the

> DGC runs.

>

> The remote object is unexported by DGC.

>

> > Which I guess is also silly since if the GC is

> > runnin it means basically its already unexported,

> or

> > at least unexporting.

>

> Not silly at all unless you think DGC == GC. DGC is

> different from local GC and precedes it in time.

I meant DGC. If the Unexported method is being called on that interface, its called when the object is already 'unexported' so there is no point in me unexporting it as a result of that call... But I also remove it from the cache, so maybe I am not as crazy as I thought.

_dnoyeBa at 2007-7-8 23:00:48 > top of Java-index,Core,Core APIs...
# 5

> I thought when the server exported an object and the

> client requests that object, at that point the client

> has a reference to something that will one day be

> eligible for DGC. WHich I consider a logical

> connection.

But it's only a one-way association. The client has a reference to the server but the server has no idea about the client's existence. The term 'reference' is more appropriate than 'connection'. I would normally consider a 'connection' to be something represented by state at both ends.

> But I think I see what you are saying. By server you

> mean the object that was registered in the

> registry

No, I mean any exported remote object.

> So I agree that simply

> getting the object from the registry does not cause

> any connection.

More generally, getting a remote reference via any remote method invocation does not cause any connection. The Registry is just a (not very) special case of this.

> If the connection drops, it will remain exported

> until the DGC on the server JVM is run right?

Right, i.e. until the server JVM's DGC finds the expired lease which hasn't been renewed.

> Yes, once again I mixed my terms. My clients call

> the server and obtain another object, and they use

> that 2nd object for all their business. And when

> they are done they close the 2nd object. But the

> "server" which was registred with the registry,

> remains.

And so does the 2nd object unless it got unexported. There's no difference between the 1st object being returned by Registry.lookup() and the 2nd object being returned by 1stObject.whatever(), the operations are identical. The Registry has no magical properties, it's just another remote object.

> I meant DGC. If the Unexported method is being

> called on that interface, its called when the object

> is already 'unexported' so there is no point in me

> unexporting it as a result of that call...

I don't understand any of this. What's the Unexported method and how can it be called when the remote object is already unexported? Or do you mean the Unreferenced.unreferenced() method? And if you do, this method is called while the object is still exported. In fact the application's implementation of Unreferenced.unreferenced() is the best place for the object to unexport itself and clean up after itself, if it has to do that.

ejpa at 2007-7-8 23:00:48 > top of Java-index,Core,Core APIs...
# 6

> But it's only a one-way association. The client has a

> reference to the server but the server has no idea

> about the client's existence. The term 'reference' is

> more appropriate than 'connection'. I would normally

> consider a 'connection' to be something represented

> by state at both ends.

>

> But I think I see what you are saying. By server

> you

> mean the object that was registered in the

> registry

>

> No, I mean any exported remote object.

So when the client gets a reference to an object at the server, the DGC is not aware of this?

>

> > So I agree that simply

> > getting the object from the registry does not

> cause

> > any connection.

>

> More generally, getting a remote reference via

> any remote method invocation does not cause

> any connection. The Registry is just a (not very)

> special case of this.

>

> If the connection drops, it will remain exported

> until the DGC on the server JVM is run right?

>

> Right, i.e. until the server JVM's DGC finds the

> expired lease which hasn't been renewed.

Well what began the lease? Obtaining the reference, or calling a method on it? Because if it waits till I call a mehod, then the DGC can be reclaiming my objects before I get to use them right?

> I meant DGC. If the Unexported method is being

> called on that interface, its called when the

> object

> is already 'unexported' so there is no point in me

> unexporting it as a result of that call...

>

> I don't understand any of this. What's the Unexported

> method and how can it be called when the remote

> object is already unexported? Or do you mean the

> Unreferenced.unreferenced() method? And if you do,

> this method is called while the object is still

> exported. In fact the application's implementation

> of Unreferenced.unreferenced() is the best place for

> the object to unexport itself and clean up after

> itself, if it has to do that.

Yes, thats what I meant. Unreferenced. Didin't have my code around to take a look. If the client says he is done, then I forcefully unexport the object, and if the unreference method is called, I also forcefully unexport the object.

Hmm, do I have to unexport every object I export? If so I got a lot more "unreferenced' methods to implement...

_dnoyeBa at 2007-7-8 23:00:48 > top of Java-index,Core,Core APIs...
# 7

> So when the client gets a reference to an object at

> the server, the DGC is not aware of this?

The DGC is aware of it as soon as the client calls DGC.dirty().

> Well what began the lease? Obtaining the reference,

> or calling a method on it?

DGC.dirty().

> Because if it waits till

> I call a mehod, then the DGC can be reclaiming my

> objects before I get to use them right?

Of course not. First, it doesn't wait. Second, DGC.dirty() prevents reclaiming: it is called periodically by the client as long as the remote stub is reachable inside the client JVM. Once the remote stub becomes unreachable in the client, i.e. is eligible for local GC in the client, it calls DGC.clean(), which ends that lease at the server. Every time the sum of the clean() calls at the server causes the lease count, i.e. the client count, to go to zero, Unreferenced.unreferenced() is called if the remote object implements Unreferenced. If the remote object stays 'clean' for long enough and it is unreachable in the server, it is then GC'd locally in the server. This also causies it to be unexported.

> Yes, thats what I meant. Unreferenced. Didin't have

> my code around to take a look. If the client says he

> is done, then I forcefully unexport the object, and

> if the unreference method is called, I also

> forcefully unexport the object.

You could just do the latter, of course. Or you could do nothing, see below.

> Hmm, do I have to unexport every object I export? If

> so I got a lot more "unreferenced' methods to

> implement...

If there is only one client per remote object, and there are no local references to these remote objects, DGC will clean them up for you, so you wouldn't need either your 'close' method or Unreferenced. If you have local references, i.e. other data structures to maintain (your cache), Unreferenced.unreferenced() is the best place to do the unexport and the associated cleanup. In fact you really only need to do the cleanup - i.e. clear all local references to the object and local GC will do the export (if it ever happens of course)

Basically I would recommend you get rid of your remote close method and use Unreferenced instead.

ejpa at 2007-7-8 23:00:48 > top of Java-index,Core,Core APIs...
# 8
THANKS FOR ALL!! I WILL LET THE DGC AND GC DO HIS WORK
DaleGroa at 2007-7-8 23:00:48 > top of Java-index,Core,Core APIs...
# 9

IRMIServer srvr = (IRMIServer) Naming.lookup(url); //no connection created

srvr.doMyThing(); //connection created?

I am assuming above that when that method is called on the remote object a connection is created. And that is the first place a connection is created. Well a stateful connection at least. And I am assuming DGC.dirty() is some internal RMI thing!? Nothing I would call yes?

I agree I do not have to let the client say when he is done. But it makes things cleaner for me. But it dont matter because I do have to handle dropped connections which will be dealt with using Unreferenced.

I am maintaining a connection to another server, so when Unreferenced is called or the client asks to close the connection, I can break that connection to this other database server. I could do without that too and let the GC cause everythign to close. I am just a big aggressive thats all.

My cache map holds weak value objects. So it will not keep the server from reclaiming the objects. Actually its not really a cache with the weak references, its more of a multiton. Which is actually what I am using it for.

_dnoyeBa at 2007-7-8 23:00:48 > top of Java-index,Core,Core APIs...
# 10

> I am assuming above that when that method is called

> on the remote object a connection is created.

Yes, or reused if there is one to reuse.

> And that is the first place a connection is created.

Not necessarily. DGC.dirty() might have been called first.

> And I am assuming DGC.dirty() is some internal RMI thing!?

>Nothing I would call yes?

Yes and yes. It's an RMI call so it uses a TCP connection like all RMI calls, but it's made automatically and executed automatically at the server.

ejpa at 2007-7-8 23:00:48 > top of Java-index,Core,Core APIs...
# 11

To be honest, I don't even need to use unreferenced. My cache is 'weak' so objects will automatically leave it, and the remote objects are reclaimed by the DGC then the GC on their own. Drop connection or intentional closed connection is no different. Maybe I should leave well enough alone. I'll have to vacillate on it.

_dnoyeBa at 2007-7-8 23:00:48 > top of Java-index,Core,Core APIs...