A two phase commit would do the job indeed, but is not the only way (at one condition se (*1)), a much
simpler approach, one that is better suited for James would be :

1) On the sender side (the SMTP source) :

boolean success = false;

while(!success) {
success = send(mail);// It's a prerequisite that send returns "true" if and only if an acknowledgement is received,
// and that the later is sent if and only it the message was persisted. (*1)
if(success)
deleteFromLocalStore(mail); // or "persist the fact that 'mail' was sent.
sleep(x);
}

2) On the receiver side (James) :

while(true) {
mail = receiveMail(); // a blocking call that unblocks when an email gets in...
if(!alreadyExistsInPersistentStore(mail))
persist(mail);
}

The (1) part insures "at least once" guaranty of delivery, while (2) by detecting duplicates takes care of the
"at most once" part guaranty.

The only prerequisite for this is that SMTP provides for some kind of acknowledgement of receipt,
and that the SMTP source implementation uses this ack. to delete the mail from its "to send" list...

Does SMTP have this ?

Note that this also takes care of DB failures, since the ACK. is sent only when successfully stored.


Noel J. Bergman wrote:

This is a transaction issue.  But there is no mechanism within SMTP for a
two-phase commit.  There is always some chance that between storing the
message and advising the client that the system could crash.  For that
matter, after sending an acknowledgment to the client, there is some chance
that the packet could be lost.  This effects receipt and relaying by James.

Internally, mail is queued between the handler and the spool manager, and
then within the spool manager for each transition between processors.  Not
for each mailet.

What you want is a transaction, so that the process of your storing the
mailet in the database, and the message being removed from the spool appears
to be atomic.  But there is no two-phase commit within the spooling
mechanism.  If your mailet puts the message in a database, as LocalDelivery
can, then your mailet should set the state to GHOST, and the message will be
removed from the spool, so that the only copy will be the one you saved.  As
I said, there is a small window between storing the message in the database,
and when it is cancelled from the spool.  Very unlikely, but possible.

	--- Noel


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


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

Reply via email to