james-server-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Noel J. Bergman" <n...@devtech.com>
Subject RE: Same exception for JamesSpoolManager
Date Thu, 06 Jun 2002 18:21:54 GMT
Serge,

So basically AvalonSpoolRepository.accept() should only return an object
that it has locked, and if it has it locked then it should only be possible
to lock it and return it once.  This is the crux of the problem;
AvalonMailRepository.retrieve() should never be called for the same key
concurrently (although it should be more bulletproof).

As I see it:

  JamesSpoolManager.run()
  {
      ...
      key = spool.accept()
      [
        for(Iterator it = list(); it.hasNext(); ) {
         String s = it.next().toString();
         if (lock(s)
         [
            if (lock.lock(key)
            [
               Object theLock;
               synchronized(this) {
                  theLock = locks.get(key);
                  if (null == theLock) {
                      locks.put(key, getCallerId());
                      return true;
                  } else if (getCallerId() == theLock) {
                      return true;
                  } else {
                      return false;
               }
            ]) {
                synchronized (this) {
                   notifyAll();
                }
                return true;
            } else {
                return false;
            }
         ]) {
             if (DEEP_DEBUG) {
                 getLogger().debug("accept() has locked: " + s);
             }
             return s;
         }
	];
	msg = spool.retrieve(key);

[] are used to designate the extracted code for the called method.
getCallerId() returns the current thread.

So it appears that we have multiple threads running through the
JamesSpoolManager, and somehow both of them are getting the same object from
spool.accept().  Locking is based upon a Lock object inside the spool
instance.  An object is considered locked if its string value appears as a
key in the Lock's hashtable.  The owning thread is stored in the hashtable
(does this mean that if the object isn't unlocked, the thread reference
dangles in the hashtable)?

Is that a correct interpretation?

	--- Noel

-----Original Message-----
From: Serge Knystautas [mailto:sergek@lokitech.com]
Sent: Thursday, June 06, 2002 11:14
To: James Developers List
Subject: Re: Same exception for JamesSpoolManager


Andrei,

I've seen this exception occassionally at high loads as well, and what I
believe is causing it is 2 threads getting simultaneous locks on the
same Mail object.  One thread processes it, and then the second one
tries to get it and can't get to it.  This means something bad is
happening with the locking, although there is something good happening
because the 2 threads do not both process the same message... merely 2
threads get told they are to process the same message, but one does it
and then after the first one completes, the second one tries and fails.
  So, it's a problem but doesn't seem to cause functional problems.

Hopefully this gives you some direction into finding the problem.  (I
didn't get the chance to apply your patches last night.  again, I'm
going to try tonight.  I'm just having a heavy few weeks and just tend
to commit in spurts.)
--
Serge Knystautas
Loki Technologies - Unstoppable Websites
http://www.lokitech.com


Noel J. Bergman wrote:
> Andrei,
>
> Glad to hear how it is going, and I hope to see your changes in the CVS
> really soon, since it seems that you've really improved the stablity of
> James.
>
> However, you've posted the stack trace of the symptom, but not the log of
> the more proximate cause. What is the RuntimeException in the log? Are
they
> always the same?  I'm running with JDBC, so I won't see the same results
as
> you.
>
> 	--- Noel
>
> -----Original Message-----
> From: Andrei A. Ivanov [mailto:myfam@surfeu.fi]
> Sent: Thursday, June 06, 2002 11:00
> To: James Developers List
> Subject: Re: Same exception for JamesSpoolManager
>
>
> Noel, thanks for answer.
> Yes of course it is in the log. I am running long (many hours) tests with
> load about 5 emails / second. I have stability requirements first of all.
> James behaves generally very well. I am using my SMTPServer-Handler
classes
> because it won't live with the original one (especially when TLS is in
use).
> Only bad thing I have are these exceptions in JamesSpoolManager (which
> originates from the place you've pointed). There are from 10 to 50 such
> exceptions per 100 000 mails. Not a big deal though I am wondering about
> possible cause of these exceptions (RuntimeException when mc = (MailImpl)
> or.get(key)) .
>
> Andrei
>
> ----- Original Message -----
> From: "Noel J. Bergman" <noel@devtech.com>
> To: "James Developers List" <james-dev@jakarta.apache.org>
> Sent: Thursday, June 06, 2002 5:44 PM
> Subject: RE: Same exception for JamesSpoolManager
>
>
>
>>You are using AvalonMailRepository, yes?  Please look at the code:
>>
>>  MailImpl mc = null;
>>  try {
>>        mc = (MailImpl) or.get(key);
>>  } catch (RuntimeException re) {
>>      getLogger().error("Exception retrieving mail: " + re + ", so we're
>>deleting it... good ridance!");
>>      remove(key);
>>      return null;
>>  }
>>
>>Is there something logged about the exception? THAT seems to be the root
>>cause, but it won't appear in a stack trace.
>>
>>--- Noel
>>
>>-----Original Message-----
>>From: Andrei A. Ivanov [mailto:myfam@surfeu.fi]
>>Sent: Thursday, June 06, 2002 4:44
>>To: James Developers List
>>Subject: Same exception for JamesSpoolManager
>>
>>
>>Which I had often for older versions of James still comes for latest James
>>from cvs (see below)
>>This is when it gets name of mail. How to fix that, any ideas?
>>
>>Andrei
>>
>>java.lang.NullPointerException
>>        at
>>org.apache.james.transport.JamesSpoolManager.run(JamesSpoolManager.java:20
7
>
> )
>
>>        at
>>org.apache.avalon.excalibur.thread.impl.ExecutableRunnable.execute(Executa
b
>
> leRunnable.java:47)
>
>>        at
>>org.apache.avalon.excalibur.thread.impl.WorkerThread.run(WorkerThread.java
:
>
> 80)
>
>>java.lang.NullPointerException
>>        at
>>org.apache.james.transport.JamesSpoolManager.run(JamesSpoolManager.java:20
7
>
> )
>
>>        at
>>org.apache.avalon.excalibur.thread.impl.ExecutableRunnable.execute(Executa
b
>
> leRunnable.java:47)
>
>>        at
>>org.apache.avalon.excalibur.thread.impl.WorkerThread.run(WorkerThread.java
:
>
> 80)
>
>>java.lang.NullPointerException
>>        at
>>org.apache.james.transport.JamesSpoolManager.run(JamesSpoolManager.java:20
7
>
> )
>
>>        at
>>org.apache.avalon.excalibur.thread.impl.ExecutableRunnable.execute(Executa
b
>
> leRunnable.java:47)
>
>>        at
>>org.apache.avalon.excalibur.thread.impl.WorkerThread.run(WorkerThread.java
:
>
> 80)
>
>>java.lang.NullPointerException
>>        at
>>org.apache.james.transport.JamesSpoolManager.run(JamesSpoolManager.java:20
7
>
> )
>
>>        at
>>org.apache.avalon.excalibur.thread.impl.ExecutableRunnable.execute(Executa
b
>
> l
>
>>eRunnable.java:47)
>>        at
>>org.apache.avalon.excalibur.thread.impl.WorkerThread.run(WorkerThread.java
:
>
> 80)
>
>>java.lang.NullPointerException
>>        at
>>org.apache.james.transport.JamesSpoolManager.run(JamesSpoolManager.java:20
7
>
> )
>
>>        at
>>org.apache.avalon.excalibur.thread.impl.ExecutableRunnable.execute(Executa
b
>
> leRunnable.java:47)
>
>>        at
>>org.apache.avalon.excalibur.thread.impl.WorkerThread.run(WorkerThread.java
:
>
> 80)
>
>>java.lang.NullPointerException


--
To unsubscribe, e-mail:   <mailto:james-dev-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:james-dev-help@jakarta.apache.org>


--
To unsubscribe, e-mail:   <mailto:james-dev-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:james-dev-help@jakarta.apache.org>


Mime
View raw message