Skip to content

Instantly share code, notes, and snippets.

@braingineer
Created January 17, 2016 01:06
Show Gist options
  • Save braingineer/00b8cc1366d502770d1f to your computer and use it in GitHub Desktop.
Save braingineer/00b8cc1366d502770d1f to your computer and use it in GitHub Desktop.
Wraps a function in a process that terminates after s seconds. returns None if process terminates else returns result.
"""
Inspired from [1] and [2], but neither fit my need.
The following lets you decorate a function with a time limit, kills it when it doesn't finish in that time.
The needed part for me was that I had to get the result if it didn't get killed and None if it did.
The following accomplished this.
[1] http://stackoverflow.com/a/26664130
[2] https://gist.github.com/aaronchall/6331661fe0185c30a0b4
"""
from __future__ import print_function
import sys
import threading
from time import sleep
import multiprocessing
def exit_after(s):
'''
use as decorator to exit process if
function takes longer than s seconds
'''
def outer(fn):
q = multiprocessing.Queue()
def surrogate(*args, **kwargs):
r = fn(*args, **kwargs)
q.put(r)
def inner(*args, **kwargs):
p = multiprocessing.Process(target=surrogate, args=args, kwargs=kwargs)
p.start()
p.join(s)
if p.is_alive():
p.terminate()
return None
return q.get(False)
return inner
return outer
@exit_after(1)
def bad_func():
print("Starting bad_func")
sleep(5)
print("Ending bad_func")
return 5
@exit_after(1)
def good_func():
print("good func")
return 2
def test():
print("starting test")
r = bad_func()
print("bad_func returned; result should be None. it =", r)
r = good_func()
print("good func returned. it should equal 2. it =", r)
print("ending test")
if __name__ == "__main__":
test()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment