lib/Lock.js
function attemptLock(lock, timeout, callback) {
  var lockPath;
  var sequenceNodeName;
  var timerId = null;
  var start = Date.now();

  createNode(lock, afterCreate);

  function afterCreate(err, nodePath) {
    if (err) {
      return exit(err);
    }

    lockPath = nodePath;

    sequenceNodeName = nodePath.substring(lock.basePath.length + 1);

    getSortedChildren(lock, afterGetChildren);
  }

  function afterGetChildren(err, list) {
    if (exited()) {
      return;
    }
    if (err) {
      return exit(err);
    }

    var result = lock.driver.getsTheLock(list, sequenceNodeName,
      lock.maxLeases);

    if (result.error) {
      return exit(result.error);
    }
    else if (result.hasLock) {
      return exit(null, lockPath);
    }

    var watchPath = utils.join(lock.basePath, result.watchPath);

    lock.client
      .getData()
      .usingWatcher(watcher)
      .forPath(watchPath, afterGetData);

    setTimer();
  }

  function afterGetData(err) {
    if (exited() || !err) {
      return;
    }

    if (err.getCode() === Exception.NO_NODE) {
      getSortedChildren(lock, afterGetChildren);
    }
    else {
      exit(err);
    }
  }

  function watcher(event) {
    if (!exited() && event.getType() === Event.NODE_DELETED) {
      getSortedChildren(lock, afterGetChildren);
    }
  }

  function setTimer() {
    if (timerId) {
      return;
    }

    if (timeout >= 0) {
      timeout -= Date.now() - start;

      if (timeout <= 0) {
        return sayBye();
      }

      timerId = setTimeout(sayBye, timeout);
    }
  }

  function sayBye() {
    exit(new TimeoutError('Could not acquire lock %s', lock.basePath));
  }

  function exit(err, path) {
    if (timerId) {
      clearTimeout(timerId);
      timerId = -1;
    }

    var cb = callback;
    callback = null;

    if (!err) {
      cb(null, path);
    }
    else if (lockPath) {
      deleteNode(lock, lockPath, proceed);
    }
    else {
      cb(err);
    }

    function proceed(deleteError) {
      if (deleteError) {
        cb(deleteError);
      }
      else {
        cb(err);
      }
    }
  }

  function exited() {
    return !callback;
  }
}
function attemptLock(lock, timeout, callback) {
  var lockPath;
  var sequenceNodeName;
  var timerId = null;
  var start = Date.now();

  createNode(lock, afterCreate);

  function afterCreate(err, nodePath) {
    if (err) {
      return exit(err);
    }

    lockPath = nodePath;

    sequenceNodeName = nodePath.substring(lock.basePath.length + 1);

    getSortedChildren(lock, afterGetChildren);
  }

  function afterGetChildren(err, list) {
    if (exited()) {
      return;
    }
    if (err) {
      return exit(err);
    }

    var result = lock.driver.getsTheLock(list, sequenceNodeName,
      lock.maxLeases);

    if (result.error) {
      return exit(result.error);
    }
    else if (result.hasLock) {
      return exit(null, lockPath);
    }

    var watchPath = utils.join(lock.basePath, result.watchPath);

    lock.client
      .getData()
      .usingWatcher(watcher)
      .forPath(watchPath, afterGetData);

    setTimer();
  }

  function afterGetData(err) {
    if (exited() || !err) {
      return;
    }

    if (err.getCode() === Exception.NO_NODE) {
      getSortedChildren(lock, afterGetChildren);
    }
    else {
      exit(err);
    }
  }

  function watcher(event) {
    if (!exited() && event.getType() === Event.NODE_DELETED) {
      getSortedChildren(lock, afterGetChildren);
    }
  }

  function setTimer() {
    if (timerId) {
      return;
    }

    if (timeout >= 0) {
      timeout -= Date.now() - start;

      if (timeout <= 0) {
        return sayBye();
      }

      timerId = setTimeout(sayBye, timeout);
    }
  }

  function sayBye() {
    exit(new TimeoutError('Could not acquire lock %s', lock.basePath));
  }

  function exit(err, path) {
    if (timerId) {
      clearTimeout(timerId);
      timerId = -1;
    }

    var cb = callback;
    callback = null;

    if (!err) {
      cb(null, path);
    }
    else if (lockPath) {
      deleteNode(lock, lockPath, proceed);
    }
    else {
      cb(err);
    }

    function proceed(deleteError) {
      if (deleteError) {
        cb(deleteError);
      }
      else {
        cb(err);
      }
    }
  }

  function exited() {
    return !callback;
  }
}
function attemptLock ( lock , timeout , callback ) { var lockPath ; var sequenceNodeName ; var timerId = null ; var start = Date . now ( ) ; createNode ( lock , afterCreate ) ; function afterCreate ( err , nodePath ) { if ( err ) { return exit ( err ) ; } lockPath = nodePath ; sequenceNodeName = nodePath . substring ( lock . basePath . length + 1 ) ; getSortedChildren ( lock , afterGetChildren ) ; } function afterGetChildren ( err , list ) { if ( exited ( ) ) { return ; } if ( err ) { return exit ( err ) ; } var result = lock . driver . getsTheLock ( list , sequenceNodeName , lock . maxLeases ) ; if ( result . error ) { return exit ( result . error ) ; } else if ( result . hasLock ) { return exit ( null , lockPath ) ; } var watchPath = utils . join ( lock . basePath , result . watchPath ) ; lock . client . getData ( ) . usingWatcher ( watcher ) . forPath ( watchPath , afterGetData ) ; setTimer ( ) ; } function afterGetData ( err ) { if ( exited ( ) || ! err ) { return ; } if ( err . getCode ( ) === Exception . NO_NODE ) { getSortedChildren ( lock , afterGetChildren ) ; } else { exit ( err ) ; } } function watcher ( event ) { if ( ! exited ( ) && event . getType ( ) === Event . NODE_DELETED ) { getSortedChildren ( lock , afterGetChildren ) ; } } function setTimer ( ) { if ( timerId ) { return ; } if ( timeout >= 0 ) { timeout -= Date . now ( ) - start ; if ( timeout <= 0 ) { return sayBye ( ) ; } timerId = setTimeout ( sayBye , timeout ) ; } } function sayBye ( ) { exit ( new TimeoutError ( 'Could not acquire lock %s' , lock . basePath ) ) ; } function exit ( err , path ) { if ( timerId ) { clearTimeout ( timerId ) ; timerId = - 1 ; } var cb = callback ; callback = null ; if ( ! err ) { cb ( null , path ) ; } else if ( lockPath ) { deleteNode ( lock , lockPath , proceed ) ; } else { cb ( err ) ; } function proceed ( deleteError ) { if ( deleteError ) { cb ( deleteError ) ; } else { cb ( err ) ; } } } function exited ( ) { return ! callback ; } }
Attempt to acquire a lock.

@private
@param {Lock} lock Instance
@param {Number} timeout Timeout
@param {Function} callback Callback function: <code>(err, lockPath)</code>
Attempt to acquire a lock .