use of io.opentracing.ActiveSpan in project sharding-jdbc by shardingjdbc.
the class ExecuteEventListener method listenOverall.
/**
* listen overall sql execution event.
*
* @param event Overall sql execution event.
*/
@Subscribe
@AllowConcurrentEvents
public void listenOverall(final OverallExecutionEvent event) {
Tracer tracer = ShardingJDBCTracer.get();
ActiveSpan activeSpan;
switch(event.getEventExecutionType()) {
case BEFORE_EXECUTE:
activeSpan = tracer.buildSpan("/SJDBC/TRUNK/" + event.getSqlType().name()).withTag(Tags.COMPONENT.getKey(), "ShardingJDBC").startActive();
trunkContainer.set(activeSpan);
if (isParallelExecute(event)) {
ExecutorDataMap.getDataMap().put(SNAPSHOT_DATA_KEY, activeSpan.capture());
}
break;
case EXECUTE_FAILURE:
activeSpan = trunkContainer.get();
activeSpan.setTag(Tags.ERROR.getKey(), true);
if (event.getException().isPresent()) {
activeSpan.log(System.currentTimeMillis(), log(event.getException().get()));
}
deactivate();
break;
case EXECUTE_SUCCESS:
deactivate();
break;
default:
throw new ShardingJdbcException("Unsupported event type");
}
}
use of io.opentracing.ActiveSpan in project batfish by batfish.
the class BdpEngine method computeDependentRoutesIteration.
private void computeDependentRoutesIteration(Map<String, Node> nodes, Topology topology, BdpDataPlane dp, int dependentRoutesIterations, SortedSet<Prefix> oscillatingPrefixes) {
// (Re)initialization of dependent route calculation
AtomicInteger reinitializeDependentCompleted = _newBatch.apply("Iteration " + dependentRoutesIterations + ": Reinitialize dependent routes", nodes.size());
try (ActiveSpan computeDependentRoutesSpan = GlobalTracer.get().buildSpan(String.format("Compute dependent routes, iteration:%d", dependentRoutesIterations)).startActive()) {
// avoid unused warning
assert computeDependentRoutesSpan != null;
try (ActiveSpan moveRibsSpan = GlobalTracer.get().buildSpan("Move dependent routes").startActive()) {
// avoid unused warning
assert moveRibsSpan != null;
nodes.values().parallelStream().forEach(n -> {
for (VirtualRouter vr : n._virtualRouters.values()) {
/*
* For RIBs that require comparision to previous version,
* call a function that stores existing ribs
* as previous RIBs, then re-initializes current RIBs
*/
vr.moveRibs();
/*
* For RIBs that do not require comparison to previous version, just re-init
*/
vr.reinitRibsNewIteration();
}
reinitializeDependentCompleted.incrementAndGet();
});
}
try (ActiveSpan activeStaticRoutesSpan = GlobalTracer.get().buildSpan("Activate static routes").startActive()) {
// avoid unused warning
assert activeStaticRoutesSpan != null;
// Static nextHopIp routes
AtomicInteger recomputeStaticCompleted = _newBatch.apply("Iteration " + dependentRoutesIterations + ": Recompute static routes with next-hop IP", nodes.size());
nodes.values().parallelStream().forEach(n -> {
boolean staticChanged;
do {
staticChanged = false;
for (VirtualRouter vr : n._virtualRouters.values()) {
staticChanged |= vr.activateStaticRoutes();
}
} while (staticChanged);
recomputeStaticCompleted.incrementAndGet();
});
}
// Generated/aggregate routes
AtomicInteger recomputeAggregateCompleted = _newBatch.apply("Iteration " + dependentRoutesIterations + ": Recompute aggregate/generated routes", nodes.size());
try (ActiveSpan activeGeneratedRoutesSpan = GlobalTracer.get().buildSpan("Activate generated routes").startActive()) {
// avoid unused warning
assert activeGeneratedRoutesSpan != null;
nodes.values().parallelStream().forEach(n -> {
for (VirtualRouter vr : n._virtualRouters.values()) {
vr._generatedRib = new Rib(vr);
while (vr.activateGeneratedRoutes()) {
}
vr.importRib(vr._mainRib, vr._generatedRib);
}
recomputeAggregateCompleted.incrementAndGet();
});
}
// recompute exports
try (ActiveSpan initOspfExportsSpan = GlobalTracer.get().buildSpan("Initialize OSPF exports").startActive()) {
// avoid unused warning
assert initOspfExportsSpan != null;
nodes.values().parallelStream().forEach(n -> {
for (VirtualRouter vr : n._virtualRouters.values()) {
vr.initOspfExports();
}
});
}
// repropagate exports
AtomicBoolean ospfExternalChanged = new AtomicBoolean(true);
int ospfExternalSubIterations = 0;
try (ActiveSpan repropagateOspfExportsSpan = GlobalTracer.get().buildSpan("Repropagate OSPF exports").startActive()) {
// avoid unused warning
assert repropagateOspfExportsSpan != null;
while (ospfExternalChanged.get()) {
ospfExternalSubIterations++;
AtomicInteger propagateOspfExternalCompleted = _newBatch.apply("Iteration " + dependentRoutesIterations + ": Propagate OSPF external routes: subIteration: " + ospfExternalSubIterations, nodes.size());
ospfExternalChanged.set(false);
nodes.values().parallelStream().forEach(n -> {
for (VirtualRouter vr : n._virtualRouters.values()) {
if (vr.propagateOspfExternalRoutes(nodes, topology)) {
ospfExternalChanged.set(true);
}
}
propagateOspfExternalCompleted.incrementAndGet();
});
AtomicInteger unstageOspfExternalCompleted = _newBatch.apply("Iteration " + dependentRoutesIterations + ": Unstage OSPF external routes: subIteration: " + ospfExternalSubIterations, nodes.size());
nodes.values().parallelStream().forEach(n -> {
for (VirtualRouter vr : n._virtualRouters.values()) {
vr.unstageOspfExternalRoutes();
}
unstageOspfExternalCompleted.incrementAndGet();
});
}
}
AtomicInteger importOspfExternalCompleted = _newBatch.apply("Iteration " + dependentRoutesIterations + ": Unstage OSPF external routes", nodes.size());
try (ActiveSpan importOspfExternalRoutesSpan = GlobalTracer.get().buildSpan("Import OSPF external routes").startActive()) {
// avoid unused warning
assert importOspfExternalRoutesSpan != null;
nodes.values().parallelStream().forEach(n -> {
for (VirtualRouter vr : n._virtualRouters.values()) {
vr.importRib(vr._ospfRib, vr._ospfExternalType1Rib);
vr.importRib(vr._ospfRib, vr._ospfExternalType2Rib);
vr.importRib(vr._mainRib, vr._ospfRib);
}
importOspfExternalCompleted.incrementAndGet();
});
}
// first let's initialize nodes-level generated/aggregate routes
try (ActiveSpan initBgpAggregateRoutesSpan = GlobalTracer.get().buildSpan("Initialize BGP aggregate routes").startActive()) {
// avoid unused warning
assert initBgpAggregateRoutesSpan != null;
nodes.values().parallelStream().forEach(n -> {
for (VirtualRouter vr : n._virtualRouters.values()) {
if (vr._vrf.getBgpProcess() != null) {
vr.initBgpAggregateRoutes();
}
}
});
}
AtomicInteger propagateBgpCompleted = _newBatch.apply("Iteration " + dependentRoutesIterations + ": Propagate BGP routes", nodes.size());
try (ActiveSpan propagateBgpRoutesSpan = GlobalTracer.get().buildSpan("Propagate BGP routes").startActive()) {
// avoid unused warning
assert propagateBgpRoutesSpan != null;
nodes.values().parallelStream().forEach(n -> {
for (VirtualRouter vr : n._virtualRouters.values()) {
vr.propagateBgpRoutes(dp.getIpOwners(), dependentRoutesIterations, oscillatingPrefixes, nodes);
}
propagateBgpCompleted.incrementAndGet();
});
}
AtomicInteger importBgpCompleted = _newBatch.apply("Iteration " + dependentRoutesIterations + ": Import BGP routes into respective RIBs", nodes.size());
try (ActiveSpan finalizeBgpRoutesSpan = GlobalTracer.get().buildSpan("Finalize BGP routes").startActive()) {
// avoid unused warning
assert finalizeBgpRoutesSpan != null;
nodes.values().parallelStream().forEach(n -> {
for (VirtualRouter vr : n._virtualRouters.values()) {
BgpProcess proc = vr._vrf.getBgpProcess();
if (proc != null) {
vr.finalizeBgpRoutes(proc.getMultipathEbgp(), proc.getMultipathIbgp());
}
}
importBgpCompleted.incrementAndGet();
});
}
}
}
use of io.opentracing.ActiveSpan in project batfish by batfish.
the class BdpEngine method computeFixedPoint.
/**
* Attempt to compute the fixed point of the data plane.
*
* @param nodes A dictionary of configuration-wrapping Bdp nodes keyed by name
* @param topology The topology representing physical adjacencies between interface of the nodes
* @param dp The output data plane
* @param externalAdverts Optional external BGP advertisements fed into the data plane computation
* @param ae The output answer element in which to store a report of the computation. Also
* contains the current recovery iteration.
* @param recoveryIterationHashCodes Dependent-route computation iteration hash-code dictionaries,
* themselves keyed by outer recovery iteration.
* @return true iff the computation is oscillating
*/
private boolean computeFixedPoint(SortedMap<String, Node> nodes, Topology topology, BdpDataPlane dp, Set<BgpAdvertisement> externalAdverts, BdpAnswerElement ae, SortedMap<Integer, SortedMap<Integer, Integer>> recoveryIterationHashCodes, SortedMap<Integer, SortedSet<Prefix>> iterationOscillatingPrefixes) {
try (ActiveSpan computeFixedPointSpan = GlobalTracer.get().buildSpan("Computing fixed point").startActive()) {
// avoid unused warning
assert computeFixedPointSpan != null;
SortedSet<Prefix> oscillatingPrefixes = ae.getOscillatingPrefixes();
// BEGIN DONE ONCE (except main rib)
// For each virtual router, setup the initial easy-to-do routes and init protocol-based RIBs:
AtomicInteger initialCompleted = _newBatch.apply("Compute initial connected and static routes, ospf setup, bgp setup", nodes.size());
try (ActiveSpan initRibsBdpSpan = GlobalTracer.get().buildSpan("Initializing easy routes for BDP").startActive()) {
// avoid unused warning
assert initRibsBdpSpan != null;
nodes.values().parallelStream().forEach(n -> {
for (VirtualRouter vr : n._virtualRouters.values()) {
vr.initRibsForBdp(dp.getIpOwners(), externalAdverts);
}
initialCompleted.incrementAndGet();
});
}
// OSPF internal routes
int numOspfInternalIterations;
try (ActiveSpan ospfInternalRoutesSpan = GlobalTracer.get().buildSpan("Initializing OSPF internal routes").startActive()) {
assert ospfInternalRoutesSpan != null;
numOspfInternalIterations = initOspfInternalRoutes(nodes, topology);
}
// RIP internal routes
try (ActiveSpan ripInternalRoutesSpan = GlobalTracer.get().buildSpan("Initializing RIP internal routes").startActive()) {
assert ripInternalRoutesSpan != null;
initRipInternalRoutes(nodes, topology);
}
// Prep for traceroutes
nodes.values().parallelStream().forEach(n -> n._virtualRouters.values().forEach(vr -> {
vr.importRib(vr._mainRib, vr._independentRib);
// Needed for activateStaticRoutes
vr._prevMainRib = vr._mainRib;
vr.activateStaticRoutes();
}));
// Update bgp neighbors with reachability
dp.setNodes(nodes);
computeFibs(nodes);
dp.setTopology(topology);
initRemoteBgpNeighbors(nodes.entrySet().stream().collect(ImmutableMap.toImmutableMap(Entry::getKey, e -> e.getValue().getConfiguration())), dp.getIpOwners(), true, this, dp);
// END DONE ONCE
/*
* Setup maps to track iterations. We need this for oscillation detection.
* Specifically, if we detect that an iteration hashcode (a hash of all the nodes' RIBs)
* has been previously encountered, we go into recovery mode.
* Recovery mode means enabling "lockstep route propagation" for oscillating prefixes.
*
* Lockstep route propagation only allows one of the neighbors to propagate routes for
* oscillating prefixes in a given iteration.
* E.g., lexicographically lower neighbor propagates routes during
* odd iterations, and lex-higher neighbor during even iterations.
*/
Map<Integer, SortedSet<Integer>> iterationsByHashCode = new HashMap<>();
SortedMap<Integer, Integer> iterationHashCodes = new TreeMap<>();
Map<Integer, SortedSet<Route>> iterationRoutes = null;
Map<Integer, SortedMap<String, SortedMap<String, SortedSet<AbstractRoute>>>> iterationAbstractRoutes = null;
if (_settings.getBdpRecordAllIterations()) {
if (_settings.getBdpDetail()) {
iterationAbstractRoutes = new TreeMap<>();
} else {
iterationRoutes = new TreeMap<>();
}
} else if (_maxRecordedIterations > 0) {
if (_settings.getBdpDetail()) {
iterationAbstractRoutes = new LRUMap<>(_maxRecordedIterations);
} else {
iterationRoutes = new LRUMap<>(_maxRecordedIterations);
}
}
AtomicBoolean dependentRoutesChanged = new AtomicBoolean(false);
AtomicBoolean evenDependentRoutesChanged = new AtomicBoolean(false);
AtomicBoolean oddDependentRoutesChanged = new AtomicBoolean(false);
int numDependentRoutesIterations = 0;
// Go into iteration mode, until the routes converge (or oscillation is detected)
do {
numDependentRoutesIterations++;
AtomicBoolean currentChangedMonitor;
if (oscillatingPrefixes.isEmpty()) {
currentChangedMonitor = dependentRoutesChanged;
} else if (numDependentRoutesIterations % 2 == 0) {
currentChangedMonitor = evenDependentRoutesChanged;
} else {
currentChangedMonitor = oddDependentRoutesChanged;
}
currentChangedMonitor.set(false);
computeDependentRoutesIteration(nodes, topology, dp, numDependentRoutesIterations, oscillatingPrefixes);
/* Collect sizes of certain RIBs this iteration */
computeIterationStatistics(nodes, ae, numDependentRoutesIterations);
recordIterationDebugInfo(nodes, dp, iterationRoutes, iterationAbstractRoutes, numDependentRoutesIterations);
// Check to see if hash has changed
AtomicInteger checkFixedPointCompleted = _newBatch.apply("Iteration " + numDependentRoutesIterations + ": Check if fixed-point reached", nodes.size());
// This hashcode uniquely identifies the iteration (i.e., network state)
int iterationHashCode = computeIterationHashCode(nodes);
SortedSet<Integer> iterationsWithThisHashCode = iterationsByHashCode.computeIfAbsent(iterationHashCode, h -> new TreeSet<>());
iterationHashCodes.put(numDependentRoutesIterations, iterationHashCode);
int minNumberOfUnchangedIterationsForConvergence = oscillatingPrefixes.isEmpty() ? 1 : 2;
if (iterationsWithThisHashCode.isEmpty() || (!oscillatingPrefixes.isEmpty() && iterationsWithThisHashCode.equals(Collections.singleton(numDependentRoutesIterations - 1)))) {
iterationsWithThisHashCode.add(numDependentRoutesIterations);
} else if (!iterationsWithThisHashCode.contains(numDependentRoutesIterations - minNumberOfUnchangedIterationsForConvergence)) {
int lowestIterationWithThisHashCode = iterationsWithThisHashCode.first();
int completedOscillationRecoveryAttempts = ae.getCompletedOscillationRecoveryAttempts();
if (!oscillatingPrefixes.isEmpty()) {
completedOscillationRecoveryAttempts++;
ae.setCompletedOscillationRecoveryAttempts(completedOscillationRecoveryAttempts);
}
recoveryIterationHashCodes.put(completedOscillationRecoveryAttempts, iterationHashCodes);
handleOscillation(recoveryIterationHashCodes, iterationRoutes, iterationAbstractRoutes, lowestIterationWithThisHashCode, numDependentRoutesIterations, iterationOscillatingPrefixes, ae);
return true;
}
compareToPreviousIteration(nodes, currentChangedMonitor, checkFixedPointCompleted);
computeFibs(nodes);
initRemoteBgpNeighbors(nodes.entrySet().stream().collect(ImmutableMap.toImmutableMap(Entry::getKey, e -> e.getValue().getConfiguration())), dp.getIpOwners(), true, this, dp);
} while (checkDependentRoutesChanged(dependentRoutesChanged, evenDependentRoutesChanged, oddDependentRoutesChanged, oscillatingPrefixes, numDependentRoutesIterations));
AtomicInteger computeBgpAdvertisementsToOutsideCompleted = _newBatch.apply("Compute BGP advertisements sent to outside", nodes.size());
nodes.values().parallelStream().forEach(n -> {
for (VirtualRouter vr : n._virtualRouters.values()) {
vr.computeBgpAdvertisementsToOutside(dp.getIpOwners());
}
computeBgpAdvertisementsToOutsideCompleted.incrementAndGet();
});
// Set iteration stats in the answer
ae.setOspfInternalIterations(numOspfInternalIterations);
ae.setDependentRoutesIterations(numDependentRoutesIterations);
return false;
}
}
use of io.opentracing.ActiveSpan in project batfish by batfish.
the class BdpEngine method computeDataPlane.
BdpDataPlane computeDataPlane(boolean differentialContext, Map<String, Configuration> configurations, Topology topology, Set<BgpAdvertisement> externalAdverts, BdpAnswerElement ae) {
_logger.resetTimer();
BdpDataPlane dp = new BdpDataPlane();
_logger.info("\n*** COMPUTING DATA PLANE ***\n");
try (ActiveSpan computeDataPlaneSpan = GlobalTracer.get().buildSpan("Computing data plane").startActive()) {
// avoid unused warning
assert computeDataPlaneSpan != null;
try (ActiveSpan computeIpOwnersSpan = GlobalTracer.get().buildSpan("Computing ip owners").startActive()) {
assert computeIpOwnersSpan != null;
Map<Ip, Set<String>> ipOwners = CommonUtil.computeIpOwners(configurations, true);
Map<Ip, String> ipOwnersSimple = CommonUtil.computeIpOwnersSimple(ipOwners);
dp.initIpOwners(configurations, ipOwners, ipOwnersSimple);
}
initRemoteBgpNeighbors(configurations, dp.getIpOwners());
SortedMap<String, Node> nodes = new TreeMap<>();
SortedMap<Integer, SortedMap<Integer, Integer>> recoveryIterationHashCodes = new TreeMap<>();
SortedMap<Integer, SortedSet<Prefix>> iterationOscillatingPrefixes = new TreeMap<>();
do {
configurations.values().forEach(c -> nodes.put(c.getHostname(), new Node(c)));
} while (computeFixedPoint(nodes, topology, dp, externalAdverts, ae, recoveryIterationHashCodes, iterationOscillatingPrefixes));
computeFibs(nodes);
dp.setNodes(nodes);
dp.setTopology(topology);
ae.setVersion(Version.getVersion());
}
_logger.printElapsedTime();
return dp;
}
use of io.opentracing.ActiveSpan in project batfish by batfish.
the class WorkItemTest method testNullActiveSpan.
@Test
public void testNullActiveSpan() {
_workItem.setSourceSpan(null, _mockTracer);
SpanContext sourceSpanContext = _workItem.getSourceSpan(_mockTracer);
assertThat(sourceSpanContext, nullValue());
try (ActiveSpan childSpan = _mockTracer.buildSpan("test dangling child").addReference(References.FOLLOWS_FROM, sourceSpanContext).startActive()) {
assertThat(childSpan, notNullValue());
assertThat(childSpan, instanceOf(ThreadLocalActiveSpan.class));
}
}
Aggregations