You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
102 lines
2.7 KiB
Python
102 lines
2.7 KiB
Python
"""
|
|
Send signal to pid 1 to reload service
|
|
"""
|
|
import glob
|
|
import os
|
|
import signal
|
|
from multiprocessing import Process
|
|
|
|
from watchdog.events import FileSystemEventHandler
|
|
from watchdog.observers import Observer
|
|
|
|
from .logs import Logs
|
|
|
|
|
|
class Reload(FileSystemEventHandler):
|
|
|
|
"""Reload object"""
|
|
|
|
def __init__(self, sig, reloader, pid=1):
|
|
self.signal = sig
|
|
self.reloader = reloader
|
|
self.pid = pid
|
|
self.log = Logs().log
|
|
|
|
def on_any_event(self, event):
|
|
if event.src_path in self.reloader.files:
|
|
self.log.info(
|
|
'File {file} has changed, send sig {sig} to pid {pid}'.format(
|
|
file=event.src_path,
|
|
sig=self.signal,
|
|
pid=self.pid,
|
|
)
|
|
)
|
|
os.kill(self.pid, self.signal)
|
|
else:
|
|
self.log.debug(
|
|
'Reloader triggered but file {file} is not watched'.format(
|
|
file=event.src_path
|
|
)
|
|
)
|
|
|
|
|
|
class Reloader(object):
|
|
|
|
"""Reload service when files change"""
|
|
|
|
def __init__(self, sig='SIGHUP', files=[]):
|
|
if not files:
|
|
raise Exception('No file to watch for reload')
|
|
|
|
self.log = Logs().log
|
|
self.proc = None
|
|
self._files = files
|
|
sig_attr = getattr(signal, sig)
|
|
try:
|
|
assert int(sig_attr)
|
|
except BaseException:
|
|
raise Exception('Wrong signal provided for reload')
|
|
self.observer = Observer()
|
|
rel = Reload(sig=sig_attr, reloader=self)
|
|
for dir in self.dirs:
|
|
self.log.debug('Registering watcher for {dir}'.format(dir=dir))
|
|
self.observer.schedule(rel, dir, recursive=False)
|
|
|
|
def _get_files(self):
|
|
"""Return iterator of tuples (path, file)"""
|
|
for f in self._files:
|
|
for m in glob.iglob(f):
|
|
if os.path.isdir(m):
|
|
yield (m, m)
|
|
yield (os.path.dirname(m), m)
|
|
if os.path.isdir(f):
|
|
yield (f, f)
|
|
yield (os.path.dirname(f), f)
|
|
|
|
@property
|
|
def files(self):
|
|
"""Return list of watched files"""
|
|
return list(set([files[1] for files in self._get_files()]))
|
|
|
|
@property
|
|
def dirs(self):
|
|
"""Return list of watched directories"""
|
|
return list(set([files[0] for files in self._get_files()]))
|
|
|
|
def run(self, ret=False):
|
|
while True:
|
|
self.observer.start()
|
|
if ret:
|
|
return self.observer
|
|
self.observer.join()
|
|
|
|
def run_in_process(self):
|
|
self.proc = Process(target=self.run)
|
|
self.proc.start()
|
|
|
|
def stop(self):
|
|
if self.proc:
|
|
self.proc.stop()
|
|
else:
|
|
self.observer.stop()
|