Happy-the-monk has asked for the wisdom of the Perl Monks concerning the following question:

Wise monks,

When I took over legacy POP3 mail processing production code years ago, it had a number of bugs to fix. Not having much time to do it, I fixed some of the bugs as time permitted.

A serious bug that's a bit over my head is when concurrent POP3-clients try to delete the same mail message using Mail::POP3Client -
each client would first fetch the mail at $id, read the headers to see if the message-id is the right one, then delete it on the POP3 server.
Imagine two clients trying to do that with the same message - each would fetch it, find it to be the right one and send the delete request. Add a little network latency and two different messages would be deleted.

I guess I am looking for a kind of file/Flock way to allow only one client at a time to prepare and execute a deletion, having the others wait until it has finished.
But I am certain, other people will have had the same problem before me and may have got better solutions. Could you point me towards it?

Cheers, Sören

Replies are listed 'Best First'.
Re: Locking a POP3 Mailbox
by exussum0 (Vicar) on May 01, 2004 at 13:02 UTC
Re: Locking a POP3 Mailbox
by kappa (Chaplain) on May 01, 2004 at 16:36 UTC
    Any rfc-compliant (or just written by a sufficiently consious programmer) POP3-server should do transparent locking itself. Look, RFC says locking should take place :) (search for 'lock') Having said that, do you really experience any problems with several pop3 clients accessing the same mailbox in parallel or try to predict possible race condition?
      Once the POP3 server has determined through the use of any authentication command that the client should be given access to the appropriate maildrop, the POP3 server then acquires an exclusive- access lock on the maildrop, as necessary to prevent messages from being modified or removed before the session enters the UPDATE state. If the lock is successfully acquired, the POP3 server responds with a positive status indicator. The POP3 session now enters the TRANSACTION state, with no messages marked as deleted.
      Problem is, "should" is the operative word. It's not required. :\

Re: Locking a POP3 Mailbox
by sgifford (Prior) on May 01, 2004 at 16:10 UTC

    You simply want to use filesystem locks. Locking should be coordinated between all of the different mail subsystems, so you should find out what kind of file locking the mail delivery agent uses and use the same thing. Common locking protocols for mailboxes are just using flock or fcntl(LOCK_EX,...) to lock the mbox file, or create a mailbox.LOCK file. You would probably want to lock when the POP program started, so nothing changed underneath you.

      Oh, maybe I misunderstood your question. Are you trying to deal with locking on the POP3 server end, or the client? If it's the client and all clients run on the same machine, again you can use filesystem locks. Just do open(LOCK,">>/tmp/lockfile"); flock(LOCK,LOCK_EX); before opening the POP connection, but with error checking and a lockfile that's not in a world-writable area.