I have a really busy couple of weeks in front of me, but once that is done,
I should have time to work on this for v3.0.

This is an approach to implement the scheduling aspect of my "New Approach
to Spooling" proposla.  It is intentionally compatible with the existing
Mailet API.

The change will consist of three parts: a processor, a mailet and a utility
class.  The processor would be defined, to use a simplified example without
configuration options, as:

  <processor name="SCHEDULER">
    <mailet class="Scheduler"/>
  </processor>

which does nothing for you unless you know what the Scheduler mailet is, how
messages get there, and where they go afterwards.

The Scheduler mailet will be derived from the part of RemoteDelivery that
receives a message on a spool thread, and has a separate thread processing
an internal queue.  We won't need more than one scheduler thread.  When a
message's schedule time occurs, the mailet will post it to the designated
destination.

The utility class will contain the actual scheduler, whose core pseudo-code
can be described as:

  schedule.retry(mail)
    boolean scheduled = false;
    retries = getRetryCount(mail);
    if (retries < getMaxRetries()) {
      setRetryTime(mail)  { mail.setAttribute("org.apache.james.RETRY_TIME",
nextTime(mail)); }
      setRetryCount(mail) {
mail.setAttribute("org.apache.james.RETRY_COUNT", ++retries); }
      // WARNING: THESE TWO OPERATIONS MUST BE PERFORMED IN THIS SEQUENCE
SINCE BOTH DEPEND UPON THE MAIL'S STATE
      setRetryDest(mail)  { mail.setAttribute("org.apache.james.RETRY_DEST",
mail.getState()); }
      setScheduler(mail)  { mail.setState(schedule_processor); }
      scheduled = true;
    }
    return scheduled

The code looks at the message, decides if there are more retries available,
and if so posts the message so that the scheduler knows when to post it
back, and to which processor.  Yes, the rescheduling would be on a processor
boundary, which will be the transaction boundary once we properly support
transactions.

The schedule object would be constructed from a retry schedule such as the
one we have for RemoteDelivery.  Actually, I'll do an abstract class with
the code for scheduling and an abstract method "nextTime" method, and then a
specific implementation making use of the code from RemoteDelivery, to
separate mechanics from policy.  RemoteDelivery would receive messages and
perform something like:

 if (!deliver(mail) && !schedule.retry(mail)) {
    process a bounce
 }

Other mailets, such as ClamAV, could contain similar code to schedule
retries if a resource they need is not available (and optionally notify the
administrator of the problem).  Additional work will be done to allow
matchers to also rescheduling.

Comments solicited.  This is just a first out.

        --- Noel



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to