Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Document-level locking for MongoDB via Mongoid
Ruby

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.
lib
spec
.document
.gitignore
.rspec
.travis.yml
Gemfile
Guardfile
LICENSE.txt
README.md
Rakefile
VERSION
mongoid-locker.gemspec

README.md

mongoid-locker Build Status

Document-level locking for MongoDB via Mongoid. The need arose at Jux from multiple processes on multiple servers trying to act upon the same document and stepping on each other's toes. Mongoid-Locker is an easy way to ensure only one process can perform a certain operation on a document at a time.

Tested against MRI 1.8.7, 1.9.2 and 1.9.3, Rubinius 1.8 and 1.9, and JRuby 1.8 and 1.9.

Usage

Add to your Gemfile:

gem 'mongoid-locker', '~> 0.1.0'

and run bundle install. In the model you wish to lock, include Mongoid::Locker after Mongoid::Document. For example:

class QueueItem
  include Mongoid::Document
  include Mongoid::Locker

  field :completed_at, :type => Time
end

Then, execute any code you like in a block like so:

queue_item.with_lock do

  # do stuff

  queue_item.completed_at = Time.now
  queue_item.save!
end

#with_lock takes a couple options as a hash:

  • timeout: The amount of time until a lock expires, in seconds. Defaults to 5.
  • wait: If a lock exists on the document, wait until that lock expires and try again. Defaults to false.

The default timeout can also be set on a per-class basis:

class QueueItem
  # ...
  timeout_lock_after 10
end

Note that these locks are only enforced when using #with_lock, not at the database level. It is useful for transactional operations, where you can make atomic modification of the document with checks. For exmple, you could deduct a purchase from a user's balance... unless they are broke.

More in-depth method documentation can be found at rdoc.info. Enjoy!

Contributing

Pull requests are welcome. To run tests:

$ bundle install
$ rake

To auto-run tests as you code:

$ bundle install
$ guard
Something went wrong with that request. Please try again.