def buildTxn(self, counter, resumeTxn=False): """ Constructs a new transaction instance :param counter: counter with probe and sample data """ txnId = None self.suspendingTxn = False if resumeTxn: txnId = counter.data txn = Transaction(counter, txnId) self.resumeFragment = self.fragments.addResumeFragment(txnId, txn) return txn self.resumeFragment = None self.nextFragmentId += 1 return Transaction(counter, self.nextFragmentId)
def loadCounter(self, counter): """ Associates the given counter to a transaction :param counter: Counter with probe and sample data :type counter: xpedite.types.Counter """ self.processedCounterCount += 1 userProbe = self.probeMap.get(counter.probe, None) if self.currentTxn: if userProbe: if not userProbe.isAnonymous: self.markCounter(counter) if counter.txnId or userProbe.isAnonymous: if userProbe.isAnonymous or counter.txnId == self.currentTxn.txnId: self.currentTxn.addCounter(counter, False) else: if self.distortionCount == 0: self.appendTxn(self.currentTxn) self.currentTxn = Transaction(counter, counter.txnId) else: self.distortionCount -= 1 self.compromisedTxns.append(self.currentTxn) self.currentTxn = Transaction(counter, counter.txnId) else: # explicit probe missing id likely compromised - skip this and the next transaction self.currentTxn.addCounter(counter, False) self.distortionCount = 2 else: self.currentTxn.addCounter(counter, False) elif userProbe and not userProbe.isAnonymous and self.markCounter(counter): self.currentTxn = Transaction(counter, counter.txnId) else: self.nonTxnCounters.append(counter)
class ChaoticTxnLoader(AbstractTxnLoader): """Loads transactions from counters with tolerance for compromised transactions""" def __init__(self, name, cpuInfo, probes, topdownMetrics, events): """ Constructs a transaction loader resilient to data corruption :param name: Name of the profile being loaded :param probes: List of probes enabled for the profile session :param topdownMetrics: Top down metrics to be computed :param events: PMU events collected for the profile session """ AbstractTxnLoader.__init__(self, name, cpuInfo, probes, topdownMetrics, events) self.distortionCount = 0 @staticmethod def markCounter(counter): """ Extracts transaction id from the given counter :param counter: Counter with transaction id """ if counter.data and len(counter.data) >= 8: idIndex = len(counter.data)-8 counter.txnId = int(counter.data[idIndex:], 16) counter.data = counter.data[0:idIndex] return counter.txnId def loadCounter(self, counter): """ Associates the given counter to a transaction :param counter: Counter with probe and sample data :type counter: xpedite.types.Counter """ self.processedCounterCount += 1 userProbe = self.probeMap.get(counter.probe, None) if self.currentTxn: if userProbe: if not userProbe.isAnonymous: self.markCounter(counter) if counter.txnId or userProbe.isAnonymous: if userProbe.isAnonymous or counter.txnId == self.currentTxn.txnId: self.currentTxn.addCounter(counter, False) else: if self.distortionCount == 0: self.appendTxn(self.currentTxn) self.currentTxn = Transaction(counter, counter.txnId) else: self.distortionCount -= 1 self.compromisedTxns.append(self.currentTxn) self.currentTxn = Transaction(counter, counter.txnId) else: # explicit probe missing id likely compromised - skip this and the next transaction self.currentTxn.addCounter(counter, False) self.distortionCount = 2 else: self.currentTxn.addCounter(counter, False) elif userProbe and not userProbe.isAnonymous and self.markCounter(counter): self.currentTxn = Transaction(counter, counter.txnId) else: self.nonTxnCounters.append(counter) def endLoad(self): """Marks end of the current load session""" if self.currentTxn: if self.distortionCount == 0: self.appendTxn(self.currentTxn) else: self.compromisedTxns.append(self.currentTxn) self.distortionCount = 0 self.currentTxn = None