Author: remi
Date: 2009-04-01 17:52:20 +0200 (Wed, 01 Apr 2009)
New Revision: 4317
Added:
software_suite_v2/tuxware/tuxdroidserver/trunk/util/scheduler/TaskDescription.py
Modified:
software_suite_v2/tuxware/tuxdroidserver/trunk/resources/01_robot_system/resourceScheduler.py
software_suite_v2/tuxware/tuxdroidserver/trunk/util/scheduler/Scheduler.py
software_suite_v2/tuxware/tuxdroidserver/trunk/util/scheduler/Task.py
Log:
* updated scheduler and task classes
* added TaskDescription class
* disabled the resource "scheduler" for the moment
Modified:
software_suite_v2/tuxware/tuxdroidserver/trunk/resources/01_robot_system/resourceScheduler.py
===================================================================
---
software_suite_v2/tuxware/tuxdroidserver/trunk/resources/01_robot_system/resourceScheduler.py
2009-04-01 14:00:47 UTC (rev 4316)
+++
software_suite_v2/tuxware/tuxdroidserver/trunk/resources/01_robot_system/resourceScheduler.py
2009-04-01 15:52:20 UTC (rev 4317)
@@ -117,7 +117,7 @@
# Create an instance of the resource
resourceScheduler = TDSResourceScheduler("resourceScheduler")
# Register the resource into the resources manager
-resourcesManager.addResource(resourceScheduler)
+#resourcesManager.addResource(resourceScheduler)
#
------------------------------------------------------------------------------
# Declaration of the service "run_daily_at_time".
Modified:
software_suite_v2/tuxware/tuxdroidserver/trunk/util/scheduler/Scheduler.py
===================================================================
--- software_suite_v2/tuxware/tuxdroidserver/trunk/util/scheduler/Scheduler.py
2009-04-01 14:00:47 UTC (rev 4316)
+++ software_suite_v2/tuxware/tuxdroidserver/trunk/util/scheduler/Scheduler.py
2009-04-01 15:52:20 UTC (rev 4317)
@@ -6,9 +6,20 @@
import datetime
import threading
import time
+import random
+try:
+ from hashlib import md5
+except:
+ from md5 import md5
+
from Task import Task
+TASK_NEXT_TIME = 0
+TASK_OBJECT = 1
+TASK_ID = 2
+TASK_NAME = 3
+
#
------------------------------------------------------------------------------
# Scheduler task manager.
#
------------------------------------------------------------------------------
@@ -19,13 +30,16 @@
#
--------------------------------------------------------------------------
# Constructor of the class.
#
--------------------------------------------------------------------------
- def __init__(self):
+ def __init__(self, appGlobals):
"""Constructor.
"""
self.__started = False
self.__startedMutex = threading.Lock()
self.__tasksToExecuteStack = []
self.__tasksToExecuteStackMutex = threading.Lock()
+ self.__appGlobals = appGlobals
+ self.__onTaskAddedCallback = None
+ self.__onTaskRemovedCallback = None
#
--------------------------------------------------------------------------
# Start the scheduler.
@@ -68,36 +82,151 @@
self.__startedMutex.release()
#
--------------------------------------------------------------------------
+ # Generate a single id.
+ #
--------------------------------------------------------------------------
+ def __generateSingleId(self, baseString = None):
+ """Generate a single id.
+ @baseString: Base string. (default None)
+ @return: The single id.
+ """
+ if baseString == None:
+ baseString = str(time.time() + random.random())
+ md5H = md5()
+ md5H.update(baseString)
+ id = md5H.hexdigest()
+ return id
+
+ #
--------------------------------------------------------------------------
+ # This method generate a single task name from the taskName argument.
+ #
--------------------------------------------------------------------------
+ def __generateSingleName(self, taskName):
+ """This method generate a single task name from the taskName argument.
+ @param taskName: Base task name.
+ @return: A single task name.
+ If the taskName is already not existing in the scheduler, the method
+ return it.
+ """
+ def checkNameExists(taskNameToCheck):
+ result = False
+ self.__tasksToExecuteStackMutex.acquire()
+ for taskInfo in self.__tasksToExecuteStack:
+ if taskInfo[TASK_NAME] == taskNameToCheck:
+ result = True
+ break
+ self.__tasksToExecuteStackMutex.release()
+ return result
+ baseTaskName = taskName
+ if (baseTaskName.find("(") > 0) and (baseTaskName.find(")") != -1):
+ baseTaskName = baseTaskName[:baseTaskName.find("(") - 1]
+ if baseTaskName == "":
+ baseTaskName = "Default"
+ i = 0
+ while checkNameExists(taskName):
+ i += 1
+ taskName = "%s (%d)" % (baseTaskName, i)
+ return taskName
+
+ #
--------------------------------------------------------------------------
# Insert a task in the scheduler.
#
--------------------------------------------------------------------------
- def insertTask(self, task):
+ def insertTask(self, task, name):
"""Insert a task in the scheduler.
@param task: Task object.
- @return: The task identifier or None if fail.
+ @return: The task identifier and the task name or None None if fail.
"""
nextTime = task.getNextExecuteTime()
- id = clientsManager.generateSingleId()
+ id = self.__generateSingleId()
+ name = self.__generateSingleName(name)
self.__tasksToExecuteStackMutex.acquire()
if nextTime != None:
- self.__tasksToExecuteStack.append([nextTime, task, id])
+ task.getDescription().setId(id)
+ task.getDescription().setName(name)
+ self.__tasksToExecuteStack.append([nextTime, task, id, name])
+ resultId = id
+ resultName = name
+ else:
+ resultId = None
+ resultName = None
self.__tasksToExecuteStackMutex.release()
- return id
+ if resultId != None:
+ if self.__onTaskAddedCallback != None:
+ self.__onTaskAddedCallback(task)
+ return resultId, resultName
#
--------------------------------------------------------------------------
- # Remove a task from the scheduler.
+ # Get the number of tasks contained in the scheduler.
#
--------------------------------------------------------------------------
- def removeTask(self, taskId):
- """Remove a task from the scheduler.
+ def getTasksCount(self):
+ """Get the number of tasks contained in the scheduler.
+ @return: An integer.
+ """
+ self.__tasksToExecuteStackMutex.acquire()
+ result = len(self.__tasksToExecuteStack)
+ self.__tasksToExecuteStackMutex.release()
+ return result
+
+ #
--------------------------------------------------------------------------
+ # Get the tasks contained in the scheduler.
+ #
--------------------------------------------------------------------------
+ def getTasks(self):
+ """Get the tasks contained in the scheduler.
+ @return: A list of Task objects.
+ """
+ result = []
+ self.__tasksToExecuteStackMutex.acquire()
+ for taskInfo in self.__tasksToExecuteStack:
+ result.append(taskInfo[TASK_OBJECT])
+ self.__tasksToExecuteStackMutex.release()
+ return result
+
+ #
--------------------------------------------------------------------------
+ # Remove a task from the scheduler by its identifier.
+ #
--------------------------------------------------------------------------
+ def removeTaskById(self, taskId):
+ """Remove a task from the scheduler by its identifier.
@param taskId: Task identifier.
"""
+ task = None
self.__tasksToExecuteStackMutex.acquire()
for taskInfo in self.__tasksToExecuteStack:
- if taskInfo[2] == taskId:
+ if taskInfo[TASK_ID] == taskId:
self.__tasksToExecuteStack.remove(taskInfo)
+ task = taskInfo[TASK_OBJECT]
break
self.__tasksToExecuteStackMutex.release()
+ if task != None:
+ if self.__onTaskRemovedCallback != None:
+ self.__onTaskRemovedCallback(task)
#
--------------------------------------------------------------------------
+ # Remove a task from the scheduler by its name.
+ #
--------------------------------------------------------------------------
+ def removeTaskByName(self, taskName):
+ """Remove a task from the scheduler by its name.
+ @param taskName: Task name.
+ """
+ task = None
+ self.__tasksToExecuteStackMutex.acquire()
+ for taskInfo in self.__tasksToExecuteStack:
+ if taskInfo[TASK_NAME] == taskName:
+ self.__tasksToExecuteStack.remove(taskInfo)
+ task = taskInfo[TASK_OBJECT]
+ break
+ self.__tasksToExecuteStackMutex.release()
+ if task != None:
+ if self.__onTaskRemovedCallback != None:
+ self.__onTaskRemovedCallback(task)
+
+ #
--------------------------------------------------------------------------
+ # Remove a task from the scheduler.
+ #
--------------------------------------------------------------------------
+ def removeTask(self, taskId):
+ """Remove a task from the scheduler.
+ @param taskId: Task identifier.
+ """
+ self.removeTaskById(taskId)
+
+ #
--------------------------------------------------------------------------
# Clear the scheduler.
#
--------------------------------------------------------------------------
def clear(self):
@@ -108,6 +237,30 @@
self.__tasksToExecuteStackMutex.release()
#
--------------------------------------------------------------------------
+ # Set the on task added event callback.
+ #
--------------------------------------------------------------------------
+ def setOnTaskAddedCallback(self, funct):
+ """Set the on task added event callback.
+ @param funct: Function pointer.
+ Function prototype:
+ def onTaskAdded(self, task):
+ pass
+ """
+ self.__onTaskAddedCallback = funct
+
+ #
--------------------------------------------------------------------------
+ # Set the on task removed event callback.
+ #
--------------------------------------------------------------------------
+ def setOnTaskRemovedCallback(self, funct):
+ """Set the on task removed event callback.
+ @param funct: Function pointer.
+ Function prototype:
+ def onTaskRemoved(self, task):
+ pass
+ """
+ self.__onTaskRemovedCallback = funct
+
+ #
--------------------------------------------------------------------------
# Loop of the tasks checker.
#
--------------------------------------------------------------------------
def __tasksCheckerLoop(self):
@@ -120,19 +273,26 @@
now = datetime.datetime.now()
tasksToRemove = []
tasksToAdd = []
+ tasksFinished = []
self.__tasksToExecuteStackMutex.acquire()
for taskInfo in self.__tasksToExecuteStack:
- if now > taskInfo[0]:
+ if now > taskInfo[TASK_NEXT_TIME]:
tasksToRemove.append(taskInfo)
- nextTime = taskInfo[1].getNextExecuteTime()
- diff = now - taskInfo[0]
+ nextTime = taskInfo[TASK_OBJECT].getNextExecuteTime()
+ diff = now - taskInfo[TASK_NEXT_TIME]
if diff.seconds <= 10:
- taskInfo[1].execute()
+ taskInfo[TASK_OBJECT].execute(self.__appGlobals)
if nextTime != None:
- tasksToAdd.append([nextTime, taskInfo[1], taskInfo[2]])
+ tasksToAdd.append([nextTime, taskInfo[TASK_OBJECT],
+ taskInfo[TASK_ID], taskInfo[TASK_NAME]])
+ else:
+ tasksFinished.append(taskInfo[TASK_OBJECT])
for taskInfo in tasksToRemove:
self.__tasksToExecuteStack.remove(taskInfo)
for taskInfo in tasksToAdd:
self.__tasksToExecuteStack.append(taskInfo)
self.__tasksToExecuteStackMutex.release()
+ for task in tasksFinished:
+ if self.__onTaskRemovedCallback != None:
+ self.__onTaskRemovedCallback(task)
time.sleep(1.0)
Modified: software_suite_v2/tuxware/tuxdroidserver/trunk/util/scheduler/Task.py
===================================================================
--- software_suite_v2/tuxware/tuxdroidserver/trunk/util/scheduler/Task.py
2009-04-01 14:00:47 UTC (rev 4316)
+++ software_suite_v2/tuxware/tuxdroidserver/trunk/util/scheduler/Task.py
2009-04-01 15:52:20 UTC (rev 4317)
@@ -6,10 +6,7 @@
import datetime
import threading
-SCH_LOOP_ABS = 0
-SCH_LOOP_REL = 1
-SCH_ONCE_ABS = 2
-SCH_ONCE_REL = 3
+from TaskDescription import *
#
------------------------------------------------------------------------------
# Class the create a scheduled task.
@@ -21,58 +18,75 @@
#
--------------------------------------------------------------------------
# Constructor of the class.
#
--------------------------------------------------------------------------
- def __init__(self, ruleType, weekMask, hour, minute, second, command,
- year = None, month = None, day = None):
+ def __init__(self, ruleType, weekMask, hour, minute, second, year, month,
+ day, command, arguments):
"""Constructor of the class.
@param ruleType: <SCH_LOOP_ABS|SCH_LOOP_REL|SCH_ONCE_ABS|SCH_ONCE_REL>
@param weekMask: Week mask. [True, True, True, True, True, True, True]
- @param hour: <0..23>
- @param minute: <0..59>
- @param second: <0..59>
- @param command: Command to execute.
+ @param hour: <hh>
+ @param minute: <mm>
+ @param second: <ss>
+ @param year: <yyyy> or -1
+ @param month: <mm> or -1
+ @param day: <dd> or -1
+ @param command: Command to execute as string.
+ @param arguments: Arguments of the command as tuple.
"""
- self.__ruleType = ruleType
- self.__weekMask = weekMask
- self.__hour = hour
- self.__minute = minute
- self.__second = second
- self.__command = command
- self.__year = year
- self.__month = month
- self.__day = day
+ dictionary = {
+ 'type' : ruleType,
+ 'weekMask' : weekMask,
+ 'year' : year,
+ 'month' : month,
+ 'day' : day,
+ 'hour' : hour,
+ 'minute' : minute,
+ 'second' : second,
+ 'command' : command,
+ 'arguments' : arguments,
+ }
+ self.__description = TaskDescription(self, dictionary)
now = datetime.datetime.now()
self.__monthAtStart = now.month
self.__monthMask = self.__createMonthMask(self.__monthAtStart)
- if self.__ruleType == SCH_LOOP_ABS:
- if self.__hour == 0:
- m = int(now.minute / self.__minute) * self.__minute
- self.__startTime = datetime.datetime(now.year, now.month,
now.day,
- now.hour - self.__hour, m, self.__second)
- self.__incrementTime = datetime.timedelta(minutes =
self.__minute)
+ if ruleType == SCH_LOOP_ABS:
+ if hour == 0:
+ m = int(now.minute / minute) * minute
+ self.__startTime = datetime.datetime(now.year, now.month,
+ now.day, now.hour - hour, m, second)
+ self.__incrementTime = datetime.timedelta(minutes = minute)
else:
- self.__startTime = datetime.datetime(now.year, now.month,
now.day,
- now.hour - self.__hour, self.__minute, self.__second)
- self.__incrementTime = datetime.timedelta(hours = self.__hour)
- elif self.__ruleType == SCH_LOOP_REL:
+ self.__startTime = datetime.datetime(now.year, now.month,
+ now.day, now.hour - hour, minute, second)
+ self.__incrementTime = datetime.timedelta(hours = hour)
+ elif ruleType == SCH_LOOP_REL:
self.__startTime = datetime.datetime.now()
- self.__incrementTime = datetime.timedelta(seconds = self.__second,
- minutes = self.__minute, hours = self.__hour)
- elif self.__ruleType == SCH_ONCE_ABS:
- if (self.__year != None) and (self.__month != None) and
(self.__day != None):
- self.__startTime = datetime.datetime(self.__year, self.__month,
- self.__day, self.__hour, self.__minute, self.__second)
+ self.__incrementTime = datetime.timedelta(seconds = second,
+ minutes = minute, hours = hour)
+ elif ruleType == SCH_ONCE_ABS:
+ if (year != -1) and (month != -1) and (day != -1):
+ self.__startTime = datetime.datetime(year, month,
+ day, hour, minute, second)
self.__incrementTime = None
else:
self.__startTime = datetime.datetime(now.year, now.month,
- now.day, self.__hour, self.__minute, self.__second)
+ now.day, hour, minute, second)
self.__incrementTime = datetime.timedelta(days = 1)
- elif self.__ruleType == SCH_ONCE_REL:
+ elif ruleType == SCH_ONCE_REL:
self.__startTime = datetime.datetime.now()
- self.__incrementTime = datetime.timedelta(hours = self.__hour,
- minutes = self.__minute, seconds = self.__second)
+ self.__incrementTime = datetime.timedelta(hours = hour,
+ minutes = minute, seconds = second)
self.__lastExecuteTime = None
#
--------------------------------------------------------------------------
+ # Get the description object of the task.
+ #
--------------------------------------------------------------------------
+ def getDescription(self):
+ """Get the description object of the task.
+ @return: A TaskDescription object.
+ """
+ return self.__description
+
+ #
--------------------------------------------------------------------------
# Create the month mask.
#
--------------------------------------------------------------------------
def __createMonthMask(self, month):
@@ -86,7 +100,7 @@
result = []
dayIndex = firstDayOfMonth
for i in range(40):
- result.append(self.__weekMask[dayIndex])
+ result.append(self.__description.getWeekMask()[dayIndex])
dayIndex += 1
if dayIndex > 6:
dayIndex = 0
@@ -114,17 +128,17 @@
"""
result = None
now = datetime.datetime.now()
- if self.__ruleType == SCH_LOOP_ABS:
+ if self.__description.getType() == SCH_LOOP_ABS:
if self.__lastExecuteTime == None:
result = self.__startTime + self.__incrementTime
else:
result = self.__lastExecuteTime + self.__incrementTime
- elif self.__ruleType == SCH_LOOP_REL:
+ elif self.__description.getType() == SCH_LOOP_REL:
if self.__lastExecuteTime == None:
result = self.__startTime + self.__incrementTime
else:
result = self.__lastExecuteTime + self.__incrementTime
- elif self.__ruleType == SCH_ONCE_ABS:
+ elif self.__description.getType() == SCH_ONCE_ABS:
if self.__lastExecuteTime == None:
result = self.__startTime
else:
@@ -132,7 +146,7 @@
result = None
else:
result = self.__lastExecuteTime + self.__incrementTime
- elif self.__ruleType == SCH_ONCE_REL:
+ elif self.__description.getType() == SCH_ONCE_REL:
if self.__lastExecuteTime == None:
result = self.__startTime + self.__incrementTime
else:
@@ -151,16 +165,16 @@
#
--------------------------------------------------------------------------
# Execute the task.
#
--------------------------------------------------------------------------
- def execute(self):
+ def execute(self, appGlobals):
"""Execute the task.
"""
def async():
try:
- if str(type(self.__command)) == "<type 'str'>":
- exec(self.__command) in globals()
- else:
- self.__command()
+ command = eval(self.__description.getCommand(), appGlobals)
+ arguments = self.__description.getArguments()
+ command(*arguments)
except:
+ print "error"
pass
t = threading.Thread(target = async)
t.start()
Added:
software_suite_v2/tuxware/tuxdroidserver/trunk/util/scheduler/TaskDescription.py
===================================================================
---
software_suite_v2/tuxware/tuxdroidserver/trunk/util/scheduler/TaskDescription.py
(rev 0)
+++
software_suite_v2/tuxware/tuxdroidserver/trunk/util/scheduler/TaskDescription.py
2009-04-01 15:52:20 UTC (rev 4317)
@@ -0,0 +1,179 @@
+# Copyright (C) 2009 C2ME Sa
+# Remi Jocaille <[email protected]>
+# Distributed under the terms of the GNU General Public License
+# http://www.gnu.org/copyleft/gpl.html
+
+SCH_LOOP_ABS = 0
+SCH_LOOP_REL = 1
+SCH_ONCE_ABS = 2
+SCH_ONCE_REL = 3
+
+#
------------------------------------------------------------------------------
+# Task description class.
+#
------------------------------------------------------------------------------
+class TaskDescription(object):
+ """Task description class.
+ """
+
+ #
--------------------------------------------------------------------------
+ # Constructor of the class.
+ #
--------------------------------------------------------------------------
+ def __init__(self, parent, dictionary):
+ """Constructor of the class.
+ @param parent: Parent Task.
+ @param dictionary: Description as dictionary.
+ """
+ self.__parent = parent
+ self.__dictionary = dictionary
+ self.__name = None
+ self.__id = None
+
+ #
--------------------------------------------------------------------------
+ # Get the task name.
+ #
--------------------------------------------------------------------------
+ def getName(self):
+ """Get the task name.
+ @return: A string.
+ """
+ return self.__name
+
+ #
--------------------------------------------------------------------------
+ # Set the task name.
+ #
--------------------------------------------------------------------------
+ def setName(self, name):
+ """Set the task name.
+ @param name: Task name.
+ """
+ self.__name = name
+
+ #
--------------------------------------------------------------------------
+ # Get the task identifier.
+ #
--------------------------------------------------------------------------
+ def getId(self):
+ """Get the task identifier.
+ @return: A string.
+ """
+ return self.__id
+
+ #
--------------------------------------------------------------------------
+ # Set the task identifier.
+ #
--------------------------------------------------------------------------
+ def setId(self, id):
+ """Set the task identifier.
+ @param id: Task identifier.
+ """
+ self.__id = id
+
+ #
--------------------------------------------------------------------------
+ # Get the task type.
+ #
--------------------------------------------------------------------------
+ def getType(self):
+ """Get the task type.
+ @return: <SCH_LOOP_ABS|SCH_LOOP_REL|SCH_ONCE_ABS|SCH_ONCE_REL>.
+ """
+ return self.__dictionary['type']
+
+ #
--------------------------------------------------------------------------
+ # Get the task configuration to string.
+ #
--------------------------------------------------------------------------
+ def toString(self):
+ """Get the task configuration to string.
+ @return: A string
+ """
+ ymd = "%.4d/%.2d/%.2d" % (self.getYear(), self.getMonth(),
+ self.getDay())
+ hms = "%.2d:%.2d:%.2d" % (self.getHour(), self.getMinute(),
+ self.getSecond())
+ if self.getType() == SCH_LOOP_REL:
+ return "[EVERY X] Delay %s" % hms
+ elif self.getType() == SCH_LOOP_ABS:
+ return "[EVERY X FROM FULL HOUR] Delay %s" % hms
+ elif self.getType() == SCH_ONCE_ABS:
+ if (self.getYear() == -1) and (self.getMonth() == -1) and \
+ (self.getDay() == -1):
+ return "[DAILY AT] Time %s" % hms
+ else:
+ return "[ONCE AT] Date %s Time %s" % (ymd, hms)
+ else: # SCH_ONCE_REL
+ return "[ONCE DELAYED] Timeout %s" % hms
+
+ #
--------------------------------------------------------------------------
+ # Get the week mask.
+ #
--------------------------------------------------------------------------
+ def getWeekMask(self):
+ """Get the week mask.
+ @return: Week mask. [True, True, True, True, True, True, True]
+ """
+ return self.__dictionary['weekMask']
+
+ #
--------------------------------------------------------------------------
+ # Get the year value.
+ #
--------------------------------------------------------------------------
+ def getYear(self):
+ """Get the year value.
+ @return: An integer or -1.
+ """
+ return self.__dictionary['year']
+
+ #
--------------------------------------------------------------------------
+ # Get the month value.
+ #
--------------------------------------------------------------------------
+ def getMonth(self):
+ """Get the month value.
+ @return: An integer or -1.
+ """
+ return self.__dictionary['month']
+
+ #
--------------------------------------------------------------------------
+ # Get the day value.
+ #
--------------------------------------------------------------------------
+ def getDay(self):
+ """Get the day value.
+ @return: An integer or -1.
+ """
+ return self.__dictionary['day']
+
+ #
--------------------------------------------------------------------------
+ # Get the hour value.
+ #
--------------------------------------------------------------------------
+ def getHour(self):
+ """Get the hour value.
+ @return: An integer.
+ """
+ return self.__dictionary['hour']
+
+ #
--------------------------------------------------------------------------
+ # Get the minute value.
+ #
--------------------------------------------------------------------------
+ def getMinute(self):
+ """Get the minute value.
+ @return: An integer.
+ """
+ return self.__dictionary['minute']
+
+ #
--------------------------------------------------------------------------
+ # Get the second value.
+ #
--------------------------------------------------------------------------
+ def getSecond(self):
+ """Get the second value.
+ @return: An integer.
+ """
+ return self.__dictionary['second']
+
+ #
--------------------------------------------------------------------------
+ # Get the command.
+ #
--------------------------------------------------------------------------
+ def getCommand(self):
+ """Get the command.
+ @return: A string.
+ """
+ return self.__dictionary['command']
+
+ #
--------------------------------------------------------------------------
+ # Get the arguments of the command.
+ #
--------------------------------------------------------------------------
+ def getArguments(self):
+ """Get the arguments of the command.
+ @return: A tuple.
+ """
+ return self.__dictionary['arguments']
------------------------------------------------------------------------------
_______________________________________________
Tux-droid-svn mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/tux-droid-svn