Last active
April 20, 2017 14:34
-
-
Save jtallieu/26ced34ee423971c60be5c8e5957ab47 to your computer and use it in GitHub Desktop.
Eagle Eye Networks :: Python screening sample - Exceptions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
::Eagle Eye Networks Inc.::: | |
::Python screening:: | |
The "SummertimeService" will drive you insane. | |
It throws random errors. Summertime it works | |
summertime it don't. | |
Some errors you can ignore and assume worked, | |
others you need to reset the service. | |
Refactor the code that calls the SummertimeService | |
10x's and prints statistics about it's performance. | |
Heed the 'test' function docstring. DO NOT FIX the | |
SummertimeService. | |
""" | |
import random | |
import threading | |
""" | |
DO NOT MODIFY OR FIX THIS CLASS | |
""" | |
class SummertimeService(object): | |
"""Summertime it works, summertime it doesn't""" | |
def reset(self): | |
print "Resetting the SummertimeService" | |
def increment(self): | |
"""DO NOT MODIFY THIS""" | |
# 66.6% chance of finishing clean | |
throw = random.choice([False, False, True]) | |
if not throw: | |
print ">> Clean increment" | |
return True | |
else: | |
exc = random.choice([ | |
### Exceptions that are OK | |
FloatingPointError, # OK | |
OverflowError, # OK | |
ZeroDivisionError, # OK | |
ReferenceError, # OK | |
IndexError, # OK | |
### Exceptions that are failures | |
MemoryError, # Require a reset | |
KeyError, | |
LookupError, | |
### Exceptions that are ERRORS | |
SystemError, | |
IOError | |
]) | |
print ">> !!!Raising {}!!!".format(exc.__name__) | |
raise exc("") | |
### MODIFY ANYTHING BELOW THIS | |
svc = SummertimeService() | |
MUTEX = threading.Lock() | |
lookup_errors = 0 | |
def increment(): | |
"""Be thread safe and avoid deadlock""" | |
global lookup_errors | |
### Service errors to handle | |
failure_exceptions = ['MemoryError', 'KeyError', 'LookupError'] | |
acceptible_errors = [ | |
'FloatingPointError', | |
'OverflowError', | |
'ZeroDivisionError', | |
'ReferenceError', | |
'IndexError' | |
] | |
MUTEX.acquire(True) | |
result = False | |
exc = None | |
try: | |
result = svc.increment() | |
except Exception as e: | |
exc_name = e.__class__.__name__ | |
# ignore exceptions and return True | |
if exc_name in acceptible_errors: | |
result = True | |
#ignore exceptions and return False | |
elif exc_name in failure_exceptions: | |
result = False | |
if exc_name == "MemoryError": | |
svc.reset() | |
else: | |
# errors that propagate out | |
exc = e | |
MUTEX.release() | |
if exc: | |
raise exc | |
return result | |
def test(): | |
""" | |
Increment the service 10x's and collect the stats, | |
count SystemError as an error. Die ungracefully | |
on any other error with a stack trace | |
""" | |
tries = success = fail = errors = 0 | |
for _ in xrange(0, 10): | |
tries += 1 | |
try: | |
if increment(): | |
success += 1 | |
else: | |
fail += 1 | |
except SystemError: | |
errors += 1 | |
print "{} Attempts".format(tries) | |
print "{} success".format(success) | |
print "{} failed".format(fail) | |
print "{} errors".format(errors) | |
print "{} lookup errors".format(lookup_errors) | |
if __name__ == "__main__": | |
test() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment