cathead/cathead/scheduler.py

86 lines
3.1 KiB
Python

# Copyright 2015 Tom Cammann
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import logging
from apscheduler.jobstores.base import JobLookupError
from apscheduler.schedulers import background
import certwatch
LOG = logging.getLogger(__name__)
class Scheduler(object):
def __init__(self):
self._scheduler = background.BackgroundScheduler()
self._scheduler.configure(daemon=True)
self.job_dict = {}
self._scheduler.start()
def is_tracked(self, key_path):
return key_path in self.job_dict
def _remove_job(self, key_path):
try:
self._scheduler.remove_job(key_path)
except JobLookupError:
LOG.info("No scheduled job for %s, creating new job", key_path)
def _create_success_callback(self, key_path, callback):
def success_callback():
job_info = self.job_dict[key_path]
self._remove_job(key_path)
watcher = job_info['watcher']
seconds = watcher.seconds_until_expiry()
new_interval = seconds - seconds / 5
self._scheduler.add_job(watcher.check_and_update, 'interval',
seconds=new_interval, id=key_path)
if callback:
try:
callback()
except Exception as e:
LOG.exception(e)
return success_callback
def _create_failure_callback(self, key_path):
def failure_callback():
job_info = self.job_dict[key_path]
self._remove_job(key_path)
watcher = job_info['watcher']
self._scheduler.add_job(watcher.check_and_update,
'interval', seconds=10, id=key_path)
return failure_callback
def add_cert_watch(self, driver, key_path, cert_path,
common_name, on_refresh_success=None,
jitter=0, refresh_window=None):
if self.is_tracked(key_path):
raise Exception("Already tracking certificate")
on_success = self._create_success_callback(key_path,
on_refresh_success)
on_failure = on_failure = self._create_failure_callback(key_path)
watcher = certwatch.CertWatcher(key_path, cert_path, common_name,
driver, on_refresh_success=on_success,
on_refresh_failure=on_failure)
self.job_dict[key_path] = {'watcher': watcher}
watcher.check_and_update()
def wait(self):
self._scheduler._thread.join()