use of org.apache.hadoop.hbase.procedure2.Procedure in project hbase by apache.
the class WALProcedureStore method insert.
@Override
public void insert(final Procedure[] procs) {
if (LOG.isTraceEnabled()) {
LOG.trace("Insert " + Arrays.toString(procs));
}
ByteSlot slot = acquireSlot();
try {
// Serialize the insert
long[] procIds = new long[procs.length];
for (int i = 0; i < procs.length; ++i) {
assert !procs[i].hasParent();
procIds[i] = procs[i].getProcId();
ProcedureWALFormat.writeInsert(slot, procs[i]);
}
// Push the transaction data and wait until it is persisted
pushData(PushType.INSERT, slot, Procedure.NO_PROC_ID, procIds);
} catch (IOException e) {
// We are not able to serialize the procedure.
// this is a code error, and we are not able to go on.
LOG.fatal("Unable to serialize one of the procedure: " + Arrays.toString(procs), e);
throw new RuntimeException(e);
} finally {
releaseSlot(slot);
}
}
use of org.apache.hadoop.hbase.procedure2.Procedure in project hbase by apache.
the class ProcedureExecutor method executeRollback.
/**
* Execute the rollback of the full procedure stack.
* Once the procedure is rolledback, the root-procedure will be visible as
* finished to user, and the result will be the fatal exception.
*/
private LockState executeRollback(final long rootProcId, final RootProcedureState procStack) {
final Procedure rootProc = procedures.get(rootProcId);
RemoteProcedureException exception = rootProc.getException();
if (exception == null) {
exception = procStack.getException();
rootProc.setFailure(exception);
store.update(rootProc);
}
final List<Procedure> subprocStack = procStack.getSubproceduresStack();
assert subprocStack != null : "Called rollback with no steps executed rootProc=" + rootProc;
int stackTail = subprocStack.size();
boolean reuseLock = false;
while (stackTail-- > 0) {
final Procedure proc = subprocStack.get(stackTail);
LockState lockState;
if (!reuseLock && (lockState = acquireLock(proc)) != LockState.LOCK_ACQUIRED) {
// queue waiting for the lock availability
return lockState;
}
lockState = executeRollback(proc);
boolean abortRollback = lockState != LockState.LOCK_ACQUIRED;
abortRollback |= !isRunning() || !store.isRunning();
// If the next procedure is the same to this one
// (e.g. StateMachineProcedure reuse the same instance)
// we can avoid to lock/unlock each step
reuseLock = stackTail > 0 && (subprocStack.get(stackTail - 1) == proc) && !abortRollback;
if (!reuseLock) {
releaseLock(proc, false);
}
// useful to test the procedure recovery.
if (abortRollback) {
return lockState;
}
subprocStack.remove(stackTail);
// if the procedure is kind enough to pass the slot to someone else, yield
if (proc.isYieldAfterExecutionStep(getEnvironment())) {
return LockState.LOCK_YIELD_WAIT;
}
if (proc != rootProc) {
execCompletionCleanup(proc);
}
}
// Finalize the procedure state
LOG.info("Rolled back " + rootProc + " exec-time=" + StringUtils.humanTimeDiff(rootProc.elapsedTime()) + " exception=" + exception.getMessage());
procedureFinished(rootProc);
return LockState.LOCK_ACQUIRED;
}
use of org.apache.hadoop.hbase.procedure2.Procedure in project hbase by apache.
the class TestMasterProcedureScheduler method testYieldWithSharedLockHeld.
@Test
public void testYieldWithSharedLockHeld() throws Exception {
final TableName tableName = TableName.valueOf(name.getMethodName());
queue.addBack(new TestTableProcedure(1, tableName, TableProcedureInterface.TableOperationType.READ));
queue.addBack(new TestTableProcedure(2, tableName, TableProcedureInterface.TableOperationType.READ));
queue.addBack(new TestTableProcedure(3, tableName, TableProcedureInterface.TableOperationType.EDIT));
// fetch and acquire the first shared-lock
Procedure proc1 = queue.poll();
assertEquals(1, proc1.getProcId());
assertEquals(false, queue.waitTableSharedLock(proc1, tableName));
// fetch and acquire the second shared-lock
Procedure proc2 = queue.poll();
assertEquals(2, proc2.getProcId());
assertEquals(false, queue.waitTableSharedLock(proc2, tableName));
// nothing available, until xlock release
assertEquals(null, queue.poll(0));
// put the procs back in the queue
queue.yield(proc2);
queue.yield(proc1);
// fetch from the queue, it should fetch the ones with just added back
proc1 = queue.poll();
assertEquals(1, proc1.getProcId());
proc2 = queue.poll();
assertEquals(2, proc2.getProcId());
// release the xlock
queue.wakeTableSharedLock(proc1, tableName);
queue.wakeTableSharedLock(proc2, tableName);
Procedure proc3 = queue.poll();
assertEquals(3, proc3.getProcId());
}
use of org.apache.hadoop.hbase.procedure2.Procedure in project hbase by apache.
the class TestMasterProcedureScheduler method testYieldWithXLockHeld.
@Test
public void testYieldWithXLockHeld() throws Exception {
final TableName tableName = TableName.valueOf(name.getMethodName());
queue.addBack(new TestTableProcedure(1, tableName, TableProcedureInterface.TableOperationType.EDIT));
queue.addBack(new TestTableProcedure(2, tableName, TableProcedureInterface.TableOperationType.EDIT));
// fetch from the queue and acquire xlock for the first proc
Procedure proc = queue.poll();
assertEquals(1, proc.getProcId());
assertEquals(false, queue.waitTableExclusiveLock(proc, tableName));
// nothing available, until xlock release
assertEquals(null, queue.poll(0));
// put the proc in the queue
queue.yield(proc);
// fetch from the queue, it should be the one with just added back
proc = queue.poll();
assertEquals(1, proc.getProcId());
// release the xlock
queue.wakeTableExclusiveLock(proc, tableName);
proc = queue.poll();
assertEquals(2, proc.getProcId());
}
use of org.apache.hadoop.hbase.procedure2.Procedure in project hbase by apache.
the class TestMasterProcedureScheduler method testInheritedRegionXLock.
@Test
public void testInheritedRegionXLock() {
final TableName tableName = TableName.valueOf(name.getMethodName());
final HRegionInfo region = new HRegionInfo(tableName, Bytes.toBytes("a"), Bytes.toBytes("b"));
queue.addBack(new TestRegionProcedure(1, tableName, TableProcedureInterface.TableOperationType.SPLIT, region));
queue.addBack(new TestRegionProcedure(1, 2, tableName, TableProcedureInterface.TableOperationType.UNASSIGN, region));
queue.addBack(new TestRegionProcedure(3, tableName, TableProcedureInterface.TableOperationType.REGION_EDIT, region));
// fetch the root proc and take the lock on the region
Procedure rootProc = queue.poll();
assertEquals(1, rootProc.getProcId());
assertEquals(false, queue.waitRegion(rootProc, region));
// fetch the sub-proc and take the lock on the region (inherited lock)
Procedure childProc = queue.poll();
assertEquals(2, childProc.getProcId());
assertEquals(false, queue.waitRegion(childProc, region));
// proc-3 will be fetched but it can't take the lock
Procedure proc = queue.poll();
assertEquals(3, proc.getProcId());
assertEquals(true, queue.waitRegion(proc, region));
// release the child lock
queue.wakeRegion(childProc, region);
// nothing in the queue (proc-3 is suspended)
assertEquals(null, queue.poll(0));
// release the root lock
queue.wakeRegion(rootProc, region);
// proc-3 should be now available
proc = queue.poll();
assertEquals(3, proc.getProcId());
assertEquals(false, queue.waitRegion(proc, region));
queue.wakeRegion(proc, region);
}
Aggregations