diff --git a/eventlet/hubs/hub.py b/eventlet/hubs/hub.py index 74f2809..4e93000 100644 --- a/eventlet/hubs/hub.py +++ b/eventlet/hubs/hub.py @@ -241,10 +241,11 @@ class BaseHub(object): # the 0 placeholder makes it easy to bisect_right using (now, 1) self.next_timers.append((when, 0, info)) - def add_timer(self, timer): + def add_timer(self, timer, track=True): scheduled_time = self.clock() + timer.seconds self._add_absolute_timer(scheduled_time, timer) - self.track_timer(timer) + if track: + self.track_timer(timer) return scheduled_time def track_timer(self, timer): @@ -259,7 +260,7 @@ class BaseHub(object): del self.timers_by_greenlet[timer.greenlet][timer] if not self.timers_by_greenlet[timer.greenlet]: del self.timers_by_greenlet[timer.greenlet] - except KeyError: + except (KeyError, AttributeError): pass def timer_canceled(self, timer): @@ -272,16 +273,30 @@ class BaseHub(object): ins(t, item) del self.next_timers[:] - def schedule_call(self, seconds, cb, *args, **kw): + def schedule_call_local(self, seconds, cb, *args, **kw): """Schedule a callable to be called after 'seconds' seconds have - elapsed. + elapsed. Cancel the timer if greenlet has exited. seconds: The number of seconds to wait. cb: The callable to call after the given time. *args: Arguments to pass to the callable when called. **kw: Keyword arguments to pass to the callable when called. """ t = Timer(seconds, cb, *args, **kw) - self.add_timer(t) + self.add_timer(t, track=True) + return t + + schedule_call = schedule_call_local + + def schedule_call_global(self, seconds, cb, *args, **kw): + """Schedule a callable to be called after 'seconds' seconds have + elapsed. The timer will NOT + seconds: The number of seconds to wait. + cb: The callable to call after the given time. + *args: Arguments to pass to the callable when called. + **kw: Keyword arguments to pass to the callable when called. + """ + t = Timer(seconds, cb, *args, **kw) + self.add_timer(t, track=False) return t def fire_timers(self, when): diff --git a/eventlet/hubs/libev.py b/eventlet/hubs/libev.py index 637c670..3baf741 100644 --- a/eventlet/hubs/libev.py +++ b/eventlet/hubs/libev.py @@ -113,12 +113,13 @@ class Hub(hub.BaseHub): self.interrupted = False raise KeyboardInterrupt() - def add_timer(self, timer): + def add_timer(self, timer, track=True): # store the pyevent timer object so that we can cancel later eventtimer = libev.Timer(timer.seconds, 0, self._evloop, timer) timer.impltimer = eventtimer eventtimer.start() - self.track_timer(timer) + if track: + self.track_timer(timer) def timer_finished(self, timer): try: diff --git a/eventlet/hubs/libevent.py b/eventlet/hubs/libevent.py index cc8cd1d..1cf5b23 100644 --- a/eventlet/hubs/libevent.py +++ b/eventlet/hubs/libevent.py @@ -118,12 +118,13 @@ class Hub(hub.BaseHub): self.interrupted = False raise KeyboardInterrupt() - def add_timer(self, timer): + def add_timer(self, timer, track=True): # store the pyevent timer object so that we can cancel later eventtimer = event.timeout(timer.seconds, timer) timer.impltimer = eventtimer eventtimer.add() - self.track_timer(timer) + if track: + self.track_timer(timer) def timer_finished(self, timer): try: diff --git a/eventlet/hubs/twistedr.py b/eventlet/hubs/twistedr.py index 98a80aa..29073d2 100644 --- a/eventlet/hubs/twistedr.py +++ b/eventlet/hubs/twistedr.py @@ -111,7 +111,7 @@ class BaseTwistedHub(object): def exc_descriptor(self, _fileno): pass # XXX do something sensible here - def schedule_call(self, seconds, func, *args, **kwargs): + def schedule_call_local(self, seconds, func, *args, **kwargs): from twisted.internet import reactor def call_with_timer_attached(*args1, **kwargs1): try: @@ -124,6 +124,12 @@ class BaseTwistedHub(object): self.track_timer(timer) return timer + schedule_call = schedule_call_local + + def schedule_call_global(self, seconds, func, *args, **kwargs): + from twisted.internet import reactor + return callLater(reactor, seconds, func, *args, **kwargs) + def track_timer(self, timer): try: current_greenlet = greenlet.getcurrent()