Eliminate SHUTDOWN_EVENT global

This commit is contained in:
Matt Martz 2018-01-02 16:07:46 -06:00
parent fa2e15ee08
commit 6381ba3742
1 changed files with 71 additions and 32 deletions

View File

@ -51,7 +51,6 @@ class FakeShutdownEvent(object):
# Some global variables we use # Some global variables we use
SHUTDOWN_EVENT = FakeShutdownEvent()
DEBUG = False DEBUG = False
_GLOBAL_DEFAULT_TIMEOUT = object() _GLOBAL_DEFAULT_TIMEOUT = object()
@ -677,18 +676,19 @@ def get_attributes_by_tag_name(dom, tag_name):
return dict(list(elem.attributes.items())) return dict(list(elem.attributes.items()))
def print_dots(current, total, start=False, end=False): def print_dots(shutdown_event):
"""Built in callback function used by Thread classes for printing """Built in callback function used by Thread classes for printing
status status
""" """
def inner(current, total, start=False, end=False):
if SHUTDOWN_EVENT.isSet(): if shutdown_event.isSet():
return return
sys.stdout.write('.') sys.stdout.write('.')
if current + 1 == total and end is True: if current + 1 == total and end is True:
sys.stdout.write('\n') sys.stdout.write('\n')
sys.stdout.flush() sys.stdout.flush()
return inner
def do_nothing(*args, **kwargs): def do_nothing(*args, **kwargs):
@ -698,7 +698,8 @@ def do_nothing(*args, **kwargs):
class HTTPDownloader(threading.Thread): class HTTPDownloader(threading.Thread):
"""Thread class for retrieving a URL""" """Thread class for retrieving a URL"""
def __init__(self, i, request, start, timeout, opener=None): def __init__(self, i, request, start, timeout, opener=None,
shutdown_event=None):
threading.Thread.__init__(self) threading.Thread.__init__(self)
self.request = request self.request = request
self.result = [0] self.result = [0]
@ -710,11 +711,16 @@ class HTTPDownloader(threading.Thread):
else: else:
self._opener = urlopen self._opener = urlopen
if shutdown_event:
self._shutdown_event = shutdown_event
else:
self._shutdown_event = FakeShutdownEvent()
def run(self): def run(self):
try: try:
if (timeit.default_timer() - self.starttime) <= self.timeout: if (timeit.default_timer() - self.starttime) <= self.timeout:
f = self._opener(self.request) f = self._opener(self.request)
while (not SHUTDOWN_EVENT.isSet() and while (not self._shutdown_event.isSet() and
(timeit.default_timer() - self.starttime) <= (timeit.default_timer() - self.starttime) <=
self.timeout): self.timeout):
self.result.append(len(f.read(10240))) self.result.append(len(f.read(10240)))
@ -730,11 +736,16 @@ class HTTPUploaderData(object):
has been reached has been reached
""" """
def __init__(self, length, start, timeout): def __init__(self, length, start, timeout, shutdown_event=None):
self.length = length self.length = length
self.start = start self.start = start
self.timeout = timeout self.timeout = timeout
if shutdown_event:
self._shutdown_event = shutdown_event
else:
self._shutdown_event = FakeShutdownEvent()
self._data = None self._data = None
self.total = [0] self.total = [0]
@ -763,7 +774,7 @@ class HTTPUploaderData(object):
def read(self, n=10240): def read(self, n=10240):
if ((timeit.default_timer() - self.start) <= self.timeout and if ((timeit.default_timer() - self.start) <= self.timeout and
not SHUTDOWN_EVENT.isSet()): not self._shutdown_event.isSet()):
chunk = self.data.read(n) chunk = self.data.read(n)
self.total.append(len(chunk)) self.total.append(len(chunk))
return chunk return chunk
@ -777,7 +788,8 @@ class HTTPUploaderData(object):
class HTTPUploader(threading.Thread): class HTTPUploader(threading.Thread):
"""Thread class for putting a URL""" """Thread class for putting a URL"""
def __init__(self, i, request, start, size, timeout, opener=None): def __init__(self, i, request, start, size, timeout, opener=None,
shutdown_event=None):
threading.Thread.__init__(self) threading.Thread.__init__(self)
self.request = request self.request = request
self.request.data.start = self.starttime = start self.request.data.start = self.starttime = start
@ -791,11 +803,16 @@ class HTTPUploader(threading.Thread):
else: else:
self._opener = urlopen self._opener = urlopen
if shutdown_event:
self._shutdown_event = shutdown_event
else:
self._shutdown_event = FakeShutdownEvent()
def run(self): def run(self):
request = self.request request = self.request
try: try:
if ((timeit.default_timer() - self.starttime) <= self.timeout and if ((timeit.default_timer() - self.starttime) <= self.timeout and
not SHUTDOWN_EVENT.isSet()): not self._shutdown_event.isSet()):
try: try:
f = self._opener(request) f = self._opener(request)
except TypeError: except TypeError:
@ -969,7 +986,7 @@ class Speedtest(object):
"""Class for performing standard speedtest.net testing operations""" """Class for performing standard speedtest.net testing operations"""
def __init__(self, config=None, source_address=None, timeout=10, def __init__(self, config=None, source_address=None, timeout=10,
secure=False): secure=False, shutdown_event=None):
self.config = {} self.config = {}
self._source_address = source_address self._source_address = source_address
@ -978,6 +995,11 @@ class Speedtest(object):
self._secure = secure self._secure = secure
if shutdown_event:
self._shutdown_event = shutdown_event
else:
self._shutdown_event = FakeShutdownEvent()
self.get_config() self.get_config()
if config is not None: if config is not None:
self.config.update(config) self.config.update(config)
@ -1372,9 +1394,14 @@ class Speedtest(object):
def producer(q, requests, request_count): def producer(q, requests, request_count):
for i, request in enumerate(requests): for i, request in enumerate(requests):
thread = HTTPDownloader(i, request, start, thread = HTTPDownloader(
i,
request,
start,
self.config['length']['download'], self.config['length']['download'],
opener=self._opener) opener=self._opener,
shutdown_event=self._shutdown_event
)
thread.start() thread.start()
q.put(thread, True) q.put(thread, True)
callback(i, request_count, start=True) callback(i, request_count, start=True)
@ -1427,7 +1454,12 @@ class Speedtest(object):
for i, size in enumerate(sizes): for i, size in enumerate(sizes):
# We set ``0`` for ``start`` and handle setting the actual # We set ``0`` for ``start`` and handle setting the actual
# ``start`` in ``HTTPUploader`` to get better measurements # ``start`` in ``HTTPUploader`` to get better measurements
data = HTTPUploaderData(size, 0, self.config['length']['upload']) data = HTTPUploaderData(
size,
0,
self.config['length']['upload'],
shutdown_event=self._shutdown_event
)
if pre_allocate: if pre_allocate:
data.pre_allocate() data.pre_allocate()
requests.append( requests.append(
@ -1439,9 +1471,15 @@ class Speedtest(object):
def producer(q, requests, request_count): def producer(q, requests, request_count):
for i, request in enumerate(requests[:request_count]): for i, request in enumerate(requests[:request_count]):
thread = HTTPUploader(i, request[0], start, request[1], thread = HTTPUploader(
i,
request[0],
start,
request[1],
self.config['length']['upload'], self.config['length']['upload'],
opener=self._opener) opener=self._opener,
shutdown_event=self._shutdown_event
)
thread.start() thread.start()
q.put(thread, True) q.put(thread, True)
callback(i, request_count, start=True) callback(i, request_count, start=True)
@ -1477,14 +1515,15 @@ class Speedtest(object):
return self.results.upload return self.results.upload
def ctrl_c(signum, frame): def ctrl_c(shutdown_event):
"""Catch Ctrl-C key sequence and set a SHUTDOWN_EVENT for our threaded """Catch Ctrl-C key sequence and set a SHUTDOWN_EVENT for our threaded
operations operations
""" """
def inner(signum, frame):
SHUTDOWN_EVENT.set() shutdown_event.set()
print_('\nCancelling...') print_('\nCancelling...')
sys.exit(0) sys.exit(0)
return inner
def version(): def version():
@ -1622,10 +1661,10 @@ def printer(string, quiet=False, debug=False, error=False, **kwargs):
def shell(): def shell():
"""Run the full speedtest.net test""" """Run the full speedtest.net test"""
global SHUTDOWN_EVENT, DEBUG global DEBUG
SHUTDOWN_EVENT = threading.Event() shutdown_event = threading.Event()
signal.signal(signal.SIGINT, ctrl_c) signal.signal(signal.SIGINT, ctrl_c(shutdown_event))
args = parse_args() args = parse_args()
@ -1665,7 +1704,7 @@ def shell():
if quiet or debug: if quiet or debug:
callback = do_nothing callback = do_nothing
else: else:
callback = print_dots callback = print_dots(shutdown_event)
printer('Retrieving speedtest.net configuration...', quiet) printer('Retrieving speedtest.net configuration...', quiet)
try: try: