Reputation: 1096
I am looping over a list and performing some action on each member of the list.
If a member takes too much time (1 sec in this case), I intend to pass it. However the block inside the try
statement is always being processed and is never timing out. I don't understand why.
from eventlet import *
for rule in data:
#Timeout block
t=Timeout(1)
try:
f = expr2bdd(expr(rule))
solutions = satisfy_all(f, count=True)
each_rule["solution"]=solutions
except:
pass
finally:
t.cancel()
Upvotes: 1
Views: 891
Reputation: 5577
Eventlet is a concurrent networking library...
It's not clear what expr2bdd
and satisfy_all
functions do, but most likely they only do some CPU calculations and no disk/network IO. In this case there is no point where Eventlet gets a chance to run and fire timeout exception.
If you have control over expr2bdd
and satisfy_all
functions and there are any kind of loops, place eventlet.sleep(0)
at each iteration. That's Eventlet idiom for "yield control to other coroutines", that's where timeout will be fired.
If you don't have control over said functions, second best option is to run them in a separate process which you can forcefully kill. On POSIX compatible OS (e.g. Linux, *BSD, OSX), you can use os.fork
to run a piece of code in separate process. For maximum portability, use subprocess.Popen([sys.executable,...])
or multiprocessing.Process
. The latter gives higher level API, mainly around easier data exchange (serialization) at the cost of performance overhead, which may be negligible in your case. In any case, basic pattern is this: (in a thread or eventlet coroutine, you start a second process and then .communicate()/join()
on it. Use eventlet.Timeout
or Thread.join()
with timeout. If timeout fires, use p.terminate()
or p.kill()
to stop current calculations.
Upvotes: 1