diff --git a/docker_volume_watcher/container_notifier.py b/docker_volume_watcher/container_notifier.py index c335560..00c8376 100644 --- a/docker_volume_watcher/container_notifier.py +++ b/docker_volume_watcher/container_notifier.py @@ -5,11 +5,43 @@ import logging from os.path import relpath import posixpath +import time import docker from watchdog.observers import Observer from watchdog.events import PatternMatchingEventHandler +def debounce(bounce_delay): + """ + define debounce method annotation + + Args: + bounce_delay (int): the minimum delay in seconds between two function calls + """ + + def decorate(my_function): + """ + Decorator ensures function that can only be called once every `bounce_delay` seconds. + + Args: + my_function (function): the function to debounce + """ + + old_time = {'value' : None} + + def wrapped(*args, **kwargs): + """ + internal function + """ + new_time = time.time() + if old_time['value'] is None or new_time - old_time['value'] >= bounce_delay: + result = my_function(*args, **kwargs) + old_time['value'] = time.time() + return result + return None + return wrapped + return decorate + class NonZeroExitError(RuntimeError): """ A non-zero exit code error from the command execution in docker. @@ -54,6 +86,10 @@ def __init__(self, container, host_dir, container_dir, exclude_patterns=None): def __str__(self): return '%s -> %s:%s' % (self.host_dir, self.container.name, self.container_dir) + # debounce avoid two subsequents save to ooccur + # limitation, if several files are saved the same time + # some files could be skipped + @debounce(2) def __change_handler(self, event): host_path = event.dest_path if hasattr(event, 'dest_path') else event.src_path relative_host_path = relpath(host_path, self.host_dir).replace('\\', '/')