Loading sbws/core/scanner.py +17 −2 Original line number Diff line number Diff line Loading @@ -29,7 +29,6 @@ from multiprocessing.dummy import Pool import time import os import logging import requests import random from .. import settings Loading Loading @@ -367,6 +366,19 @@ def measure_relay(args, conf, destinations, cb, rl, relay): def dispatch_worker_thread(*a, **kw): # If at the point where the relay is actually going to be measured there # are not any functional destinations or the `end_event` is set, do not # try to start measuring the relay, since it will fail anyway. try: # a[2] is the argument `destinations` functional_destinations = a[2].functional_destinations # In case the arguments or the method change, catch the possible exceptions # but ignore here that there are not destinations. except (IndexError, TypeError): log.debug("Wrong argument or attribute.") functional_destinations = True if not functional_destinations or settings.end_event.is_set(): return None return measure_relay(*a, **kw) Loading Loading @@ -530,7 +542,10 @@ def main_loop(args, conf, controller, relay_list, circuit_builder, result_dump, loop_tstop = time.time() loop_tdelta = (loop_tstop - loop_tstart) / 60 log.debug("Measured %s relays in %s minutes", num_relays, loop_tdelta) # At this point, we know the relays that were queued to be measured. # That does not mean they were actually measured. log.debug("Attempted to measure %s relays in %s minutes", num_relays, loop_tdelta) # In a testing network, exit after first loop if controller.get_conf('TestingTorNetwork') == '1': log.info("In a testing network, exiting after the first loop.") Loading sbws/globals.py +3 −1 Original line number Diff line number Diff line Loading @@ -127,7 +127,9 @@ DESTINATION_VERIFY_CERTIFICATE = True # whether the destination is functional or not. NUM_DESTINATION_ATTEMPTS_STORED = 10 # Time to wait before trying again a destination that wasn't functional. DELTA_SECONDS_RETRY_DESTINATION = 60 * 60 * 3 # Because intermitent failures with CDN destinations, start trying again # after 5 min. DELTA_SECONDS_RETRY_DESTINATION = 60 * 5 # Number of consecutive times a destination can fail before considering it # not functional. MAX_NUM_DESTINATION_FAILURES = 3 Loading sbws/lib/destination.py +24 −11 Original line number Diff line number Diff line Loading @@ -229,12 +229,19 @@ class Destination: the time to try again is incremented and resetted as soon as the destination does not fail. """ # NOTE: does a destination fail because several threads are using # it at the same time? # If a destination fails for 1 minute and there're 3 threads, the # 3 threads will fail. # Failed the last X consecutive times if self._are_last_attempts_failures(): # The log here will appear in all the the queued # relays and threads. log.warning("The last %s times the destination %s failed." "It will not be used again in %s hours.\n", "Disabled for %s minutes.", self._max_num_failures, self.url, self._delta_seconds_retry / 60 / 60) self._delta_seconds_retry / 60) log.warning("Please, add more destinations or increment the " "number of maximum number of consecutive failures " "in the configuration.") Loading Loading @@ -285,19 +292,22 @@ class Destination: return p @staticmethod def from_config(conf_section, max_dl): def from_config(conf_section, max_dl, number_threads): assert 'url' in conf_section url = conf_section['url'] verify = _parse_verify_option(conf_section) try: max_num_failures = conf_section.getint('max_num_failures') # Because one a destination fails, all the threads that are using # it at that moment will fail too, multiply by the number of # threads. max_num_failures = (conf_section.getint('max_num_failures') or MAX_NUM_DESTINATION_FAILURES) except ValueError: log.warning("Configuration max_num_failures is wrong, ignoring.") max_num_failures = None if max_num_failures: # If the operator did not setup the number, set to the default. max_num_failures = MAX_NUM_DESTINATION_FAILURES max_num_failures *= number_threads return Destination(url, max_dl, verify, max_num_failures) else: return Destination(url, max_dl, verify) class DestinationList: Loading Loading @@ -331,7 +341,10 @@ class DestinationList: log.debug('Loading info for destination %s', key) dests.append(Destination.from_config( conf[dest_sec], conf.getint('scanner', 'max_download_size'))) # Multiply by the number of threads since all the threads will # fail at the same time. conf.getint('scanner', 'max_download_size'), conf.getint('scanner', 'measurement_threads'))) if len(dests) < 1: msg = 'No enabled destinations in config. Please see '\ 'docs/source/man_sbws.ini.rst" or "man 5 sbws.ini" ' \ Loading tests/unit/lib/test_destination.py +6 −6 Original line number Diff line number Diff line Loading @@ -5,9 +5,9 @@ from sbws.lib import destination def test_destination_is_functional(): eight_hours_ago = datetime.utcnow() - timedelta(hours=8) four_hours_ago = datetime.utcnow() - timedelta(hours=4) two_hours_ago = datetime.utcnow() - timedelta(hours=2) eleven_mins_ago = datetime.utcnow() - timedelta(minutes=11) six_mins_ago = datetime.utcnow() - timedelta(minutes=6) four_mins_ago = datetime.utcnow() - timedelta(minutes=4) d = destination.Destination('unexistenturl', 0, False) assert d.is_functional() Loading @@ -29,19 +29,19 @@ def test_destination_is_functional(): d.add_failure() d.add_failure() # And last failure was 2h ago d.add_failure(two_hours_ago) d.add_failure(four_mins_ago) assert d._are_last_attempts_failures() assert not d._is_last_try_old_enough() assert not d.is_functional() # But if the last failure was 4h ago, try to use it again # And last failure was 4h ago d.add_failure(four_hours_ago) d.add_failure(six_mins_ago) assert d._is_last_try_old_enough() assert d.is_functional() # If last failure was 8h ago, try to use it again again d.add_failure(eight_hours_ago) d.add_failure(eleven_mins_ago) assert d._is_last_try_old_enough() assert d.is_functional() Loading Loading
sbws/core/scanner.py +17 −2 Original line number Diff line number Diff line Loading @@ -29,7 +29,6 @@ from multiprocessing.dummy import Pool import time import os import logging import requests import random from .. import settings Loading Loading @@ -367,6 +366,19 @@ def measure_relay(args, conf, destinations, cb, rl, relay): def dispatch_worker_thread(*a, **kw): # If at the point where the relay is actually going to be measured there # are not any functional destinations or the `end_event` is set, do not # try to start measuring the relay, since it will fail anyway. try: # a[2] is the argument `destinations` functional_destinations = a[2].functional_destinations # In case the arguments or the method change, catch the possible exceptions # but ignore here that there are not destinations. except (IndexError, TypeError): log.debug("Wrong argument or attribute.") functional_destinations = True if not functional_destinations or settings.end_event.is_set(): return None return measure_relay(*a, **kw) Loading Loading @@ -530,7 +542,10 @@ def main_loop(args, conf, controller, relay_list, circuit_builder, result_dump, loop_tstop = time.time() loop_tdelta = (loop_tstop - loop_tstart) / 60 log.debug("Measured %s relays in %s minutes", num_relays, loop_tdelta) # At this point, we know the relays that were queued to be measured. # That does not mean they were actually measured. log.debug("Attempted to measure %s relays in %s minutes", num_relays, loop_tdelta) # In a testing network, exit after first loop if controller.get_conf('TestingTorNetwork') == '1': log.info("In a testing network, exiting after the first loop.") Loading
sbws/globals.py +3 −1 Original line number Diff line number Diff line Loading @@ -127,7 +127,9 @@ DESTINATION_VERIFY_CERTIFICATE = True # whether the destination is functional or not. NUM_DESTINATION_ATTEMPTS_STORED = 10 # Time to wait before trying again a destination that wasn't functional. DELTA_SECONDS_RETRY_DESTINATION = 60 * 60 * 3 # Because intermitent failures with CDN destinations, start trying again # after 5 min. DELTA_SECONDS_RETRY_DESTINATION = 60 * 5 # Number of consecutive times a destination can fail before considering it # not functional. MAX_NUM_DESTINATION_FAILURES = 3 Loading
sbws/lib/destination.py +24 −11 Original line number Diff line number Diff line Loading @@ -229,12 +229,19 @@ class Destination: the time to try again is incremented and resetted as soon as the destination does not fail. """ # NOTE: does a destination fail because several threads are using # it at the same time? # If a destination fails for 1 minute and there're 3 threads, the # 3 threads will fail. # Failed the last X consecutive times if self._are_last_attempts_failures(): # The log here will appear in all the the queued # relays and threads. log.warning("The last %s times the destination %s failed." "It will not be used again in %s hours.\n", "Disabled for %s minutes.", self._max_num_failures, self.url, self._delta_seconds_retry / 60 / 60) self._delta_seconds_retry / 60) log.warning("Please, add more destinations or increment the " "number of maximum number of consecutive failures " "in the configuration.") Loading Loading @@ -285,19 +292,22 @@ class Destination: return p @staticmethod def from_config(conf_section, max_dl): def from_config(conf_section, max_dl, number_threads): assert 'url' in conf_section url = conf_section['url'] verify = _parse_verify_option(conf_section) try: max_num_failures = conf_section.getint('max_num_failures') # Because one a destination fails, all the threads that are using # it at that moment will fail too, multiply by the number of # threads. max_num_failures = (conf_section.getint('max_num_failures') or MAX_NUM_DESTINATION_FAILURES) except ValueError: log.warning("Configuration max_num_failures is wrong, ignoring.") max_num_failures = None if max_num_failures: # If the operator did not setup the number, set to the default. max_num_failures = MAX_NUM_DESTINATION_FAILURES max_num_failures *= number_threads return Destination(url, max_dl, verify, max_num_failures) else: return Destination(url, max_dl, verify) class DestinationList: Loading Loading @@ -331,7 +341,10 @@ class DestinationList: log.debug('Loading info for destination %s', key) dests.append(Destination.from_config( conf[dest_sec], conf.getint('scanner', 'max_download_size'))) # Multiply by the number of threads since all the threads will # fail at the same time. conf.getint('scanner', 'max_download_size'), conf.getint('scanner', 'measurement_threads'))) if len(dests) < 1: msg = 'No enabled destinations in config. Please see '\ 'docs/source/man_sbws.ini.rst" or "man 5 sbws.ini" ' \ Loading
tests/unit/lib/test_destination.py +6 −6 Original line number Diff line number Diff line Loading @@ -5,9 +5,9 @@ from sbws.lib import destination def test_destination_is_functional(): eight_hours_ago = datetime.utcnow() - timedelta(hours=8) four_hours_ago = datetime.utcnow() - timedelta(hours=4) two_hours_ago = datetime.utcnow() - timedelta(hours=2) eleven_mins_ago = datetime.utcnow() - timedelta(minutes=11) six_mins_ago = datetime.utcnow() - timedelta(minutes=6) four_mins_ago = datetime.utcnow() - timedelta(minutes=4) d = destination.Destination('unexistenturl', 0, False) assert d.is_functional() Loading @@ -29,19 +29,19 @@ def test_destination_is_functional(): d.add_failure() d.add_failure() # And last failure was 2h ago d.add_failure(two_hours_ago) d.add_failure(four_mins_ago) assert d._are_last_attempts_failures() assert not d._is_last_try_old_enough() assert not d.is_functional() # But if the last failure was 4h ago, try to use it again # And last failure was 4h ago d.add_failure(four_hours_ago) d.add_failure(six_mins_ago) assert d._is_last_try_old_enough() assert d.is_functional() # If last failure was 8h ago, try to use it again again d.add_failure(eight_hours_ago) d.add_failure(eleven_mins_ago) assert d._is_last_try_old_enough() assert d.is_functional() Loading