[tor-commits] [onionperf/master] Let TGen client finish by itself in one-shot mode.
karsten at torproject.org
karsten at torproject.org
Tue Sep 1 20:40:04 UTC 2020
commit 959cf3689106189001a83c7e58dc40e10497a081
Author: Philipp Winter <phw at nymity.ch>
Date: Fri Aug 7 14:48:58 2020 -0700
Let TGen client finish by itself in one-shot mode.
We tell TGen client to finish on its own by passing the count option to
the end node:
https://github.com/shadow/tgen/blob/master/doc/TGen-Options.md#end-options
This patch adds another argument to the function watchdog_thread_task(),
no_relaunch, which instructs the function to not re-launch its process
if it fails.
---
onionperf/measurement.py | 45 +++++++++++++++++++++++----------------------
onionperf/model.py | 3 ++-
2 files changed, 25 insertions(+), 23 deletions(-)
diff --git a/onionperf/measurement.py b/onionperf/measurement.py
index e2d8d1c..d699292 100644
--- a/onionperf/measurement.py
+++ b/onionperf/measurement.py
@@ -50,10 +50,11 @@ def readline_thread_task(instream, q):
# wait for lines from stdout until the EOF
for line in iter(instream.readline, b''): q.put(line)
-def watchdog_thread_task(cmd, cwd, writable, done_ev, send_stdin, ready_search_str, ready_ev):
+def watchdog_thread_task(cmd, cwd, writable, done_ev, send_stdin, ready_search_str, ready_ev, no_relaunch):
- # launch or re-launch our sub process until we are told to stop
- # if we fail too many times in too short of time, give up and exit
+ # launch or re-launch (or don't re-launch, if no_relaunch is set) our sub
+ # process until we are told to stop if we fail too many times in too short
+ # of time, give up and exit
failure_times = []
pause_time_seconds = 0
while done_ev.is_set() is False:
@@ -105,6 +106,10 @@ def watchdog_thread_task(cmd, cwd, writable, done_ev, send_stdin, ready_search_s
subp.wait()
elif done_ev.is_set():
logging.info("command '{}' finished as expected".format(cmd))
+ elif no_relaunch:
+ logging.info("command '{}' finished on its own".format(cmd))
+ # our command finished on its own. time to terminate.
+ done_ev.set()
else:
logging.warning("command '{}' finished before expected".format(cmd))
now = time.time()
@@ -284,15 +289,9 @@ class Measurement(object):
time.sleep(1)
while True:
if tgen_model.num_transfers:
- downloads = 0
- while True:
- downloads = self.__get_download_count(tgen_client_writable.filename)
- time.sleep(1)
- if downloads >= tgen_model.num_transfers:
- logging.info("Onionperf has downloaded %d files and will now shut down." % tgen_model.num_transfers)
- break
- else:
- continue
+ # This function blocks until our TGen client process
+ # terminated on its own.
+ self.__wait_for_tgen_client()
break
if self.__is_alive():
@@ -366,7 +365,10 @@ class Measurement(object):
logging.info("Logging TGen {1} process output to {0}".format(tgen_logpath, name))
tgen_cmd = "{0} {1}".format(self.tgen_bin_path, tgen_confpath)
- tgen_args = (tgen_cmd, tgen_datadir, tgen_writable, self.done_event, None, None, None)
+ # If we're running in "one-shot mode", TGen client will terminate on
+ # its own and we don't need our watchdog to restart the process.
+ no_relaunch = (name == "client" and tgen_model_conf.num_transfers)
+ tgen_args = (tgen_cmd, tgen_datadir, tgen_writable, self.done_event, None, None, None, no_relaunch)
tgen_watchdog = threading.Thread(target=watchdog_thread_task, name="tgen_{0}_watchdog".format(name), args=tgen_args)
tgen_watchdog.start()
self.threads.append(tgen_watchdog)
@@ -464,7 +466,7 @@ WarnUnsafeSocks 0\nSafeLogging 0\nMaxCircuitDirtiness 60 seconds\nDataDirectory
tor_stdin_bytes = str_tools._to_bytes(tor_config)
tor_ready_str = "Bootstrapped 100"
tor_ready_ev = threading.Event()
- tor_args = (tor_cmd, tor_datadir, tor_writable, self.done_event, tor_stdin_bytes, tor_ready_str, tor_ready_ev)
+ tor_args = (tor_cmd, tor_datadir, tor_writable, self.done_event, tor_stdin_bytes, tor_ready_str, tor_ready_ev, False)
tor_watchdog = threading.Thread(target=watchdog_thread_task, name="tor_{0}_watchdog".format(name), args=tor_args)
tor_watchdog.start()
self.threads.append(tor_watchdog)
@@ -491,14 +493,13 @@ WarnUnsafeSocks 0\nSafeLogging 0\nMaxCircuitDirtiness 60 seconds\nDataDirectory
return tor_writable, torctl_writable
- def __get_download_count(self, tgen_logpath):
- count = 0
- if tgen_logpath is not None and os.path.exists(tgen_logpath):
- with open(tgen_logpath, 'r') as fin:
- for line in fin:
- if re.search("transfer-complete", line) is not None:
- count += 1
- return count
+ def __wait_for_tgen_client(self):
+ logging.info("Waiting for TGen client to finish.")
+ for t in self.threads:
+ if t.getName() == "tgen_client_watchdog":
+ while t.is_alive():
+ time.sleep(1)
+ logging.info("TGen client finished.")
def __is_alive(self):
all_alive = True
diff --git a/onionperf/model.py b/onionperf/model.py
index a4af2fc..bdd5a53 100644
--- a/onionperf/model.py
+++ b/onionperf/model.py
@@ -118,7 +118,8 @@ class TorperfModel(GeneratableTGenModel):
if i > 0:
g.add_edge("pause-%d" % (i-1), "stream-%d" % i)
- g.add_node("end")
+ g.add_node("end",
+ count=str(self.config.num_transfers))
g.add_edge("pause", "stream-0")
g.add_edge("pause-%d" % (self.config.num_transfers - 1), "end")
More information about the tor-commits
mailing list