Welcome, guest | Sign In | My Account | Store | Cart
import time
import threading
import sys

# TODO: Maybe Interval should be a multiply of Precision.

class Job:
   
Interval = 0
   
Elapsed = 0
   
JobFunction = None
   
Force = False

class JobController(threading.Thread):
   
   
def __init__(self,precision=1.0):
        threading
.Thread.__init__(self)
       
self.__StopIt = False
       
self.__Jobs = {}
       
self.__JobCounter = 0
       
self.__Precision = precision
       
self.__JobsLock = threading.Lock()
       
   
def run(self):
       
       
while(1):
            jobfuncs
= []

           
if self.__StopIt == True:
               
return
           
           
self.__JobsLock.acquire()
           
try:
               
for key,val in self.__Jobs.items():
                    val
.Elapsed += self.__Precision
                   
if val.Elapsed >= val.Interval or val.Force:
                        val
.Elapsed = 0
                        val
.Force = False
                       
                       
# copy to another list for
                       
# not acquirirng JobsLock()
                       
# while calling the JobsFunction
                        jobfuncs
.append(val.JobFunction)
           
finally:
               
self.__JobsLock.release()
               
           
# now invoke the job functions
           
for jobfunc in jobfuncs:
               
try:
                    jobfunc
()
               
# no unhandled exceptions allowed
               
except Exception,e:
                   
print "JOBERROR:"+str(e)
            time
.sleep(self.__Precision)
                   
           
   
def JcStart(self):
       
self.start()
   
   
def JcStop(self):
       
self.__StopIt = True
       
   
def __AssertBounds(self,val,min,max):
       
if (val < min) or (val > max):
           
raise AssertionError, "value not in bounds" \
                     
"["+str(val)+"]["+str(min)+"]["+str(max)+"]"
       
   
def JcAddJob(self,interval,jobfunction):
       
       
self.__AssertBounds(interval,self.__Precision,float(sys.maxint))
       
       
# create a job object
        ajob
= Job()
        ajob
.Interval = interval
        ajob
.Elapsed = 0
        ajob
.JobFunction = jobfunction
        ajob
.Force = False
       
# append it to jobs dict
       
self.__JobCounter += 1

       
self.__JobsLock.acquire()
       
try:
           
self.__Jobs[self.__JobCounter] = ajob
       
finally:
           
self.__JobsLock.release()
           
       
return self.__JobCounter
       
   
def JcRemoveJob(self,jobid):
       
self.__JobsLock.acquire()
       
try:
           
del self.__Jobs[jobid]
       
finally:
           
self.__JobsLock.release()
       
   
def JcForceJob(self,jobid):
       
self.__JobsLock.acquire()
       
try:            
           
self.__Jobs[jobid].Force = True
       
finally:
           
self.__JobsLock.release()
       
   
def JcChangeJob(self,jobid,interval,jobfunction):

       
self.__AssertBounds(interval,self.__Precision,sys.maxint)
       
       
self.__JobsLock.acquire()
       
try:  
           
self.__Jobs[jobid].Interval = interval
           
self.__Jobs[jobid].JobFunction = jobfunction
       
finally:
           
self.__JobsLock.release()

# EXAMPLE
A simple example
is like this:
jc
= JobController(60.0) # precision is 60 secs, so main JobController will be invoked
                         
# per 60 secs.
jc
.JcAddJob(60*30,CheckConnectionJob)
jc
.JcAddJob(60*5,CheckStatisticsJob)
jc
.start()
jc
.JcAddJob(60*5,CheckPingJob)
.
.

History

  • revision 2 (14 years ago)
  • previous revisions are not available