(Do not) Use Rails cache as a distributed lock system

You should strive to design your application in a way that eliminates the need of critical sections as possible.

It is not robust, it adds layers of complexity and is VERY difficult to test.

You can avoid such burdens by using alternative threading constrains such as actors

Having said that there are still cases in a large distributed environment that you need to use Distributed lock manager in order to wrap a critical section of your flow.

It is preferable to use event based distributed locking – can be achieved with Zookeeper (based on Google’s Chubby)

I will show here a very simple locking mechanism based on Rails cache store.

You can set a shared cache between all your rails processes by setting config/environments/#{env}.rb

In the example I use Dalli (excellent memcached client by Mike Perham) but any store that is shared between the machines will work.

You can scroll to the bottom to see the CacheMutex spec and code

Usage is simple:

As you can see, the main disadvantage here is using a sleep-lock instead of event to notify the waiting thread.

CacheMutex source code:

<Edit>

Due to potential race conditions scenario identified by http://en.gravatar.com/cryo28 I switched to provided lock abilities of Redis-Objects https://github.com/nateware/redis-objects#lock

</Edit>

Advertisements

, , , , , ,

  1. #1 by Artem Ignatyev on July 4, 2012 - 18:53

    Looks like you locking code is prone to race condition. If two processes wait for the lock release (in sleep_lock method while loop) and the lock gets released, both processes will proceed to lock acquisition.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: