1
0
mirror of https://github.com/spl0k/supysonic.git synced 2024-11-09 19:52:16 +00:00

Slight changes to watcher

Configurable scan delay
Test friendliness
This commit is contained in:
spl0k 2017-12-05 22:15:04 +01:00
parent 2ea7224815
commit bb72ce8f7c
4 changed files with 34 additions and 15 deletions

View File

@ -79,7 +79,7 @@ Configuration files must respect a structure similar to Windows INI file, with
The sample configuration (`config.sample`) looks like this: The sample configuration (`config.sample`) looks like this:
``` ```ini
[base] [base]
; A Storm database URI. See the 'schema' folder for schema creation scripts ; A Storm database URI. See the 'schema' folder for schema creation scripts
; Default: sqlite:///tmp/supysonic/supysonic.db ; Default: sqlite:///tmp/supysonic/supysonic.db
@ -107,6 +107,11 @@ log_level = WARNING
;mount_webui = on ;mount_webui = on
[daemon] [daemon]
; Delay before triggering scanning operation after a change have been detected
; This prevents running too many scans when multiple changes are detected for a
; single file over a short time span. Default: 5
wait_delay = 5
; Optional rotating log file for the scanner daemon ; Optional rotating log file for the scanner daemon
log_file = /var/supysonic/supysonic-daemon.log log_file = /var/supysonic/supysonic-daemon.log
log_level = INFO log_level = INFO

View File

@ -25,6 +25,11 @@ log_level = WARNING
;mount_webui = on ;mount_webui = on
[daemon] [daemon]
; Delay before triggering scanning operation after a change have been detected
; This prevents running too many scans when multiple changes are detected for a
; single file over a short time span. Default: 5
wait_delay = 5
; Optional rotating log file for the scanner daemon ; Optional rotating log file for the scanner daemon
log_file = /var/supysonic/supysonic-daemon.log log_file = /var/supysonic/supysonic-daemon.log
log_level = INFO log_level = INFO

View File

@ -32,6 +32,7 @@ class DefaultConfig(object):
'mount_api': True 'mount_api': True
} }
DAEMON = { DAEMON = {
'wait_delay': 5,
'log_file': None, 'log_file': None,
'log_level': 'WARNING' 'log_level': 'WARNING'
} }
@ -67,6 +68,9 @@ class IniConfig(DefaultConfig):
def __try_parse(value): def __try_parse(value):
try: try:
return int(value) return int(value)
except ValueError:
try:
return float(value)
except ValueError: except ValueError:
lv = value.lower() lv = value.lower()
if lv in ('yes', 'true', 'on'): if lv in ('yes', 'true', 'on'):

View File

@ -108,10 +108,11 @@ class Event(object):
return self.__src return self.__src
class ScannerProcessingQueue(Thread): class ScannerProcessingQueue(Thread):
def __init__(self, database_uri, logger): def __init__(self, database_uri, delay, logger):
super(ScannerProcessingQueue, self).__init__() super(ScannerProcessingQueue, self).__init__()
self.__logger = logger self.__logger = logger
self.__timeout = delay
self.__database_uri = database_uri self.__database_uri = database_uri
self.__cond = Condition() self.__cond = Condition()
self.__timer = None self.__timer = None
@ -123,6 +124,7 @@ class ScannerProcessingQueue(Thread):
self.__run() self.__run()
except Exception, e: except Exception, e:
self.__logger.critical(e) self.__logger.critical(e)
raise e
def __run(self): def __run(self):
while self.__running: while self.__running:
@ -181,7 +183,7 @@ class ScannerProcessingQueue(Thread):
if self.__timer: if self.__timer:
self.__timer.cancel() self.__timer.cancel()
self.__timer = Timer(5, self.__wakeup) self.__timer = Timer(self.__timeout, self.__wakeup)
self.__timer.start() self.__timer.start()
def __wakeup(self): def __wakeup(self):
@ -195,7 +197,7 @@ class ScannerProcessingQueue(Thread):
return None return None
next = min(self.__queue.iteritems(), key = lambda i: i[1].time) next = min(self.__queue.iteritems(), key = lambda i: i[1].time)
if not self.__running or next[1].time + 5 <= time.time(): if not self.__running or next[1].time + self.__timeout <= time.time():
del self.__queue[next[0]] del self.__queue[next[0]]
return next[1] return next[1]
@ -204,6 +206,7 @@ class ScannerProcessingQueue(Thread):
class SupysonicWatcher(object): class SupysonicWatcher(object):
def __init__(self, config): def __init__(self, config):
self.__config = config self.__config = config
self.__running = True
def run(self): def run(self):
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -231,19 +234,21 @@ class SupysonicWatcher(object):
store.close() store.close()
return return
queue = ScannerProcessingQueue(self.__config.BASE['database_uri'], logger) queue = ScannerProcessingQueue(self.__config.BASE['database_uri'], self.__config.DAEMON['wait_delay'], logger)
handler = SupysonicWatcherEventHandler(self.__config.BASE['scanner_extensions'], queue, logger) handler = SupysonicWatcherEventHandler(self.__config.BASE['scanner_extensions'], queue, logger)
observer = Observer() observer = Observer()
for folder in folders: for folder in folders:
logger.info("Starting watcher for %s", folder.path) logger.info("Starting watcher for %s", folder.path)
observer.schedule(handler, folder.path, recursive = True) observer.schedule(handler, folder.path, recursive = True)
store.close() store.close()
try:
signal(SIGTERM, self.__terminate) signal(SIGTERM, self.__terminate)
signal(SIGINT, self.__terminate) signal(SIGINT, self.__terminate)
except:
logger.warning('Unable to set signal handlers')
self.__running = True
queue.start() queue.start()
observer.start() observer.start()
while self.__running: while self.__running: