use of org.voltcore.messaging.TransactionInfoBaseMessage in project voltdb by VoltDB.
the class Site method replayFromTaskLog.
boolean replayFromTaskLog(MinimumRatioMaintainer mrm) throws IOException {
// not yet time to catch-up.
if (m_rejoinState != kStateReplayingRejoin) {
return false;
}
TransactionInfoBaseMessage tibm = m_rejoinTaskLog.getNextMessage();
if (tibm != null) {
mrm.didUnrestricted();
if (tibm instanceof Iv2InitiateTaskMessage) {
Iv2InitiateTaskMessage m = (Iv2InitiateTaskMessage) tibm;
SpProcedureTask t = new SpProcedureTask(m_initiatorMailbox, m.getStoredProcedureName(), null, m);
if (!filter(tibm)) {
m_currentTxnId = t.getTxnId();
m_lastTxnTime = EstTime.currentTimeMillis();
t.runFromTaskLog(this);
}
} else if (tibm instanceof FragmentTaskMessage) {
FragmentTaskMessage m = (FragmentTaskMessage) tibm;
if (global_replay_mpTxn == null) {
global_replay_mpTxn = new ParticipantTransactionState(m.getTxnId(), m);
} else if (global_replay_mpTxn.txnId != m.getTxnId()) {
VoltDB.crashLocalVoltDB("Started a MP transaction during replay before completing " + " open transaction.", false, null);
}
TransactionTask t;
if (m.isSysProcTask()) {
t = new SysprocFragmentTask(m_initiatorMailbox, m, global_replay_mpTxn);
} else {
t = new FragmentTask(m_initiatorMailbox, m, global_replay_mpTxn);
}
if (!filter(tibm)) {
m_currentTxnId = t.getTxnId();
m_lastTxnTime = EstTime.currentTimeMillis();
t.runFromTaskLog(this);
}
} else if (tibm instanceof CompleteTransactionMessage) {
// Only complete transactions that are open...
if (global_replay_mpTxn != null) {
CompleteTransactionMessage m = (CompleteTransactionMessage) tibm;
CompleteTransactionTask t = new CompleteTransactionTask(m_initiatorMailbox, global_replay_mpTxn, null, m);
if (!m.isRestart()) {
global_replay_mpTxn = null;
}
if (!filter(tibm)) {
t.runFromTaskLog(this);
}
}
} else {
VoltDB.crashLocalVoltDB("Can not replay message type " + tibm + " during live rejoin. Unexpected error.", false, null);
}
}
// is wrong. Run MP txns fully kStateRejoining or fully kStateRunning.
if (m_rejoinTaskLog.isEmpty() && global_replay_mpTxn == null) {
setReplayRejoinComplete();
}
return tibm != null;
}
use of org.voltcore.messaging.TransactionInfoBaseMessage in project voltdb by VoltDB.
the class TestSpSchedulerSpHandle method testBasicSpHandleMessageStream.
// Validate the contract on the SP handles generated by the SpScheduler at the master for a partition.
// Every new message replicated by the partition master to its partition
// replicas should have a unique, constantly increasing SP handle.
// Read-only invocations and fragments are not replicated or not advance the internal SP handle
// CompleteTransactionMessages get farmed out everywhere for every MP transaction, regardless of type
@Test
public void testBasicSpHandleMessageStream() throws Exception {
TxnEgo currentHandle = TxnEgo.makeZero(0);
// SpScheduler calls advance before assignment
createObjs();
dut.setLeaderState(true);
List<Long> replicas = new ArrayList<Long>();
replicas.add(2l);
dut.updateReplicas(replicas, null);
int msgcount = 0;
for (int i = 0; i < 4000; i++) {
TransactionInfoBaseMessage msg = msgGen.generateRandomMessageInStream();
dut.deliver(msg);
ArgumentCaptor<TransactionInfoBaseMessage> replmsg = ArgumentCaptor.forClass(TransactionInfoBaseMessage.class);
if (msg.isReadOnly()) {
// Read-only invocations and fragments are not replicated
verify(mbox, times(msgcount)).send(eq(new long[] { 2l }), replmsg.capture());
} else {
msgcount++;
// Capture the InitiateTaskMessage that gets sent to the replica so we can test it,
// use it for response construction, etc.
currentHandle = currentHandle.makeNext();
verify(mbox, times(msgcount)).send(eq(new long[] { 2l }), replmsg.capture());
// assertEquals("Failed on msg: " + replmsg.getValue(),
// currentHandle.getTxnId(), replmsg.getValue().getSpHandle());
}
}
}
use of org.voltcore.messaging.TransactionInfoBaseMessage in project voltdb by VoltDB.
the class TestReplaySequencer method testMPIEOLWithoutSentinels.
@Test
public void testMPIEOLWithoutSentinels() {
ReplaySequencer dut = new ReplaySequencer();
TransactionInfoBaseMessage init1 = makeIv2InitTask(101L);
TransactionInfoBaseMessage init2 = makeIv2InitTask(102L);
TransactionInfoBaseMessage init3 = makeIv2InitTask(103L);
Assert.assertFalse(dut.offer(101L, init1));
Assert.assertFalse(dut.offer(102L, init2));
Assert.assertFalse(dut.offer(103L, init3));
Assert.assertNull(dut.poll());
Assert.assertNull(dut.drain());
Assert.assertTrue(dut.offer(0L, makeMPIEOL()));
TransactionInfoBaseMessage init4 = makeIv2InitTask(104L);
TransactionInfoBaseMessage sentinel2 = makeSentinel(2L);
TransactionInfoBaseMessage init5 = makeIv2InitTask(105L);
Assert.assertFalse(dut.offer(104L, init4));
// This will re-block us and should induce drain()
Assert.assertTrue(dut.offer(2L, sentinel2));
Assert.assertTrue(dut.offer(105L, init5));
Assert.assertNull(dut.poll());
Assert.assertEquals(init5, dut.drain());
Assert.assertNull(dut.drain());
}
use of org.voltcore.messaging.TransactionInfoBaseMessage in project voltdb by VoltDB.
the class TestReplaySequencer method testPollsInOrder3.
@Test
public void testPollsInOrder3() {
TransactionInfoBaseMessage frag1 = makeFragment(1L);
TransactionInfoBaseMessage sp2a = makeIv2InitTask(104L);
TransactionInfoBaseMessage sp2b = makeIv2InitTask(105L);
TransactionInfoBaseMessage sntl1 = makeSentinel(1L);
ReplaySequencer dut = new ReplaySequencer();
// Offer fragment first, should be sequenced
Assert.assertTrue(dut.offer(1L, frag1));
// Offer SPs, should not be sequenced
Assert.assertFalse(dut.offer(104L, sp2a));
Assert.assertFalse(dut.offer(105L, sp2b));
// Offer sentinel to free up the first fragment
Assert.assertTrue(dut.offer(1L, sntl1));
Assert.assertEquals(frag1, dut.poll());
Assert.assertEquals(null, dut.poll());
Assert.assertNull(dut.drain());
}
use of org.voltcore.messaging.TransactionInfoBaseMessage in project voltdb by VoltDB.
the class TestReplaySequencer method testTwoTxnsThenSentinels.
/**
* If the first MP txn rolled back before this partition has executed the
* first fragment, and the MPI sends out the first fragment of the next txn,
* the replay sequencer should hold on to both txns until a sentinel arrives
* to release them in order.
*/
@Test
public void testTwoTxnsThenSentinels() {
boolean result;
ReplaySequencer dut = new ReplaySequencer();
TransactionInfoBaseMessage frag = makeFragment(1L);
TransactionInfoBaseMessage complete = makeCompleteTxn(1L);
TransactionInfoBaseMessage frag3 = makeFragment(2L);
result = dut.offer(1L, frag);
Assert.assertTrue(result);
Assert.assertNull(dut.poll());
Assert.assertNull(dut.drain());
// CompleteTxn will not be queued, it always forwards to scheduler directly.
result = dut.offer(1L, complete);
Assert.assertFalse(result);
Assert.assertNull(dut.poll());
Assert.assertNull(dut.drain());
result = dut.offer(2L, frag3);
Assert.assertTrue(result);
Assert.assertNull(dut.poll());
Assert.assertNull(dut.drain());
Assert.assertTrue(dut.offer(1L, makeSentinel(1L)));
Assert.assertEquals(frag, dut.poll());
Assert.assertNull(dut.poll());
Assert.assertTrue(dut.offer(2L, makeSentinel(2L)));
Assert.assertEquals(frag3, dut.poll());
Assert.assertNull(dut.poll());
Assert.assertNull(dut.drain());
}
Aggregations