adding scheduler
This commit is contained in:
		
							
								
								
									
										76
									
								
								sleekxmpp/xmlstream/scheduler.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								sleekxmpp/xmlstream/scheduler.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,76 @@ | ||||
| try: | ||||
| 	import queue | ||||
| except ImportError: | ||||
| 	import Queue as queue | ||||
| import time | ||||
| import threading | ||||
|  | ||||
| class Task(object): | ||||
| 	"""Task object for the Scheduler class""" | ||||
| 	def __init__(self, name, seconds, callback, args=None, kwargs=None, repeat=False, qpointer=None): | ||||
| 		self.name = name | ||||
| 		self.seconds = seconds | ||||
| 		self.callback = callback | ||||
| 		self.args = args or tuple() | ||||
| 		self.kwargs = kwargs or {} | ||||
| 		self.repeat = repeat | ||||
| 		self.next = time.time() + self.seconds | ||||
| 		self.qpointer = qpointer | ||||
| 	 | ||||
| 	def run(self): | ||||
| 		if self.qpointer is not None: | ||||
| 			self.qpointer.put(('schedule', self.callback, self.args)) | ||||
| 		else: | ||||
| 			self.callback(*self.args, **self.kwargs) | ||||
| 		self.reset() | ||||
| 		return self.repeat | ||||
| 	 | ||||
| 	def reset(self): | ||||
| 		self.next = time.time() + self.seconds | ||||
|  | ||||
| class Scheduler(object): | ||||
| 	"""Threaded scheduler that allows for updates mid-execution unlike http://docs.python.org/library/sched.html#module-sched""" | ||||
| 	def __init__(self): | ||||
| 		self.addq = queue.Queue() | ||||
| 		self.schedule = [] | ||||
| 		self.thread = None | ||||
| 		self.run = True | ||||
| 	 | ||||
| 	def process(self, threaded=True): | ||||
| 		if threaded: | ||||
| 			self.thread = threading.Thread(name='shedulerprocess', target=self._process) | ||||
| 			self.thread.start() | ||||
| 		else: | ||||
| 			self._process() | ||||
|  | ||||
| 	def _process(self): | ||||
| 		while self.run: | ||||
| 			wait = 5 | ||||
| 			updated = False | ||||
| 			if self.schedule: | ||||
| 				wait = self.schedule[0].next - time.time() | ||||
| 			try: | ||||
| 				newtask = self.addq.get(True, wait) | ||||
| 			except queue.Empty: | ||||
| 				cleanup = [] | ||||
| 				for task in self.schedule: | ||||
| 					if time.time() >= task.next: | ||||
| 						updated = True | ||||
| 						if not task.run(): | ||||
| 							cleanup.append(task) | ||||
| 					else: | ||||
| 						break | ||||
| 				for task in cleanup: | ||||
| 					x = self.schedule.pop(self.schedule.index(task)) | ||||
| 			else: | ||||
| 				updated = True | ||||
| 				self.schedule.append(newtask) | ||||
| 			finally: | ||||
| 				if updated: self.schedule = sorted(self.schedule, key=lambda task: task.next) | ||||
| 				print [x.name for x in self.schedule] | ||||
|  | ||||
| 	def add(self, name, seconds, callback, args=None, kwargs=None, repeat=False, qpointer=None): | ||||
| 		self.addq.put(Task(name, seconds, callback, args, kwargs, repeat, qpointer)) | ||||
| 	 | ||||
| 	def quit(self): | ||||
| 		self.run = False | ||||
| @@ -22,6 +22,7 @@ import time | ||||
| import traceback | ||||
| import types | ||||
| import xml.sax.saxutils | ||||
| from . import scheduler | ||||
|  | ||||
| HANDLER_THREADS = 1 | ||||
|  | ||||
| @@ -75,6 +76,7 @@ class XMLStream(object): | ||||
|  | ||||
| 		self.eventqueue = queue.Queue() | ||||
| 		self.sendqueue = queue.Queue() | ||||
| 		self.scheduler = scheduler.Scheduler() | ||||
|  | ||||
| 		self.namespace_map = {} | ||||
|  | ||||
| @@ -145,6 +147,7 @@ class XMLStream(object): | ||||
| 		raise RestartStream() | ||||
| 	 | ||||
| 	def process(self, threaded=True): | ||||
| 		self.scheduler.process(threaded=True) | ||||
| 		for t in range(0, HANDLER_THREADS): | ||||
| 			self.__thread['eventhandle%s' % t] = threading.Thread(name='eventhandle%s' % t, target=self._eventRunner) | ||||
| 			self.__thread['eventhandle%s' % t].start() | ||||
| @@ -156,8 +159,8 @@ class XMLStream(object): | ||||
| 		else: | ||||
| 			self._process() | ||||
| 	 | ||||
| 	def schedule(self, seconds, handler, args=None): | ||||
| 		threading.Timer(seconds, handler, args).start() | ||||
| 	def schedule(self, name, seconds, callback, args=None, kwargs=None, repeat=False): | ||||
| 		self.scheduler.add(name, seconds, callback, args, kwargs, repeat, qpointer=self.eventqueue) | ||||
| 	 | ||||
| 	def _process(self): | ||||
| 		"Start processing the socket." | ||||
| @@ -334,7 +337,7 @@ class XMLStream(object): | ||||
| 					except Exception as e: | ||||
| 						traceback.print_exc() | ||||
| 						args[0].exception(e) | ||||
| 				elif etype == 'sched': | ||||
| 				elif etype == 'schedule': | ||||
| 					try: | ||||
| 						handler.run(*args) | ||||
| 					except: | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Nathan Fritz
					Nathan Fritz