use of org.voltdb.messaging.InitiateResponseMessage 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;
}
use of org.voltdb.messaging.InitiateResponseMessage in project voltdb by VoltDB.
the class SpScheduler method deliverReadyTxns.
/**
* Poll the replay sequencer and process the messages until it returns null
*/
private void deliverReadyTxns() {
// First, pull all the sequenced messages, if any.
VoltMessage m = m_replaySequencer.poll();
while (m != null) {
deliver(m);
m = m_replaySequencer.poll();
}
// Then, try to pull all the drainable messages, if any.
m = m_replaySequencer.drain();
while (m != null) {
if (m instanceof Iv2InitiateTaskMessage) {
// Send IGNORED response for all SPs
Iv2InitiateTaskMessage task = (Iv2InitiateTaskMessage) m;
final InitiateResponseMessage response = new InitiateResponseMessage(task);
response.setResults(new ClientResponseImpl(ClientResponse.UNEXPECTED_FAILURE, new VoltTable[0], ClientResponseImpl.IGNORED_TRANSACTION));
m_mailbox.send(response.getInitiatorHSId(), response);
}
m = m_replaySequencer.drain();
}
}
use of org.voltdb.messaging.InitiateResponseMessage in project voltdb by VoltDB.
the class MpScheduler method updateReplicas.
@Override
public void updateReplicas(final List<Long> replicas, final Map<Integer, Long> partitionMasters) {
// Handle startup and promotion semi-gracefully
m_iv2Masters.clear();
m_iv2Masters.addAll(replicas);
m_partitionMasters.clear();
m_partitionMasters.putAll(partitionMasters);
if (!m_isLeader) {
return;
}
// Stolen from SpScheduler. Need to update the duplicate counters associated with any EveryPartitionTasks
// Cleanup duplicate counters and collect DONE counters
// in this list for further processing.
List<Long> doneCounters = new LinkedList<Long>();
for (Entry<Long, DuplicateCounter> entry : m_duplicateCounters.entrySet()) {
DuplicateCounter counter = entry.getValue();
int result = counter.updateReplicas(m_iv2Masters);
if (result == DuplicateCounter.DONE) {
doneCounters.add(entry.getKey());
}
}
// Maintain the CI invariant that responses arrive in txnid order.
Collections.sort(doneCounters);
for (Long key : doneCounters) {
DuplicateCounter counter = m_duplicateCounters.remove(key);
VoltMessage resp = counter.getLastResponse();
if (resp != null && resp instanceof InitiateResponseMessage) {
InitiateResponseMessage msg = (InitiateResponseMessage) resp;
if (msg.shouldCommit()) {
m_repairLogTruncationHandle = m_repairLogAwaitingCommit;
m_repairLogAwaitingCommit = msg.getTxnId();
}
m_outstandingTxns.remove(msg.getTxnId());
m_mailbox.send(counter.m_destinationId, resp);
} else {
hostLog.warn("TXN " + counter.getTxnId() + " lost all replicas and " + "had no responses. This should be impossible?");
}
}
MpRepairTask repairTask = new MpRepairTask((InitiatorMailbox) m_mailbox, replicas);
m_pendingTasks.repair(repairTask, replicas, partitionMasters);
}
use of org.voltdb.messaging.InitiateResponseMessage in project voltdb by VoltDB.
the class SpProcedureTask method runFromTaskLog.
// This is an ugly copy/paste mix of run() and completeInitiateTask()
// that avoids using the mailbox -- since no response should be
// generated...
@Override
public void runFromTaskLog(SiteProcedureConnection siteConnection) {
LatencyWatchdog.pet();
if (HOST_TRACE_ENABLED) {
hostLog.trace("START replaying txn: " + this);
}
if (!m_txnState.isReadOnly()) {
m_txnState.setBeginUndoToken(siteConnection.getLatestUndoToken());
}
// cast up here .. ugly.
SpTransactionState txnState = (SpTransactionState) m_txnState;
final InitiateResponseMessage response = processInitiateTask(txnState.m_initiationMsg, siteConnection);
if (!response.shouldCommit()) {
m_txnState.setNeedsRollback(true);
}
if (!m_txnState.isReadOnly()) {
assert (siteConnection.getLatestUndoToken() != Site.kInvalidUndoToken) : "[SP][RW] transaction found invalid latest undo token state in Iv2ExecutionSite.";
assert (siteConnection.getLatestUndoToken() >= m_txnState.getBeginUndoToken()) : "[SP][RW] transaction's undo log token farther advanced than latest known value.";
assert (m_txnState.getBeginUndoToken() != Site.kInvalidUndoToken) : "[SP][RW] with invalid undo token in completeInitiateTask.";
// the truncation point token SHOULD be part of m_txn. However, the
// legacy interaces don't work this way and IV2 hasn't changed this
// ownership yet. But truncateUndoLog is written assuming the right
// eventual encapsulation.
siteConnection.truncateUndoLog(m_txnState.needsRollback(), m_txnState.getBeginUndoToken(), m_txnState.m_spHandle, m_txnState.getUndoLog());
}
m_txnState.setDone();
if (EXEC_TRACE_ENABLED) {
execLog.l7dlog(Level.TRACE, LogKeys.org_voltdb_ExecutionSite_SendingCompletedWUToDtxn.name(), null);
}
if (HOST_TRACE_ENABLED) {
hostLog.trace("COMPLETE replaying txn: " + this);
}
logToDR(siteConnection.getDRGateway(), txnState, response);
}
use of org.voltdb.messaging.InitiateResponseMessage in project voltdb by VoltDB.
the class SpProcedureTask method runForRejoin.
@Override
public void runForRejoin(SiteProcedureConnection siteConnection, TaskLog taskLog) throws IOException {
LatencyWatchdog.pet();
if (!m_txnState.isReadOnly()) {
taskLog.logTask(m_txnState.getNotice());
}
SpTransactionState txnState = (SpTransactionState) m_txnState;
final InitiateResponseMessage response = new InitiateResponseMessage(txnState.m_initiationMsg);
response.m_sourceHSId = m_initiator.getHSId();
response.setRecovering(true);
// add an empty dummy response
response.setResults(new ClientResponseImpl(ClientResponse.SUCCESS, new VoltTable[0], null));
m_initiator.deliver(response);
}
Aggregations