Re: Preventing multiple submits

Brian Candler <[email protected]> Thu, 17 Feb 2005 18:35:03 +0000
Newsgroups gmane.comp.apache.mod-ruby
Message-ID <[email protected]>
On Thu, Feb 17, 2005 at 06:32:38PM +0100, Andi Scharfstein wrote:
> That's what I thought, but where do I store the LRU cache? I gather
> that memory is a bad idea since there may be multiple instances of
> mod_ruby running, each with its own memory (although that might not be
> a problem, I'm not very proficient there)

That's the fundamental problem.

If you have Apache running, it has a pool of httpd worker processes (let's
say 10 for the sake of argument). Each has its own Ruby interpreter and
being a separate process, has its own address space - a variable set in one
is not visible to the others. If a user submits a page then it will hit one
of those workers; if they re-submit then there's a 90% chance that the
second request will hit a different one.

So you need a way to keep shared state, so that you can tell whether a
request is a resubmission or not.

How you do this is application-dependent. For example, if the request
triggers an SQL database update, then the safest thing to do is to arrange
that the second SQL update will fail (e.g. by a SQL constraint violation).
After all, if the first request really *has* stalled for some reason, then
it's perfectly reasonable for the user to resubmit it.

But if you want to frig something up, then you could have a separate object
which keeps track of request IDs. A little DRb server object could be
accessed by each of the mod_ruby processes to check whether an ID has been
seen before, and to set a flag for new IDs. For some ideas see
http://www.rubygarden.org/ruby?DrbTutorial

> , but disk presents another
> problem, in that undefined behaviour might occur when several users
> want to submit data simultaneously. Again, I don't know that much
> about this, so please correct me if I'm wrong (or haven't thought of
> all the possibilities). Thanks!

I'm afraid you are really going to have to get your head around locking and
race conditions, whichever solution you go with.

Good luck,

Brian.