def run_speedtest(args, conf): write_start_ts(conf) controller, _ = stem_utils.init_controller( path=conf['tor']['control_socket']) if not controller: controller = stem_utils.launch_tor(conf) else: log.warning( 'Is sbws already running? ' 'We found an existing Tor process at %s. We are not going to ' 'launch Tor, nor are we going to try to configure it to behave ' 'like we expect. This might work okay, but it also might not. ' 'If you experience problems, you should try letting sbws launch ' 'Tor for itself. The ability to use an already running Tor only ' 'exists for sbws developers. It is expected to be broken and may ' 'even lead to messed up results.', conf['tor']['control_socket']) time.sleep(15) assert stem_utils.is_controller_okay(controller) cb = CB(args, conf, controller) rl = RelayList(args, conf, controller) rd = ResultDump(args, conf, end_event) rp = RelayPrioritizer(args, conf, rl, rd) destinations, error_msg = DestinationList.from_config( conf, cb, rl, controller) if not destinations: fail_hard(error_msg) max_pending_results = conf.getint('scanner', 'measurement_threads') pool = Pool(max_pending_results) pending_results = [] while True: for target in rp.best_priority(): log.debug('Measuring %s %s', target.nickname, target.fingerprint[0:8]) callback = result_putter(rd) callback_err = result_putter_error(target) async_result = pool.apply_async( dispatch_worker_thread, [args, conf, destinations, cb, rl, target], {}, callback, callback_err) pending_results.append(async_result) while len(pending_results) >= max_pending_results: time.sleep(5) pending_results = [r for r in pending_results if not r.ready()]
def persistent_launch_tor(conf): cont = launch_tor(conf) return cont
def run_speedtest(args, conf): """Initializes all the data and threads needed to measure the relays. It launches or connect to Tor in a thread. It initializes the list of relays seen in the Tor network. It starts a thread to read the previous measurements and wait for new measurements to write them to the disk. It initializes a class that will be used to order the relays depending on their measurements age. It initializes the list of destinations that will be used for the measurements. It initializes the thread pool that will launch the measurement threads. The pool starts 3 other threads that are not the measurement (worker) threads. Finally, it calls the function that will manage the measurement threads. """ global rd, pool, controller controller, _ = stem_utils.init_controller( path=conf.getpath('tor', 'control_socket')) if not controller: controller = stem_utils.launch_tor(conf) else: log.warning( 'Is sbws already running? ' 'We found an existing Tor process at %s. We are not going to ' 'launch Tor, nor are we going to try to configure it to behave ' 'like we expect. This might work okay, but it also might not. ' 'If you experience problems, you should try letting sbws launch ' 'Tor for itself. The ability to use an already running Tor only ' 'exists for sbws developers. It is expected to be broken and may ' 'even lead to messed up results.', conf.getpath('tor', 'control_socket')) time.sleep(15) # When there will be a refactor where conf is global, this can be removed # from here. state = State(conf.getpath('paths', 'state_fname')) # XXX: tech-debt: create new function to obtain the controller and to # write the state, so that a unit test to check the state tor version can # be created # Store tor version whenever the scanner starts. state['tor_version'] = str(controller.get_version()) # Call only once to initialize http_headers settings.init_http_headers(conf.get('scanner', 'nickname'), state['uuid'], state['tor_version']) # To do not have to pass args and conf to RelayList, pass an extra # argument with the data_period measurements_period = conf.getint('general', 'data_period') rl = RelayList(args, conf, controller, measurements_period, state) cb = CB(args, conf, controller, rl) rd = ResultDump(args, conf) rp = RelayPrioritizer(args, conf, rl, rd) destinations, error_msg = DestinationList.from_config( conf, cb, rl, controller) if not destinations: fail_hard(error_msg) max_pending_results = conf.getint('scanner', 'measurement_threads') pool = Pool(max_pending_results) try: main_loop(args, conf, controller, rl, cb, rd, rp, destinations, pool) except KeyboardInterrupt: log.info("Interrupted by the user.") stop_threads(signal.SIGINT, None) # Any exception not catched at this point would make the scanner stall. # Log it and exit gracefully. except Exception as e: log.critical(FILLUP_TICKET_MSG) log.exception(e) stop_threads(signal.SIGTERM, None, 1)