title: Correct way to do a distributed mutex in Rails?
body: <p>I am building a feature that requires application-level lock functionality. </p>
  
  <p>The feature goes like this:</p>
  
  <ul>
  <li>user logs in to the site</li>
  <li>they hit a button which kicks off a bunch of API requests (this is a long-running, synchronous, process)</li>
  <li>process finishes and all is well</li>
  </ul>
  
  <p>The issue is that there can only be one instance of this process running at any one time. Any kind of double-submit will cause major problems.</p>
  
  <p>My current strategy is to implement the following logic:</p>
  
  <ul>
  <li>I will put a boolean field on a table that indicates whether or not the long-running process is currently active</li>
  <li>when the user first submits their action, I will update that boolean using a lock:</li>
  </ul>
  
  <blockquote>
  <pre><code>pc = ProcessControl.first
  pc.with_lock do  
    if pc.process_is_running?
      return # abort
    else
      pc.process_is_running = true
      pc.save!
    end
  end
  LongRunningProcess.start!
  </code></pre>
  </blockquote>
  
  <ul>
  <li>then, the long process will run, and at the end, I'll flip the flag back to false.</li>
  </ul>
  
  <p>So my question is: will this work in a distributed environment? I have multiple app servers and I want to be sure that once the long-running process is off and running on one of the app servers, any request to kick off the long running process around the same time will read <code>pc.process_is_running?</code> and it should return false, preventing the double-submit.</p>
  
  <p>I have found some resources already that indicate there are other ways to do a distributed lock, I'm hoping that this (maybe naive?) approach above will work.</p>
  
  <p>Resources I've looked at:</p>
  
  <ul>
  <li><a href="http://makandracards.com/makandra/1026-simple-database-mutex-mysql-lock" rel="nofollow">http://makandracards.com/makandra/1026-simple-database-mutex-mysql-lock</a></li>
  <li><a href="https://github.com/mceachen/with_advisory_lock" rel="nofollow">https://github.com/mceachen/with_advisory_lock</a></li>
  </ul>