// SpSchedulers will see FragmentTaskMessage for: // - The scatter fragment(s) of a multi-part transaction (normal or sysproc) // - Borrow tasks to do the local fragment work if this partition is the // buddy of the MPI. Borrow tasks may include input dependency tables for // aggregation fragments, or not, if it's a replicated table read. // For multi-batch MP transactions, we'll need to look up the transaction state // that gets created when the first batch arrives. // During command log replay a new SP handle is going to be generated, but it really // doesn't matter, it isn't going to be used for anything. void handleFragmentTaskMessage(FragmentTaskMessage message) { FragmentTaskMessage msg = message; long newSpHandle; if (m_isLeader) { // Quick hack to make progress...we need to copy the FragmentTaskMessage // before we start mucking with its state (SPHANDLE). We need to revisit // all the messaging mess at some point. msg = new FragmentTaskMessage( message.getInitiatorHSId(), message.getCoordinatorHSId(), message); // Not going to use the timestamp from the new Ego because the multi-part timestamp is what // should be used TxnEgo ego = advanceTxnEgo(); newSpHandle = ego.getTxnId(); msg.setSpHandle(newSpHandle); if (msg.getInitiateTask() != null) { msg.getInitiateTask().setSpHandle(newSpHandle); // set the handle msg.setInitiateTask( msg.getInitiateTask()); // Trigger reserialization so the new handle is used } /* * If there a replicas to send it to, forward it! * Unless... it's read only AND not a sysproc. Read only sysprocs may expect to be sent * everywhere. * In that case don't propagate it to avoid a determinism check and extra messaging overhead */ if (m_sendToHSIds.length > 0 && (!msg.isReadOnly() || msg.isSysProcTask())) { FragmentTaskMessage replmsg = new FragmentTaskMessage(m_mailbox.getHSId(), m_mailbox.getHSId(), msg); m_mailbox.send(m_sendToHSIds, replmsg); DuplicateCounter counter; /* * Non-determinism should be impossible to happen with MP fragments. * if you see "MP_DETERMINISM_ERROR" as procedure name in the crash logs * something has horribly gone wrong. */ if (message.getFragmentTaskType() != FragmentTaskMessage.SYS_PROC_PER_SITE) { counter = new DuplicateCounter( msg.getCoordinatorHSId(), msg.getTxnId(), m_replicaHSIds, "MP_DETERMINISM_ERROR"); } else { counter = new SysProcDuplicateCounter( msg.getCoordinatorHSId(), msg.getTxnId(), m_replicaHSIds, "MP_DETERMINISM_ERROR"); } m_duplicateCounters.put(new DuplicateCounterKey(msg.getTxnId(), newSpHandle), counter); } } else { newSpHandle = msg.getSpHandle(); setMaxSeenTxnId(newSpHandle); } Iv2Trace.logFragmentTaskMessage(message, m_mailbox.getHSId(), newSpHandle, false); doLocalFragmentOffer(msg); }
private void handleFragmentTaskMessageRepair( List<Long> needsRepair, FragmentTaskMessage message) { // set up duplicate counter. expect exactly the responses corresponding // to needsRepair. These may, or may not, include the local site. List<Long> expectedHSIds = new ArrayList<Long>(needsRepair); DuplicateCounter counter = new DuplicateCounter( message.getCoordinatorHSId(), // Assume that the MPI's HSID hasn't changed message.getTxnId(), expectedHSIds, "MP_DETERMINISM_ERROR"); m_duplicateCounters.put( new DuplicateCounterKey(message.getTxnId(), message.getSpHandle()), counter); // is local repair necessary? if (needsRepair.contains(m_mailbox.getHSId())) { // Sanity check that we really need repair. if (m_outstandingTxns.get(message.getTxnId()) != null) { hostLog.warn( "SPI repair attempted to repair a fragment which it has already seen. " + "This shouldn't be possible."); // Not sure what to do in this event. Crash for now throw new RuntimeException("Attempted to repair with a fragment we've already seen."); } needsRepair.remove(m_mailbox.getHSId()); // make a copy because handleIv2 non-repair case does? FragmentTaskMessage localWork = new FragmentTaskMessage( message.getInitiatorHSId(), message.getCoordinatorHSId(), message); doLocalFragmentOffer(localWork); } // is remote repair necessary? if (!needsRepair.isEmpty()) { FragmentTaskMessage replmsg = new FragmentTaskMessage(m_mailbox.getHSId(), m_mailbox.getHSId(), message); m_mailbox.send(com.google.common.primitives.Longs.toArray(needsRepair), replmsg); } }