views:

308

answers:

4

Disclaimer: I already asked this question, but without the deployment requirement. I got an answer that got 3 upvotes, and when I edited the question to include the deployment requirement the answer then became irrelevant. The reason I'm resubmitting is because SO considers the original question 'answered', even though I got no meaningful upvoted answer. I opened a uservoice submission about this problem. The reason I reposted is so StackOverflow consider the original question answered, so it doesn't show up on the 'unanswered questions' tab.

Which distributed lock service would you use?

Requirements are:

  1. A mutual exclusion (lock) that can be seen from different processes/machines
  2. lock...release semantics
  3. Automatic lock release after a certain timeout - if lock holder dies, it will automatically be freed after X seconds
  4. Java implementation
  5. Easy deployment - must not require complicated deployment beyond either Netapp, MySql or GigaSpaces. Must play well with those products (especially GigaSpaces - this is why TerraCotta was ruled out).
  6. Nice to have: .Net implementation
  7. If it's free: Deadlock detection / mitigation

I'm not interested in answers like "it can be done over a database", or "it can be done over JavaSpaces" - I know. Relevant answers should only contain a ready, out-of-the-box, proven implementation.

A: 

I get the following error when I follow your link: http://code.google.com/p/lokc/admin

Forbidden

Your client does not have permission to get URL /p/lokc/admin from this server.

Ed J
It was removed to comply with company policy ... I wrote it on company time.
ripper234
+1  A: 

Here's the outline of a GigaSpaces based answer that meets your criteria, depending on exactly what you mean in criteria 3. I work with GigaSpaces from .Net, not Java:

Create a locking class with a SpaceID+SpaceRouting property IDing what is locked and a DataMember bool property Unlocked:

sealed public class IdLockTrans
{
    [SpaceID]
    [SpaceRouting]
    public string ID
    {
        get;
        set;
    }

    [DataMember]
    public bool Unlocked
    {
        get;
        set;
    }

    public IdLockTrans(Id id)
    {
        ID = id.ID;
    }

    public IdLockTrans()
    {
    }
}

You will use GigaSpaces' lease time for lock release after a certain timeout. This will cause GigaSpaces to remove IdLockTrans objects from the space automatically after they have been idle for the timeout period. The lack of an IdLockTrans for an ID means the ID is unlocked.

Your locker class will define and initialize these class members

    private readonly ISpaceProxy _proxy;
    private readonly long _leaseTime;

    public override bool Lock(Id id, long timeout)
    {
        bool locked;
        IdLockTrans lockTransTemplate = new IdLockTrans(id);
        // Assume that this is a new id.
        try
        {
            _proxy.Write(lockTransTemplate, null, _leaseTime, 0, UpdateModifiers.WriteOnly);
            locked = true;
        }
        catch (EntryAlreadyInSpaceException)
        {
            using (ITransaction tx = _proxy.CreateLocalTransaction())
            {
                try
                {
                    lockTransTemplate.Unlocked = true;
                    IdLockTrans lockTrans = _proxy.Take(lockTransTemplate, tx, timeout);
                    locked = (lockTrans != null);
                    if (lockTrans != null)
                    {
                        lockTrans.Unlocked = false;
                        _proxy.Write(lockTrans, tx, _leaseTime, 0, UpdateModifiers.WriteOnly);
                    }
                    tx.Commit();
                }
                catch
                {
                    tx.Abort();
                    throw;
                }
            }
        }
        return locked;
    }

    public override void Unlock(Id lockedId)
    {
        IdLockTrans lockTrans = new IdLockTrans(lockedId);
        lockTrans.Unlocked = true;
        try
        {
            _proxy.Update(lockTrans, null, _leaseTime, 0, UpdateModifiers.UpdateOnly);
        }
        catch (EntryNotInSpaceException)
        {
            throw new Exception("IdLockTrans for " + lockTrans.ID
                + " not found on Unlock. Lock time exceeded lease time.");
        }
    }
Mark Nelson
That's what I ended up implementing. I can't publish the source code because it's company property, but that is the general idea.
ripper234
A: 

In case you are still looking, take a look at Apache Zookeeper:

ZooKeeper is a centralized service for maintaining configuration information, naming, providing distributed synchronization, and providing group services. All of these kinds of services are used in some form or another by distributed applications.

The Zookeeper documentation provides examples of how to build a Lock service on top of Zookeeper.

matt b
A: 

Just use GridGain 3.0 built-in Data Grid APIs: http://www.gridgain.com

Nikita Ivanov