Skip to content

Instantly share code, notes, and snippets.

@jtallieu
Last active April 20, 2017 14:34
Show Gist options
  • Save jtallieu/26ced34ee423971c60be5c8e5957ab47 to your computer and use it in GitHub Desktop.
Save jtallieu/26ced34ee423971c60be5c8e5957ab47 to your computer and use it in GitHub Desktop.
Eagle Eye Networks :: Python screening sample - Exceptions
"""
::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
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()
@jtallieu
Copy link
Author

jtallieu commented Sep 9, 2016

>> Clean increment
>> !!!Raising FloatingPointError!!!
>> Clean increment
>> !!!Raising KeyError!!!
>> Clean increment
>> !!!Raising MemoryError!!!
Resetting the SummertimeService
>> Clean increment
>> !!!Raising FloatingPointError!!!
>> !!!Raising OverflowError!!!
>> Clean increment

10 Attempts
8 success
2 failed
0 errors
1 lookup errors

@thartley
Copy link

👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment