summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonas Wielicki <j.wielicki@sotecware.net>2012-07-27 13:14:20 +0200
committerLance Stout <lancestout@gmail.com>2012-07-27 10:45:23 -0700
commite3fab66dfb27abdd8aa28a8d15367a490d4b42dd (patch)
treefea18c4597f14b54ac4ee3206219ec567632f2d1
parent5867f08bf1c6bd9866321e148bf941c0ae0dbfa0 (diff)
downloadslixmpp-e3fab66dfb27abdd8aa28a8d15367a490d4b42dd.tar.gz
slixmpp-e3fab66dfb27abdd8aa28a8d15367a490d4b42dd.tar.bz2
slixmpp-e3fab66dfb27abdd8aa28a8d15367a490d4b42dd.tar.xz
slixmpp-e3fab66dfb27abdd8aa28a8d15367a490d4b42dd.zip
Allow tasks to remove themselves during execution
The scheduler class is now capable with dealing with tasks which remove themselves from the scheduler during execution. Additionally, some optimizations were applied by use of iterators and some functions better suited for the purpose. Please peer-review, all tests pass.
-rw-r--r--sleekxmpp/xmlstream/scheduler.py28
1 files changed, 17 insertions, 11 deletions
diff --git a/sleekxmpp/xmlstream/scheduler.py b/sleekxmpp/xmlstream/scheduler.py
index d98dc6c8..b3e50983 100644
--- a/sleekxmpp/xmlstream/scheduler.py
+++ b/sleekxmpp/xmlstream/scheduler.py
@@ -15,6 +15,7 @@
import time
import threading
import logging
+import itertools
from sleekxmpp.util import Queue, QueueEmpty
@@ -156,17 +157,23 @@ class Scheduler(object):
newtask = self.addq.get(True, 0.1)
elapsed += 0.1
except QueueEmpty:
- cleanup = []
self.schedule_lock.acquire()
- for task in self.schedule:
- if time.time() >= task.next:
- updated = True
- if not task.run():
- cleanup.append(task)
+ # select only those tasks which are to be executed now
+ relevant = itertools.takewhile(
+ lambda task: time.time() >= task.next, self.schedule)
+ # run the tasks and keep the return value in a tuple
+ status = map(lambda task: (task, task.run()), relevant)
+ # remove non-repeating tasks
+ for task, doRepeat in status:
+ if not doRepeat:
+ try:
+ self.schedule.remove(task)
+ except ValueError:
+ pass
else:
- break
- for task in cleanup:
- self.schedule.pop(self.schedule.index(task))
+ # only need to resort tasks if a repeated task has
+ # been kept in the list.
+ updated = True
else:
updated = True
self.schedule_lock.acquire()
@@ -174,8 +181,7 @@ class Scheduler(object):
self.schedule.append(newtask)
finally:
if updated:
- self.schedule = sorted(self.schedule,
- key=lambda task: task.next)
+ self.schedule.sort(key=lambda task: task.next)
self.schedule_lock.release()
except KeyboardInterrupt:
self.run = False