Friday, January 21, 2011

New distributed locking service in JGroups

I just uploaded JGroups 2.12.0.Beta1, which contains a first version of the new distributed locking service (LockService), which replaces DistributedLockManager.

LockService provides a distributed implementation of java.util.concurrent.lock.Lock. A lock is named and locking granularity is per thread. Here's an example of how to use it:

// lock.xml has to have a locking protocol in it
JChannel ch=new JChannel("/home/bela/lock.xml");
LockService lock_service=new LockService(ch);
Lock lock=lock_service.getLock("mylock");
if(lock.tryLock(2000, TimeUnit.MILLISECONDS)) {
    try {
        // access the resource protected by "mylock"
    }
    finally {
        lock.unlock();
    }
}

If "mylock" is locked by a different thread, it doesn't matter whether inside the same JVM, on the same box, or somewhere in the same cluster, then tryLock() will return false after 2 seconds, else it'll return true.

Lock.newCondition() is currently not implemented - if there's a need for this, let us know on one of the JGroups mailing lists and we'll tackle this. If you have a chance to play with LockService, we're also grateful for feedback.

The new locking service is part of 2.12.0.Beta1, which can be downloaded at [1]. Documentation is at [2].
Cheers,


[1] http://sourceforge.net/projects/javagroups/files/JGroups/2.12.0.Beta1
[2] http://www.jgroups.org/manual/html/index.html, section 4.6

6 comments:

  1. William Burns7:37 PM

    There appears to be a minor bug in the ClientLock inner class of Locking.

    public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
    return acquireTryLock(unit.convert(time, TimeUnit.MILLISECONDS), true);
    }

    The TimeUnit.MILLISECONDS and unit need to be switched around. Else it will attempt to convert the time value as MILLISECONDS to what you pass in. So in my case I tried 5 SECONDS and it converted 5 MILLISECONDS to 0 SECONDS instead of the inverse. This then cause it to immediately fail on the attempt to lock.

    Obviously an easy workaround is to always pass the values as MILLISECONDS.

    I also looked through rest of jgroups code very quickly and found that the same issue appears to be in HashedTimingWheel.schedule and TimeScheduler2.schedule methods.

    ReplyDelete
  2. Wow, thanks for finding this, William !

    I saw that you opened a JIRA issue, this will get fixed asap.

    Another reiteration of the value of *open* source !

    Cheers,

    ReplyDelete
  3. What happens to a the lock if a node holding the lock crashes?

    It is not clear from the docs what happens to the lock.

    Thanks.

    ReplyDelete
  4. The locks held by the crashed member are removed and can be acquired by other members.

    ReplyDelete
  5. Anonymous8:40 AM

    Can you share the lock.xml you have used in the above code?? Also, should this lock.xml file be a separate file from other conf xmls or it can be part of a existing xml file??

    ReplyDelete
    Replies
    1. Take udp.xml or tcp.xml (shipped with JGroups) and add CENTRAL_LOCK to the top, e.g.

      .....
      <FRAG2 frag_size="60K" />
      <RSVP resend_interval="2000" timeout="10000"/>
      <pbcast.STATE_TRANSFER />
      <CENTRAL_LOCK />

      Delete