[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Ganymede Dev] Lots of 'rmi.RemoteExceptions' in debug.log

Date Sun, 27 Apr 2003 13:52:15 -0500
From Jonathan Abbey <jonabbey@arlut.utexas.edu>

On Sun, Apr 27, 2003 at 04:59:13PM +0000, John King wrote:
| 
| Hi Jon,

Hi Jan.

| I've noticed many Exceptions in my debug log, and I don't really know what 
| to think of it. This is one of them:
| 
| Sun Apr 27 16:11:07 CEST 2003:RMI:RMI TCP Connection(770)-[my.ip]:[[my.ip]: 
| arlut.csd.ganymede.DBObjectBaseField[1790]: public abstract short 
| arlut.csd.ganymede.BaseField.getTargetField() throws 
| java.rmi.RemoteException]

What you're seeing isn't really an Exception, it's just noting that
the method signature for the BaseField.getTargetField() remote
interface includes a mandatory check on the java.rmi.RemoteException
class.

If an Exception is actually thrown, you'll see a stack trace in the
debug.log file.

Using the j2sdk1.4.1 server VM on Solaris, all successful calls in our
debug.log file are prepended with 'FINER:', and the first line of
Exception reports are prepended with 'FINE:'.  

I'm actually not sure when this behavior in the debug.log started for
us, I hadn't previously seen it doing that, so I assume it's something
that Sun added in the latest JVM.  The logging to debug.log is
actually a function of the RMI server system, and not of any code in
the Ganymede server proper.

Even with older versions of the JVM, though, you should be able to
filter out normal calls with a simple grep -v and the appropriate
regular expression pattern.

| I sensored my ip out just because you never know who gets to reading this, 
| not to bug you.

Of course, no problem.

| Debug.log is also talking about 'Lease dirty', I'm curious about those 
| things too.

Lease dirty refers to a system-level RMI thread on the client or admin
console periodically calling the server and reporting that a set of
exported RMI objects are still being referenced by the client/console.
Essentially, every RMI client is required to periodically notify the
server that it is still alive and that a set of server-side objects
are in use by the client.  This periodic notification is recorded in
the RMI debug.log as a 'dirty' remote method call on a server-side
'Lease' RMI object.

If the client were to stop sending those 'dirty' calls for 10 minutes,
the RMI system on the server would assume that the exported RMI
objects were to be treated as no longer being referenced by the
client.  In that case, a server-side RMI thread would call an optional
method, named unreferenced(), on the exported objects, notifying them
that they are no longer being used by the client.

The Ganymede server uses this system to handle automatic cleanup after
a system running the Ganymede client or admin console reboots,
abruptly kills the process, or drops off of the network.

| A total other question: To what extent should I use the thread locking 
| keyword 'synchronized', I'd been implementing some methods like 
| finalizeSetValueLocal() when I ran into it.

That's a very good question.  Looking at my own code for the GASH
schema we use here at the lab, I see that I use synchronized for
finalizeSetValueLocal() in userCustom, but not in systemCustom or
interfaceCustom.

In general, I would suggest that you not use synchronized on your
DBEditObject methods, because you can run into the possibility of
deadlock in the server if you are not careful about what methods you
call from within your synchronized section, particularly if you
declare lots of synchronized methods.

In general in Ganymede, I try to use synchronization purely for
low-level encapsulated data structures, and not for methods that might
be called (even implicitly) by arbitrary thread or client action.

This was a hard lesson, deadlocks were one of the biggest problems in
Ganymede a few years ago.  There's likely still code in Ganymede which
uses thread synchronization a bit too carelessly, but I'm pretty
rigorous about improving the situation if I find older, looser
synchronization.

In the case of the synchronized finalizeSetValueLocal() in userCustom,
I believe I am trying to prevent the finalizeSetValueLocal() method
itself from running concurrently, so that there's less danger of all
of the contingent actions overlapping if a client were to attempt to
make multiple concurrent editing calls to that object.

For the most part, though, the client only makes RMI calls to the
server in reaction to events from the (single) GUI thread, which tends
to serialize things naturally anyway.

I'd say don't synchronize unless you know you need to, and even then,
think about using arlut.csd.Util.booleanSemaphore for simple mutual
exclusivity within a method, or arlut.csd.ganymede.loginSemaphore if
you need a counting semaphore.

The code for these two classes can be found in src/Util and
src/server, respectively.

| Regards,
| 
| Jan Bonne Aans
| DTO TUDelft
| The Netherlands

-- 
-------------------------------------------------------------------------------
Jonathan Abbey 				              jonabbey@arlut.utexas.edu
Applied Research Laboratories                 The University of Texas at Austin
GPG Key: 71767586 at keyserver pgp.mit.edu, http://www.ganymeta.org/workkey.gpg

Attachment: pgp00006.pgp
Description: PGP signature


  • Re: [Ganymede Dev] Lots of 'rmi.RemoteExceptions' in debug.log
    • From: Jonathan Abbey <jonabbey@arlut.utexas.edu>