def ping(siteA, siteB, ignore_missing_site=False): if isinstance(siteA, str): siteA = Site.get(siteA) if isinstance(siteB, str): siteB = Site.get(siteB) if (siteA is None or siteB is None) and ignore_missing_site: return if siteA is None: raise UserError(UserError.ENTITY_DOES_NOT_EXIST, "site does not exist", data={"site": siteA}) if siteB is None: raise UserError(UserError.ENTITY_DOES_NOT_EXIST, "site does not exist", data={"site": siteB}) key = (siteA, siteB) with pingingLock: if key in pinging: return pinging.add(key) try: try: stats = LinkStatistics.objects.get(siteA=siteA, siteB=siteB) except LinkStatistics.DoesNotExist: stats = LinkStatistics(siteA=siteA, siteB=siteB).save() choices = list(siteA.hosts.all()) hostA = None while choices and not hostA: hostA = random.choice(choices) if hostA.problems(): choices.remove(hostA) hostA = None if not hostA: return choices = list(siteB.hosts.all()) if hostA in choices: choices.remove(hostA) hostB = None while choices and not hostB: hostB = random.choice(choices) if hostB.problems(): choices.remove(hostB) hostB = None if not hostB: return begin = time.time() res = hostA.getProxy().host_ping(hostB.address) end = time.time() logging.logMessage("link measurement", category="link", siteA=siteA.name, siteB=siteB.name, hostA=hostA.name, hostB=hostB.name, result=res) stats.add(LinkMeasurement(begin=begin, end=end, loss=res['loss'], delayAvg=res.get("rtt_avg", 0.0)/2.0, delayStddev=res.get("rtt_mdev", 0.0)/2.0, measurements=res["transmitted"])) finally: with pingingLock: pinging.remove(key)