Search in sources :

Example 1 with BusyLockException

use of com.netflix.astyanax.recipes.locks.BusyLockException in project coprhd-controller by CoprHD.

the class CustomizedDistributedRowLock method acquire.

/**
 * Try to take the lock. The caller must call .release() to properly clean up
 * the lock columns from cassandra
 *
 * @throws Exception
 */
@Override
public void acquire() throws Exception {
    Preconditions.checkArgument(ttl == null || TimeUnit.SECONDS.convert(timeout, timeoutUnits) < ttl, "Timeout " + timeout + " must be less than TTL " + ttl);
    RetryPolicy retry = backoffPolicy.duplicate();
    retryCount = 0;
    while (true) {
        try {
            long curTimeMicros = getCurrentTimeMicros();
            MutationBatch m = keyspace.prepareMutationBatch().setConsistencyLevel(consistencyLevel);
            fillLockMutation(m, curTimeMicros, ttl);
            m.execute();
            verifyLock(curTimeMicros);
            acquireTime = System.currentTimeMillis();
            return;
        } catch (BusyLockException e) {
            release();
            if (!retry.allowRetry()) {
                throw e;
            }
            retryCount++;
        }
    }
}
Also used : MutationBatch(com.netflix.astyanax.MutationBatch) BusyLockException(com.netflix.astyanax.recipes.locks.BusyLockException) RetryPolicy(com.netflix.astyanax.retry.RetryPolicy)

Example 2 with BusyLockException

use of com.netflix.astyanax.recipes.locks.BusyLockException in project coprhd-controller by CoprHD.

the class GlobalLockImpl method release.

/**
 * Release the global lock
 * For VdcShared Mode, the release might just remove zk holder from local VDC ZK.
 * If no other holders, it will remove the global lock from geodb then.
 *
 * @param owner the name of the local owner (e.g. node id or svc name etc.)
 * @param force whether to allow a lock to be released by a different owner in the
 *            same VDC.
 */
public boolean release(final String owner, final boolean force) throws Exception {
    // 1. assemble global owner
    String localOwner = owner;
    String globalOwner = _vdc;
    if (_mode.equals(GlobalLock.GL_Mode.GL_NodeSvcShared_MODE)) {
        globalOwner = String.format("%1$s:%2$s", _vdc, owner);
    }
    // 2. release global lock
    _log.info("{} is releasing global lock {} ...", localOwner, _name);
    boolean bLockReleased = false;
    MutationBatch m = _keyspace.prepareMutationBatch();
    try {
        ColumnMap<String> columns = _cpDistRowlock.acquireLockAndReadRow();
        String currMode = columns.getString(GlobalLock.GL_MODE_COLUMN, null);
        String currOwner = columns.getString(GlobalLock.GL_OWNER_COLUMN, null);
        if (currMode == null || currOwner == null) {
            // the lock is not active; return true
            _log.error("The global lock {} has is not active.", _name);
            return true;
        }
        if (!currMode.equals(_mode.toString())) {
            errMsg = String.format("The global lock %s has been acquired by incompatible mode %s.", _name, currMode);
            _log.error(errMsg);
            throw new IllegalStateException(errMsg);
        }
        if (!currOwner.isEmpty() && !currOwner.equals(globalOwner)) {
            if (force && isForceReleaseEligible(currMode, globalOwner, currOwner)) {
                _log.warn("Forcibly releasing global lock with owner {}, was acquired" + " by owner {}.", globalOwner, currOwner);
            } else {
                errMsg = String.format("The global lock %s has been acquired by different owner %s.", _name, currOwner);
                _log.error(errMsg);
                return bLockReleased;
            }
        }
        // remove global lock holder from current vdc ZK
        if (!_mode.equals(GlobalLock.GL_Mode.GL_NodeSvcShared_MODE)) {
            removeLocalHolder(localOwner);
        }
        if (_mode.equals(GlobalLock.GL_Mode.GL_NodeSvcShared_MODE) || getLocalHolderNumber() == 0) {
            m.withRow(_cf, _name).deleteColumn(GlobalLock.GL_MODE_COLUMN);
            m.withRow(_cf, _name).deleteColumn(GlobalLock.GL_OWNER_COLUMN);
            m.withRow(_cf, _name).deleteColumn(GlobalLock.GL_EXPIRATION_COLUMN);
            _cpDistRowlock.releaseWithMutation(m);
            _log.info("{} released global lock {} successfully.", localOwner, _name);
        } else {
            // avoid releasing global lock if it is still hold by others
            _log.info("Skip releasing the global lock {}. It is still hold by other nodes within the vdc {}.", _name, _vdc);
        }
        bLockReleased = true;
    } catch (StaleLockException e) {
        errMsg = String.format("%s failed to release global lock %s due to internal distributed row lock becoming stale.", localOwner, _name);
        _log.error(errMsg);
        return bLockReleased;
    } catch (BusyLockException e) {
        errMsg = String.format("%s failed to release global lock %s due to locked by others.", localOwner, _name);
        _log.error(errMsg);
        return bLockReleased;
    } catch (Exception e) {
        errMsg = String.format("Failed to release global lock %s due to unexpected exception : %s.", _name, e.getMessage());
        _log.error("Failed to release global lock {} due to unexpected exception {}.", _name, e);
        throw e;
    } finally {
        _log.info("finally,internal distributed row lock releasing...");
        _cpDistRowlock.release();
        _log.info("finally,internal distributed row lock released.");
    }
    return bLockReleased;
}
Also used : MutationBatch(com.netflix.astyanax.MutationBatch) StaleLockException(com.netflix.astyanax.recipes.locks.StaleLockException) BusyLockException(com.netflix.astyanax.recipes.locks.BusyLockException) KeeperException(org.apache.zookeeper.KeeperException) BusyLockException(com.netflix.astyanax.recipes.locks.BusyLockException) StaleLockException(com.netflix.astyanax.recipes.locks.StaleLockException)

Example 3 with BusyLockException

use of com.netflix.astyanax.recipes.locks.BusyLockException in project coprhd-controller by CoprHD.

the class GlobalLockImpl method acquire.

/**
 * Acquire the global lock
 *
 * @param owner the name of the local owner (e.g. node id or svc name etc.)
 */
@Override
public boolean acquire(final String owner) throws Exception {
    // 1. assemble global owner
    String localOwner = owner;
    String globalOwner = _vdc;
    if (_mode.equals(GlobalLock.GL_Mode.GL_NodeSvcShared_MODE)) {
        globalOwner = String.format("%1$s:%2$s", _vdc, owner);
    }
    // 2. acquire global lock
    _log.info("{} is acquiring global lock {} ...", localOwner, _name);
    boolean bLockAcquired = false;
    MutationBatch m = _keyspace.prepareMutationBatch();
    try {
        ColumnMap<String> columns = _cpDistRowlock.acquireLockAndReadRow();
        String currMode = columns.getString(GlobalLock.GL_MODE_COLUMN, null);
        String currOwner = columns.getString(GlobalLock.GL_OWNER_COLUMN, null);
        String currExpiration = columns.getString(GlobalLock.GL_EXPIRATION_COLUMN, null);
        if (currMode != null && !currMode.equals(_mode.toString())) {
            errMsg = String.format("The global lock %s has been acquired by incompatible mode %s.", _name, currMode);
            _log.error(errMsg);
            throw new IllegalStateException(errMsg);
        }
        long curTimeMicros = System.currentTimeMillis();
        if (currExpiration != null) {
            long expirationTime = Long.parseLong(currExpiration);
            if (curTimeMicros < expirationTime || expirationTime == 0) {
                if (currOwner == null) {
                    errMsg = String.format("The global lock %s owner should not be null.", _name);
                    _log.error(errMsg);
                    throw new IllegalStateException(errMsg);
                }
                if (!currOwner.isEmpty() && !currOwner.equals(globalOwner)) {
                    errMsg = String.format("The global lock %s has been acquired by another owner %s.", _name, currOwner);
                    _log.error(errMsg);
                    return bLockAcquired;
                }
            }
        }
        m.withRow(_cf, _name).putColumn(GlobalLock.GL_MODE_COLUMN, _mode.toString());
        m.withRow(_cf, _name).putColumn(GlobalLock.GL_OWNER_COLUMN, globalOwner);
        long expirationTime = (_timeout == 0) ? 0 : curTimeMicros + _timeout;
        m.withRow(_cf, _name).putColumn(GlobalLock.GL_EXPIRATION_COLUMN, String.valueOf(expirationTime));
        // add global lock holder in current vdc ZK
        if (!_mode.equals(GlobalLock.GL_Mode.GL_NodeSvcShared_MODE)) {
            addLocalHolder(localOwner);
        }
        _cpDistRowlock.releaseWithMutation(m);
        bLockAcquired = true;
    } catch (StaleLockException e) {
        errMsg = String.format("%s failed to acquire global lock %s due to internal distributed row lock becoming stale.", localOwner, _name);
        _log.error(errMsg);
        return bLockAcquired;
    } catch (BusyLockException e) {
        errMsg = String.format("%s failed to acquire global lock %s due to locked by others.", localOwner, _name);
        _log.error(errMsg);
        return bLockAcquired;
    } catch (Exception e) {
        errMsg = String.format("Failed to acquire global lock %s due to unexpected exception : %s.", _name, e.getMessage());
        _log.error("Failed to acquire global lock {} due to unexpected exception {}.", _name, e);
        throw e;
    } finally {
        _log.debug("internal distributed row lock released.");
        _cpDistRowlock.release();
    }
    _log.info("{} acquired global lock {} successfully.", localOwner, _name);
    return bLockAcquired;
}
Also used : MutationBatch(com.netflix.astyanax.MutationBatch) StaleLockException(com.netflix.astyanax.recipes.locks.StaleLockException) BusyLockException(com.netflix.astyanax.recipes.locks.BusyLockException) KeeperException(org.apache.zookeeper.KeeperException) BusyLockException(com.netflix.astyanax.recipes.locks.BusyLockException) StaleLockException(com.netflix.astyanax.recipes.locks.StaleLockException)

Example 4 with BusyLockException

use of com.netflix.astyanax.recipes.locks.BusyLockException in project titan by thinkaurelius.

the class AstyanaxRecipeLocker method writeSingleLock.

@Override
protected AstyanaxLockStatus writeSingleLock(KeyColumn lockID, StoreTransaction tx) throws TemporaryLockingException, PermanentLockingException {
    long approxTimeNS = times.getApproxNSSinceEpoch();
    ByteBuffer keyToLock = serializer.toLockKey(lockID.getKey(), lockID.getColumn()).asByteBuffer();
    ColumnPrefixDistributedRowLock<ByteBuffer> lock = new ColumnPrefixDistributedRowLock<ByteBuffer>(lockKeyspace, lockColumnFamily, keyToLock).expireLockAfter(lockExpireNS, TimeUnit.NANOSECONDS).withConsistencyLevel(ConsistencyLevel.CL_QUORUM);
    try {
        lock.acquire();
        log.debug("Locked {} in store {}", lockID, lockColumnFamily.getName());
        return new AstyanaxLockStatus(approxTimeNS, TimeUnit.NANOSECONDS, lock);
    } catch (StaleLockException e) {
        // TODO handle gracefully?
        throw new TemporaryLockingException(e);
    } catch (BusyLockException e) {
        // TODO handle gracefully?
        throw new TemporaryLockingException(e);
    } catch (Exception e) {
        throw new PermanentLockingException(e);
    }
}
Also used : PermanentLockingException(com.thinkaurelius.titan.diskstorage.locking.PermanentLockingException) ColumnPrefixDistributedRowLock(com.netflix.astyanax.recipes.locks.ColumnPrefixDistributedRowLock) StaleLockException(com.netflix.astyanax.recipes.locks.StaleLockException) BusyLockException(com.netflix.astyanax.recipes.locks.BusyLockException) TemporaryLockingException(com.thinkaurelius.titan.diskstorage.locking.TemporaryLockingException) ByteBuffer(java.nio.ByteBuffer) PermanentLockingException(com.thinkaurelius.titan.diskstorage.locking.PermanentLockingException) BusyLockException(com.netflix.astyanax.recipes.locks.BusyLockException) StaleLockException(com.netflix.astyanax.recipes.locks.StaleLockException) TemporaryLockingException(com.thinkaurelius.titan.diskstorage.locking.TemporaryLockingException)

Aggregations

BusyLockException (com.netflix.astyanax.recipes.locks.BusyLockException)4 MutationBatch (com.netflix.astyanax.MutationBatch)3 StaleLockException (com.netflix.astyanax.recipes.locks.StaleLockException)3 KeeperException (org.apache.zookeeper.KeeperException)2 ColumnPrefixDistributedRowLock (com.netflix.astyanax.recipes.locks.ColumnPrefixDistributedRowLock)1 RetryPolicy (com.netflix.astyanax.retry.RetryPolicy)1 PermanentLockingException (com.thinkaurelius.titan.diskstorage.locking.PermanentLockingException)1 TemporaryLockingException (com.thinkaurelius.titan.diskstorage.locking.TemporaryLockingException)1 ByteBuffer (java.nio.ByteBuffer)1