Skip to content

Instantly share code, notes, and snippets.

@ivandeex
Last active August 29, 2015 14:25
Show Gist options
  • Save ivandeex/9b00eb5209277a66db4a to your computer and use it in GitHub Desktop.
Save ivandeex/9b00eb5209277a66db4a to your computer and use it in GitHub Desktop.
supervisor cron
from crontab import CronTab
from datetime import datetime, timedelta
import time
import os
import xmlrpclib
import urlparse
import logging
import json
import shlex
def json_conv(s):
try:
return json.loads(s)
except ValueError:
return s
cmd_map = {'start':'supervisor.startProcess', 'stop':'supervisor.stopProcess'}
rpc_url = urlparse.urljoin(os.environ['SUPERVISOR_SERVER_URL'], 'RPC2')
rpc_conn = xmlrpclib.Server(rpc_url)
cron_args = [('ARG_%02d' % n, arg) for n, arg in enumerate(sys.argv)]
cron_vars = filter(lambda it: it[0].startswith('CRON_'), os.environ.items())
wait_arg_map = {'wait':'true', 'nowait':'false'}
cron_list = []
for token in [val for name, val in sorted(cron_args + cron_vars)]:
when, _, action = token.partition(':')
cron = CronTab(when.strip())
args = shlex.split(action)
cmd = args.pop(0)
cmd = cmd_map.get(cmd, cmd)
if args:
args[-1] = wait_arg_map.get(args[-1], args[-1])
args = map(json_conv, args)
cmd_str = '%s(%s)' % (cmd, ','.join(args))
cron_list.append((cron, cmd, args, cmd_str))
logging.debug('prepared cron method %s --> %s' % (cmd_str, cron))
tick = datetime.now().replace(second=0,microsecond=0)
one_min = timedelta(0,60)
while 1:
tick += one_min
delay = tick - datetime.now()
if delay > 0:
time.sleep(delay)
for cron, cmd, args, arg_str in cron_list:
if cron.next(tick) < 60:
try:
method = getattr(rpc_conn, cmd)
method(*args)
logging.debug('called %s' % cmd_str)
except xmlrpclib.Fault as fault:
logging.error('%s: call failed: %s' % (cmd_str, fault.faultString))
except xmlrpclib.ProtocolError as perr:
logging.error('%s: protocol failed: %s' % (cmd_str, perr.errmsg))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment