Re: Correct way of avoiding a shutdown delay caused by the Reaper thread
Greg Luck <[email protected]> Tue, 8 Aug 2006 08:43:19 +1000
| Newsgroups | gmane.comp.java.sun.rmi |
|---|---|
| Message-ID | <[email protected]> |
Vinod
The code fragment in question is as follows. It is from
RMICacheManagerPeerListener in ehcache.
When we shutdown the cache manager, we need to shutdown the RMI
listener. We call dispose,
Dispose iterates through the bound and exported objects and unbinds
and unexports them.
The issue which as come about in production is that when people are
shutting down Tomcat, it is taking
up to a few minutes for this to happen. The Reaper thread was the cause.
The people having the trouble believe they have found the fundamental
cause, which they believe is that
UnicastRemoteObject.unexportObject(rmiCachePeer, false); was being
called before Naming.unbind(rmiCachePeer.getUrl());
We have changed the ordering so that unbind happens before unexport
which seems to have resolved their problem.
I have also added a Runtime.getRuntime().gc(); at the end of dispose.
I have seen people work around this problem by doing
that.
So I guess the question is, is this the best way to do things?
/**
* Stop the listener. It
* <ul>
* <li>unbinds the objects from the registry
* <li>unexports Remote objects
* </ul>
*/
public void dispose() throws CacheException {
try {
int counter = 0;
for (Iterator iterator = cachePeers.values().iterator();
iterator.hasNext();) {
RMICachePeer rmiCachePeer = (RMICachePeer)
iterator.next();
unbind(rmiCachePeer);
counter++;
}
LOG.debug(counter + " RMICachePeers unbound from
registry in RMI listener");
status = Status.STATUS_SHUTDOWN;
} catch (Exception e) {
throw new CacheException("Problem unbinding remote cache
peers. Initial cause was " + e.getMessage(), e);
} finally {
// It can take several minutes otherwise for the RMI
Reaper thread to stop.
Runtime.getRuntime().gc();
removeShutdownHook();
}
}
/**
* Unbinds an RMICachePeer and unexports it.
* <p/>
* We unbind from the registry first before unexporting.
* Unbinding first removes the very small possibility of a client
* getting the object from the registry while we are trying to
unexport it.
* <p/>
* This method may take up to 4 seconds to complete, if we are
having trouble
* unexporting the peer.
*
* @param rmiCachePeer the bound and exported cache peer
* @throws Exception
*/
protected void unbind(RMICachePeer rmiCachePeer) throws Exception {
Naming.unbind(rmiCachePeer.getUrl());
// Try to gracefully unexport before forcing it.
boolean unexported = UnicastRemoteObject.unexportObject
(rmiCachePeer, false);
for (int count = 1; (count < NAMING_UNBIND_MAX_RETRIES) && !
unexported; count++) {
try {
Thread.sleep(NAMING_UNBIND_RETRY_INTERVAL);
} catch (InterruptedException ie) {
// break out of the unexportObject loop
break;
}
unexported = UnicastRemoteObject.unexportObject
(rmiCachePeer, false);
}
// If we still haven't been able to unexport, force the
unexport
// as a last resort.
if (!unexported) {
if (!UnicastRemoteObject.unexportObject(rmiCachePeer,
true)) {
LOG.warn("Unable to unexport rmiCachePeer: " +
rmiCachePeer.getUrl() + ". Skipping.");
}
}
}
On 08/08/2006, at 6:22 AM, Vinod Johnson - Sun Microsystems wrote:
> Greg Luck wrote:
>
>> Hi
>>
>> I am, and it appears many others have had, trouble with RMI when
>> trying to shutdown a JVM.
>>
>> The issue is that the Reaper thread is not a daemon thread and does
>> not complete until the GC controlled by sun.rmi.dgc.client.gcInterval
>> has been run. Because this interval is 60 seconds it causes an
>> unacceptably long time to shutdown.
>>
> Without going into Reaper thread for a moment, could you explain a
> little more? I'm assuming that you want a timely shutdown of your
> server
> VM? Under what conditions do you want the shutdown to be triggered?
> Clients dereferencing their stubs? Client VM shutdown/termination?
> Other?
>
>>
>> So, I am wondering if their is a best practice for avoiding the
>> Reaper thread issue. The other idea I had was to set the
>> sun.rmi.dgc.client.gcInterval to 1 second, but I am unsure what
>> problems that may cause.
>>
> This would result in your RMI client VMs running GC every 1 second.
> Doesn't seem desireable to me in general.
>
>>
>> Regards
>>
>> Greg Luck
>>
>> web: http://gregluck.com
>> skype: gregrluck
>> yahoo: gregrluck
>> mobile: +61 408 061 622
>
>
>
> --
> - vinod
>
> ======================================================================
> =====
> To unsubscribe, send email to [email protected] and include in
> the body
> of the message "signoff RMI-USERS". For general help, send email to
> [email protected] and include in the body of the message "help".
>
> For a list of frequently asked RMI questions please refer to:
> http://java.sun.com/j2se/1.3/docs/guide/rmi/faq.html
>
> To view past RMI-USERS postings, please see:
> http://archives.java.sun.com/archives/rmi-users.html
Regards
Greg Luck
web: http://gregluck.com
skype: gregrluck
yahoo: gregrluck
mobile: +61 408 061 622
===========================================================================
To unsubscribe, send email to [email protected] and include in the body
of the message "signoff RMI-USERS". For general help, send email to
[email protected] and include in the body of the message "help".
For a list of frequently asked RMI questions please refer to:
http://java.sun.com/j2se/1.3/docs/guide/rmi/faq.html
To view past RMI-USERS postings, please see:
http://archives.java.sun.com/archives/rmi-users.html