mirror of
https://github.com/nikdoof/test-auth.git
synced 2025-12-14 14:52:15 +00:00
128 lines
4.0 KiB
Plaintext
128 lines
4.0 KiB
Plaintext
"""
|
|
Copyright (c) 2007-2008, Dj Gilcrease
|
|
All rights reserved.
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
in the Software without restriction, including without limitation the rights
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
all copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
THE SOFTWARE.
|
|
"""
|
|
import cPickle
|
|
from threading import Timer
|
|
from datetime import datetime
|
|
|
|
from django.dispatch import dispatcher
|
|
from django.conf import settings
|
|
|
|
from signals import cron_done
|
|
import models
|
|
|
|
# how often to check if jobs are ready to be run (in seconds)
|
|
# in reality if you have a multithreaded server, it may get checked
|
|
# more often that this number suggests, so keep an eye on it...
|
|
# default value: 300 seconds == 5 min
|
|
polling_frequency = getattr(settings, "CRON_POLLING_FREQUENCY", 300)
|
|
|
|
class Job(object):
|
|
# 86400 seconds == 24 hours
|
|
run_every = 86400
|
|
|
|
def run(self, *args, **kwargs):
|
|
self.job()
|
|
cron_done.send(sender=self, *args, **kwargs)
|
|
|
|
def job(self):
|
|
"""
|
|
Should be overridden (this way is cleaner, but the old way - overriding run() - will still work)
|
|
"""
|
|
pass
|
|
|
|
class CronScheduler(object):
|
|
def register(self, job_class, *args, **kwargs):
|
|
"""
|
|
Register the given Job with the scheduler class
|
|
"""
|
|
|
|
job_instance = job_class()
|
|
|
|
if not isinstance(job_instance, Job):
|
|
raise TypeError("You can only register a Job not a %r" % job_class)
|
|
|
|
job, created = models.Job.objects.get_or_create(name=str(job_instance.__class__))
|
|
if created:
|
|
job.instance = cPickle.dumps(job_instance)
|
|
job.args = cPickle.dumps(args)
|
|
job.kwargs = cPickle.dumps(kwargs)
|
|
job.run_frequency = job_instance.run_every
|
|
job.save()
|
|
|
|
def execute(self):
|
|
"""
|
|
Queue all Jobs for execution
|
|
"""
|
|
status, created = models.Cron.objects.get_or_create(pk=1)
|
|
|
|
# This is important for 2 reasons:
|
|
# 1. It keeps us for running more than one instance of the
|
|
# same job at a time
|
|
# 2. It reduces the number of polling threads because they
|
|
# get killed off if they happen to check while another
|
|
# one is already executing a job (only occurs with
|
|
# multi-threaded servers)
|
|
if status.executing:
|
|
return
|
|
|
|
status.executing = True
|
|
try:
|
|
status.save()
|
|
except:
|
|
# this will fail if you're debugging, so we want it
|
|
# to fail silently and start the timer again so we
|
|
# can pick up where we left off once debugging is done
|
|
Timer(polling_frequency, self.execute).start()
|
|
return
|
|
|
|
jobs = models.Job.objects.all()
|
|
for job in jobs:
|
|
if job.queued:
|
|
time_delta = datetime.now() - job.last_run
|
|
if (time_delta.seconds + 86400*time_delta.days) > job.run_frequency:
|
|
inst = cPickle.loads(str(job.instance))
|
|
args = cPickle.loads(str(job.args))
|
|
kwargs = cPickle.loads(str(job.kwargs))
|
|
|
|
try:
|
|
inst.run(*args, **kwargs)
|
|
job.last_run = datetime.now()
|
|
job.save()
|
|
|
|
except Exception:
|
|
# if the job throws an error, just remove it from
|
|
# the queue. That way we can find/fix the error and
|
|
# requeue the job manually
|
|
job.queued = False
|
|
job.save()
|
|
|
|
status.executing = False
|
|
status.save()
|
|
|
|
# Set up for this function to run again
|
|
Timer(polling_frequency, self.execute).start()
|
|
|
|
|
|
cronScheduler = CronScheduler()
|
|
|