-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcron.py
80 lines (54 loc) · 2.25 KB
/
cron.py
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
from datetime import datetime, timedelta, time
import logging
from tornado import ioloop
from tornado.options import define, options
import model
class Cron(object):
RUN_AT = None
FREQUENCY = None
@classmethod
def run(cls, debug=False):
raise NotImplementedError
@classmethod
async def first(cls, debug=False):
def closure():
logging.info('Running cron job: ' + cls.__name__)
cls.run(debug=debug)
async def runWrapper():
# WARNING! running without a specified executor might not put a limit on the number of threads
await ioloop.IOLoop.current().run_in_executor(None, closure)
# after the first run this sets up the recurring call
ioloop.PeriodicCallback(runWrapper, cls.FREQUENCY).start()
# do the first run - this must come after setting up the callback
# otherwise the timing is delayed by how long it takes to run this
await runWrapper()
@classmethod
def setup(cls, debug=False):
logging.info('Cron started, debug is ' + str(debug))
# the first callback gets added with a timer so it runs at the correct time
jobs = [AuthCron]
now = datetime.utcnow()
today = now.date()
for job in jobs:
run_at = datetime.combine(today, job.RUN_AT)
if run_at > now:
diff = run_at - now
else:
# it's in the past today, so switch it to be tomorrow
diff = run_at + timedelta(days=1) - now
ioloop.IOLoop.current().add_timeout(diff, job.first, debug=debug)
class AuthCron(Cron):
RUN_AT = time(8) # time of day, assumed to be UTC
FREQUENCY = 86400000 # in ms
# this job's specific config
MAX_DAYS = 30
@classmethod
def run(cls, debug=False):
days_ago = datetime.utcnow() - timedelta(cls.MAX_DAYS)
total = model.Auth.delete().where(model.Auth.modified_dt < days_ago).execute()
logging.info('Removed ' + str(total) + ' old auths.')
if __name__ == '__main__':
define('debug', default=False, help='enable debug')
options.parse_command_line()
ioloop.IOLoop.current().add_callback(Cron.setup, debug=options.debug)
ioloop.IOLoop.current().start()