Search in sources :

Example 1 with NonceKey

use of org.apache.hadoop.hbase.util.NonceKey in project hbase by apache.

the class ServerNonceManager method addMvccToOperationContext.

/**
 * Store the write point in OperationContext when the operation succeed.
 * @param group Nonce group.
 * @param nonce Nonce.
 * @param mvcc Write point of the succeed operation.
 */
public void addMvccToOperationContext(long group, long nonce, long mvcc) {
    if (nonce == HConstants.NO_NONCE) {
        return;
    }
    NonceKey nk = new NonceKey(group, nonce);
    OperationContext result = nonces.get(nk);
    assert result != null;
    synchronized (result) {
        result.setMvcc(mvcc);
    }
}
Also used : NonceKey(org.apache.hadoop.hbase.util.NonceKey)

Example 2 with NonceKey

use of org.apache.hadoop.hbase.util.NonceKey in project hbase by apache.

the class ServerNonceManager method startOperation.

/**
 * Starts the operation if operation with such nonce has not already succeeded. If the
 * operation is in progress, waits for it to end and checks whether it has succeeded.
 * @param group Nonce group.
 * @param nonce Nonce.
 * @param stoppable Stoppable that terminates waiting (if any) when the server is stopped.
 * @return true if the operation has not already succeeded and can proceed; false otherwise.
 */
public boolean startOperation(long group, long nonce, Stoppable stoppable) throws InterruptedException {
    if (nonce == HConstants.NO_NONCE)
        return true;
    NonceKey nk = new NonceKey(group, nonce);
    OperationContext ctx = new OperationContext();
    while (true) {
        OperationContext oldResult = nonces.putIfAbsent(nk, ctx);
        if (oldResult == null)
            return true;
        // Collision with some operation - should be extremely rare.
        synchronized (oldResult) {
            int oldState = oldResult.getState();
            LOG.debug("Conflict detected by nonce: " + nk + ", " + oldResult);
            if (oldState != OperationContext.WAIT) {
                // operation ended
                return oldState == OperationContext.PROCEED;
            }
            oldResult.setHasWait();
            // operation is still active... wait and loop
            oldResult.wait(this.conflictWaitIterationMs);
            if (stoppable.isStopped()) {
                throw new InterruptedException("Server stopped");
            }
        }
    }
}
Also used : NonceKey(org.apache.hadoop.hbase.util.NonceKey)

Example 3 with NonceKey

use of org.apache.hadoop.hbase.util.NonceKey in project hbase by apache.

the class ServerNonceManager method reportOperationFromWal.

/**
 * Reports the operation from WAL during replay.
 * @param group Nonce group.
 * @param nonce Nonce.
 * @param writeTime Entry write time, used to ignore entries that are too old.
 */
public void reportOperationFromWal(long group, long nonce, long writeTime) {
    if (nonce == HConstants.NO_NONCE)
        return;
    // Give the write time some slack in case the clocks are not synchronized.
    long now = EnvironmentEdgeManager.currentTime();
    if (now > writeTime + (deleteNonceGracePeriod * 1.5))
        return;
    OperationContext newResult = new OperationContext();
    newResult.setState(OperationContext.DONT_PROCEED);
    NonceKey nk = new NonceKey(group, nonce);
    OperationContext oldResult = nonces.putIfAbsent(nk, newResult);
    if (oldResult != null) {
        // Some schemes can have collisions (for example, expiring hashes), so just log it.
        // We have no idea about the semantics here, so this is the least of many evils.
        LOG.warn("Nonce collision during WAL recovery: " + nk + ", " + oldResult + " with " + newResult);
    }
}
Also used : NonceKey(org.apache.hadoop.hbase.util.NonceKey)

Example 4 with NonceKey

use of org.apache.hadoop.hbase.util.NonceKey in project hbase by apache.

the class TestProcedureNonce method testRunningProcWithSameNonce.

@Test
public void testRunningProcWithSameNonce() throws Exception {
    final long nonceGroup = 456;
    final long nonce = 33333;
    // register the nonce
    final NonceKey nonceKey = procExecutor.createNonceKey(nonceGroup, nonce);
    assertFalse(procExecutor.registerNonce(nonceKey) >= 0);
    // Submit a proc and use a latch to prevent the step execution until we submitted proc2
    CountDownLatch latch = new CountDownLatch(1);
    TestSingleStepProcedure proc = new TestSingleStepProcedure();
    procEnv.setWaitLatch(latch);
    long procId = procExecutor.submitProcedure(proc, nonceKey);
    while (proc.step != 1) {
        Threads.sleep(25);
    }
    // try to register a procedure with the same nonce
    // we should get back the old procId
    assertEquals(procId, procExecutor.registerNonce(nonceKey));
    // complete the procedure
    latch.countDown();
    // Restart, the procedure is not completed yet
    ProcedureTestingUtility.restart(procExecutor);
    ProcedureTestingUtility.waitProcedure(procExecutor, procId);
    // try to register a procedure with the same nonce
    // we should get back the old procId
    assertEquals(procId, procExecutor.registerNonce(nonceKey));
    Procedure<?> result = procExecutor.getResult(procId);
    ProcedureTestingUtility.assertProcNotFailed(result);
}
Also used : NonceKey(org.apache.hadoop.hbase.util.NonceKey) CountDownLatch(java.util.concurrent.CountDownLatch) Test(org.junit.Test)

Example 5 with NonceKey

use of org.apache.hadoop.hbase.util.NonceKey in project hbase by apache.

the class TestProcedureNonce method testConcurrentNonceRegistration.

private void testConcurrentNonceRegistration(final boolean submitProcedure, final long nonceGroup, final long nonce) throws IOException {
    // register the nonce
    final NonceKey nonceKey = procExecutor.createNonceKey(nonceGroup, nonce);
    final AtomicReference<Throwable> t1Exception = new AtomicReference();
    final AtomicReference<Throwable> t2Exception = new AtomicReference();
    final CountDownLatch t1NonceRegisteredLatch = new CountDownLatch(1);
    final CountDownLatch t2BeforeNonceRegisteredLatch = new CountDownLatch(1);
    final Thread[] threads = new Thread[2];
    threads[0] = new Thread() {

        @Override
        public void run() {
            try {
                // release the nonce and wake t2
                assertFalse("unexpected already registered nonce", procExecutor.registerNonce(nonceKey) >= 0);
                t1NonceRegisteredLatch.countDown();
                // hold the submission until t2 is registering the nonce
                t2BeforeNonceRegisteredLatch.await();
                Threads.sleep(1000);
                if (submitProcedure) {
                    CountDownLatch latch = new CountDownLatch(1);
                    TestSingleStepProcedure proc = new TestSingleStepProcedure();
                    procEnv.setWaitLatch(latch);
                    procExecutor.submitProcedure(proc, nonceKey);
                    Threads.sleep(100);
                    // complete the procedure
                    latch.countDown();
                } else {
                    procExecutor.unregisterNonceIfProcedureWasNotSubmitted(nonceKey);
                }
            } catch (Throwable e) {
                t1Exception.set(e);
            } finally {
                t1NonceRegisteredLatch.countDown();
                t2BeforeNonceRegisteredLatch.countDown();
            }
        }
    };
    threads[1] = new Thread() {

        @Override
        public void run() {
            try {
                // wait until t1 has registered the nonce
                t1NonceRegisteredLatch.await();
                // register the nonce
                t2BeforeNonceRegisteredLatch.countDown();
                assertFalse("unexpected non registered nonce", procExecutor.registerNonce(nonceKey) < 0);
            } catch (Throwable e) {
                t2Exception.set(e);
            } finally {
                t1NonceRegisteredLatch.countDown();
                t2BeforeNonceRegisteredLatch.countDown();
            }
        }
    };
    for (int i = 0; i < threads.length; ++i) {
        threads[i].start();
    }
    for (int i = 0; i < threads.length; ++i) {
        Threads.shutdown(threads[i]);
    }
    ProcedureTestingUtility.waitNoProcedureRunning(procExecutor);
    assertEquals(null, t1Exception.get());
    assertEquals(null, t2Exception.get());
}
Also used : NonceKey(org.apache.hadoop.hbase.util.NonceKey) AtomicReference(java.util.concurrent.atomic.AtomicReference) CountDownLatch(java.util.concurrent.CountDownLatch)

Aggregations

NonceKey (org.apache.hadoop.hbase.util.NonceKey)16 Test (org.junit.Test)4 IOException (java.io.IOException)3 CountDownLatch (java.util.concurrent.CountDownLatch)2 InputStream (java.io.InputStream)1 UncheckedIOException (java.io.UncheckedIOException)1 ArrayList (java.util.ArrayList)1 Map (java.util.Map)1 CopyOnWriteArrayList (java.util.concurrent.CopyOnWriteArrayList)1 AtomicLong (java.util.concurrent.atomic.AtomicLong)1 AtomicReference (java.util.concurrent.atomic.AtomicReference)1 DoNotRetryIOException (org.apache.hadoop.hbase.DoNotRetryIOException)1 InvalidFamilyOperationException (org.apache.hadoop.hbase.InvalidFamilyOperationException)1 ProcedureInfo (org.apache.hadoop.hbase.ProcedureInfo)1 TableName (org.apache.hadoop.hbase.TableName)1 Append (org.apache.hadoop.hbase.client.Append)1 Increment (org.apache.hadoop.hbase.client.Increment)1 Mutation (org.apache.hadoop.hbase.client.Mutation)1 PerClientRandomNonceGenerator (org.apache.hadoop.hbase.client.PerClientRandomNonceGenerator)1 RegionInfo (org.apache.hadoop.hbase.client.RegionInfo)1