CARVIEW |
Select Language
HTTP/2 302
server: nginx
date: Fri, 01 Aug 2025 09:45:22 GMT
content-type: text/plain; charset=utf-8
content-length: 0
x-archive-redirect-reason: found capture at 20090515161623
location: https://web.archive.org/web/20090515161623/https://code.activestate.com/recipes/576748
server-timing: captures_list;dur=0.485547, exclusion.robots;dur=0.021443, exclusion.robots.policy;dur=0.011276, esindex;dur=0.010699, cdx.remote;dur=76.208223, LoadShardBlock;dur=260.086803, PetaboxLoader3.datanode;dur=99.700214, PetaboxLoader3.resolve;dur=131.485935
x-app-server: wwwb-app203
x-ts: 302
x-tr: 360
server-timing: TR;dur=0,Tw;dur=0,Tc;dur=0
set-cookie: SERVER=wwwb-app203; path=/
x-location: All
x-rl: 0
x-na: 0
x-page-cache: MISS
server-timing: MISS
x-nid: DigitalOcean
referrer-policy: no-referrer-when-downgrade
permissions-policy: interest-cohort=()
HTTP/2 200
server: nginx
date: Fri, 01 Aug 2025 09:45:23 GMT
content-type: text/html; charset=utf-8
x-archive-orig-date: Fri, 15 May 2009 16:16:22 GMT
x-archive-orig-server: Apache/2.2.3 (CentOS)
x-archive-orig-expires: Fri, 15 May 2009 16:26:22 GMT
x-archive-orig-vary: Cookie
x-archive-orig-etag: 7b7c00cb33207f8eb7b498358aff6425
x-archive-orig-cache-control: max-age=600
x-archive-orig-via: 1.0 box19.activestate.com:3129 (squid/2.6.STABLE21)
x-archive-orig-connection: close
x-archive-guessed-content-type: text/html
x-archive-guessed-charset: utf-8
memento-datetime: Fri, 15 May 2009 16:16:23 GMT
link: ; rel="original", ; rel="timemap"; type="application/link-format", ; rel="timegate", ; rel="first memento"; datetime="Fri, 15 May 2009 16:16:23 GMT", ; rel="memento"; datetime="Fri, 15 May 2009 16:16:23 GMT", ; rel="next memento"; datetime="Sun, 24 May 2009 08:11:38 GMT", ; rel="last memento"; datetime="Sun, 24 May 2009 08:11:38 GMT"
content-security-policy: default-src 'self' 'unsafe-eval' 'unsafe-inline' data: blob: archive.org web.archive.org web-static.archive.org wayback-api.archive.org athena.archive.org analytics.archive.org pragma.archivelab.org wwwb-events.archive.org
x-archive-src: 51_9_20090515130345_crawl103-c/51_9_20090515161543_crawl103.arc.gz
server-timing: captures_list;dur=1.586789, exclusion.robots;dur=0.070943, exclusion.robots.policy;dur=0.031376, esindex;dur=0.026314, cdx.remote;dur=9.884402, LoadShardBlock;dur=88.249929, PetaboxLoader3.datanode;dur=86.976482, PetaboxLoader3.resolve;dur=257.527584, load_resource;dur=275.441092
x-app-server: wwwb-app203
x-ts: 200
x-tr: 455
server-timing: TR;dur=0,Tw;dur=0,Tc;dur=0
x-location: All
x-rl: 0
x-na: 0
x-page-cache: MISS
server-timing: MISS
x-nid: DigitalOcean
referrer-policy: no-referrer-when-downgrade
permissions-policy: interest-cohort=()
content-encoding: gzip
Simple MultiThreaded Timer Job Controller « ActiveState Code
ActiveState Code
Recipe 576748: Simple MultiThreaded Timer Job Controller
We have tried to write an audit for our server to check our server's connection, status and other internal info and there are multiple threads invoking multiple tasks. So I came up with this simple utility that takes a job and runs it in a specific interval.
Python |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | 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)
.
.
|
- Accounts
- Information
- Using
- Feedback
- ActiveState
© 2008 ActiveState Software. All rights reserved.
Sign in to comment