Archive for May, 2012

(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

, , , , , ,

2 Comments

Speed up network bound specs with vcr

Fast tests feedback is crucial for productivity (don’t wait for your tests on TDD), commit time (continuous integration), deploy time (continuous deployment)

VCR is a great tool for speeding up network bound tests. It uses an underlying layer to imitate web requests by dumping the first request into yml file and using the dumped response to stub future requests with the same headers.

Setup is super easy:

1) Gemfile

2) spec_helper

3) go over all failing tests and add :vcr to the group:

Each example group will be represented by a yml file in the spec/cassettes directory. The file will include all the requests and responses for the example group

4) update .gitignore to ignore cassettes

Run your specs and enjoy the velocity (on the second run ;-))

Leave a comment