1 import multiprocessing
2
3 -def dispatch(func, args=(), kwargs={}, timeout=60, process=True):
4 """Dispatch a function call to a separate process or thread to execute with
5 a maximum provided timeout. Note that in almost all occurrences a separate
6 process should be used as otherwise we might end up with out-of-order
7 locking mechanism instances, resulting in undefined behavior later on."""
8 def worker(conn, func, *args, **kwargs):
9 conn.send(func(*args, **kwargs))
10 conn.close()
11
12 if not isinstance(args, tuple) or not isinstance(kwargs, dict):
13 raise RuntimeError("args must be a tuple and kwargs a dict")
14
15 if not process:
16 raise RuntimeError("no support yet for dispatch(process=False)")
17
18 parent, child = multiprocessing.Pipe()
19 p = multiprocessing.Process(
20 target=worker, args=(child, func) + args, kwargs=kwargs
21 )
22 p.start()
23 p.join(timeout)
24 if p.is_alive():
25 p.terminate()
26 parent.close()
27 return
28
29 ret = parent.recv()
30 parent.close()
31 return ret
32