use of org.voltcore.messaging.TransactionInfoBaseMessage in project voltdb by VoltDB.
the class TestReplaySequencer method testDrain2.
@Test
public void testDrain2() {
ReplaySequencer dut = new ReplaySequencer();
// A bunch of sentinels before some SP transactions
// We need drain to skip the 3 sentinels and get to the SPs.
// need
// mp1
// mp2
// mp3
// sp1
// sp2
// sp3
// sp4
TransactionInfoBaseMessage init1 = makeIv2InitTask(101L);
TransactionInfoBaseMessage sentinel1 = makeSentinel(1L);
TransactionInfoBaseMessage init2 = makeIv2InitTask(102L);
TransactionInfoBaseMessage sentinel2 = makeSentinel(2L);
TransactionInfoBaseMessage init3 = makeIv2InitTask(103L);
TransactionInfoBaseMessage sentinel3 = makeSentinel(3L);
TransactionInfoBaseMessage init4 = makeIv2InitTask(104L);
Assert.assertTrue(dut.offer(1L, sentinel1));
Assert.assertTrue(dut.offer(2L, sentinel2));
Assert.assertTrue(dut.offer(3L, sentinel3));
Assert.assertTrue(dut.offer(101L, init1));
Assert.assertTrue(dut.offer(102L, init2));
Assert.assertTrue(dut.offer(103L, init3));
Assert.assertTrue(dut.offer(104L, init4));
Assert.assertNull(dut.drain());
// MPI EOL
Assert.assertTrue(dut.offer(0L, makeMPIEOL()));
// Now, we need to be able to drain all of the SP inits out in order to respond IGNORING
Assert.assertNull(dut.poll());
Assert.assertEquals(init1, dut.drain());
Assert.assertEquals(init2, dut.drain());
Assert.assertEquals(init3, dut.drain());
Assert.assertEquals(init4, dut.drain());
Assert.assertNull(dut.drain());
}
use of org.voltcore.messaging.TransactionInfoBaseMessage in project voltdb by VoltDB.
the class TestReplaySequencer method testDupInitMsg.
@Test
public void testDupInitMsg() {
ReplaySequencer dut = new ReplaySequencer();
// simple deduping
TransactionInfoBaseMessage init1 = makeIv2InitTask(1L);
Assert.assertFalse(dut.offer(1L, init1));
Assert.assertNotNull(dut.dedupe(1L, init1));
Assert.assertTrue(dut.offer(1L, init1));
Assert.assertNull(dut.poll());
// dedupe with sentinels mixed
TransactionInfoBaseMessage sntl1 = makeSentinel(2L);
TransactionInfoBaseMessage init2 = makeIv2InitTask(3L);
Assert.assertTrue(dut.offer(2L, sntl1));
Assert.assertTrue(dut.offer(3L, init2));
Assert.assertNotNull(dut.dedupe(3L, init2));
Assert.assertTrue(dut.offer(3L, init2));
Assert.assertNull(dut.poll());
TransactionInfoBaseMessage frag1 = makeFragment(2L);
TransactionInfoBaseMessage cmpl1 = makeCompleteTxn(2L);
Assert.assertTrue(dut.offer(2L, frag1));
Assert.assertEquals(frag1, dut.poll());
Assert.assertFalse(dut.offer(2L, cmpl1));
Assert.assertEquals(init2, dut.poll());
Assert.assertNull(dut.poll());
// dedupe with already polled
Assert.assertNotNull(dut.dedupe(1L, init1));
Assert.assertTrue(dut.offer(1L, init1));
Assert.assertNull(dut.poll());
}
use of org.voltcore.messaging.TransactionInfoBaseMessage in project voltdb by VoltDB.
the class TestReplaySequencer method testMPIEOLWithSentinels.
@Test
public void testMPIEOLWithSentinels() {
ReplaySequencer dut = new ReplaySequencer();
TransactionInfoBaseMessage init1 = makeIv2InitTask(101L);
TransactionInfoBaseMessage sentinel1 = makeSentinel(1L);
TransactionInfoBaseMessage init2 = makeIv2InitTask(102L);
TransactionInfoBaseMessage init3 = makeIv2InitTask(103L);
Assert.assertFalse(dut.offer(101L, init1));
Assert.assertNull(dut.poll());
Assert.assertTrue(dut.offer(1L, sentinel1));
Assert.assertNull(dut.poll());
// SPs blocked by the sentinel
Assert.assertTrue(dut.offer(102L, init2));
Assert.assertTrue(dut.offer(103L, init3));
Assert.assertNull(dut.poll());
Assert.assertNull(dut.drain());
// The outstanding sentinel and the MP EOL should
// move us to the draining state
Assert.assertTrue(dut.offer(0L, makeMPIEOL()));
// poll() should shut up and drain should start just
// giving us everything
Assert.assertNull(dut.poll());
Assert.assertEquals(init2, dut.drain());
Assert.assertEquals(init3, dut.drain());
TransactionInfoBaseMessage init4 = makeIv2InitTask(104L);
TransactionInfoBaseMessage sentinel2 = makeSentinel(2L);
TransactionInfoBaseMessage init5 = makeIv2InitTask(105L);
// These SPIs should be offered after sentinel1
Assert.assertTrue(dut.offer(104L, init4));
Assert.assertTrue(dut.offer(2L, sentinel2));
Assert.assertTrue(dut.offer(105L, init5));
Assert.assertNull(dut.poll());
Assert.assertEquals(init4, dut.drain());
Assert.assertEquals(init5, dut.drain());
Assert.assertNull(dut.drain());
}
use of org.voltcore.messaging.TransactionInfoBaseMessage in project voltdb by VoltDB.
the class TestReplaySequencer method testPollsInOrder.
@Test
public void testPollsInOrder() {
TransactionInfoBaseMessage sntl1 = makeSentinel(1L);
TransactionInfoBaseMessage frag1 = makeFragment(1L);
TransactionInfoBaseMessage cmpl1 = makeCompleteTxn(1L);
TransactionInfoBaseMessage sp1a = makeIv2InitTask(100L);
TransactionInfoBaseMessage sp1b = makeIv2InitTask(101L);
TransactionInfoBaseMessage sp1c = makeIv2InitTask(102L);
TransactionInfoBaseMessage sp1d = makeIv2InitTask(103L);
TransactionInfoBaseMessage sntl2 = makeSentinel(2L);
TransactionInfoBaseMessage frag2 = makeFragment(2L);
TransactionInfoBaseMessage cmpl2 = makeCompleteTxn(2L);
TransactionInfoBaseMessage sp2a = makeIv2InitTask(104L);
TransactionInfoBaseMessage sp2b = makeIv2InitTask(105L);
TransactionInfoBaseMessage sp2c = makeIv2InitTask(106L);
TransactionInfoBaseMessage sp2d = makeIv2InitTask(107L);
ReplaySequencer dut = new ReplaySequencer();
// offer all non-fragment work first..
dut.offer(1L, sntl1);
dut.offer(100L, sp1a);
dut.offer(101L, sp1b);
dut.offer(102L, sp1c);
dut.offer(103L, sp1d);
dut.offer(2L, sntl2);
dut.offer(104L, sp2a);
dut.offer(105L, sp2b);
dut.offer(106L, sp2c);
dut.offer(107L, sp2d);
// Nothing satisified.
Assert.assertEquals(null, dut.poll());
// Nothing drained
Assert.assertNull(dut.drain());
// Offer the first fragment to free up the first half.
dut.offer(1L, frag1);
dut.offer(1L, cmpl1);
Assert.assertEquals(frag1, dut.poll());
// CompleteTxn will not be queued, it always forwards to scheduler directly.
Assert.assertEquals(sp1a, dut.poll());
Assert.assertEquals(sp1b, dut.poll());
Assert.assertEquals(sp1c, dut.poll());
Assert.assertEquals(sp1d, dut.poll());
Assert.assertEquals(null, dut.poll());
Assert.assertNull(dut.drain());
// Offer the second fragment to free up the second half
dut.offer(2L, frag2);
dut.offer(2L, cmpl2);
Assert.assertEquals(frag2, dut.poll());
// CompleteTxn will not be queued, it always forwards to scheduler directly.
Assert.assertEquals(sp2a, dut.poll());
Assert.assertEquals(sp2b, dut.poll());
Assert.assertEquals(sp2c, dut.poll());
Assert.assertEquals(sp2d, dut.poll());
Assert.assertEquals(null, dut.poll());
Assert.assertNull(dut.drain());
}
use of org.voltcore.messaging.TransactionInfoBaseMessage in project voltdb by VoltDB.
the class SpScheduler method sequenceForReplay.
/**
* Sequence the message for replay if it's for CL or DR.
*
* @param message
* @return true if the message can be delivered directly to the scheduler,
* false if the message is queued
*/
@Override
public boolean sequenceForReplay(VoltMessage message) {
boolean canDeliver = false;
long sequenceWithUniqueId = Long.MIN_VALUE;
boolean commandLog = (message instanceof TransactionInfoBaseMessage && (((TransactionInfoBaseMessage) message).isForReplay()));
boolean sentinel = message instanceof MultiPartitionParticipantMessage;
boolean replay = commandLog || sentinel;
boolean sequenceForReplay = m_isLeader && replay;
if (replay) {
sequenceWithUniqueId = ((TransactionInfoBaseMessage) message).getUniqueId();
}
if (sequenceForReplay) {
InitiateResponseMessage dupe = m_replaySequencer.dedupe(sequenceWithUniqueId, (TransactionInfoBaseMessage) message);
if (dupe != null) {
// Duplicate initiate task message, send response
m_mailbox.send(dupe.getInitiatorHSId(), dupe);
} else if (!m_replaySequencer.offer(sequenceWithUniqueId, (TransactionInfoBaseMessage) message)) {
canDeliver = true;
} else {
deliverReadyTxns();
}
// If it's a DR sentinel, send an acknowledgement
if (sentinel && !commandLog) {
MultiPartitionParticipantMessage mppm = (MultiPartitionParticipantMessage) message;
final InitiateResponseMessage response = new InitiateResponseMessage(mppm);
ClientResponseImpl clientResponse = new ClientResponseImpl(ClientResponseImpl.UNEXPECTED_FAILURE, new VoltTable[0], ClientResponseImpl.IGNORED_TRANSACTION);
response.setResults(clientResponse);
m_mailbox.send(response.getInitiatorHSId(), response);
}
} else {
if (replay) {
// Update last seen and last polled uniqueId for replicas
m_replaySequencer.updateLastSeenUniqueId(sequenceWithUniqueId, (TransactionInfoBaseMessage) message);
m_replaySequencer.updateLastPolledUniqueId(sequenceWithUniqueId, (TransactionInfoBaseMessage) message);
}
canDeliver = true;
}
return canDeliver;
}
Aggregations