diff --git a/docs/ENVIRONMENT.rst b/docs/ENVIRONMENT.rst index b08b3dbe..7e90c527 100644 --- a/docs/ENVIRONMENT.rst +++ b/docs/ENVIRONMENT.rst @@ -19,6 +19,8 @@ Global/Universal - **PATRONI\_LOG\_FILE\_NUM**: The number of application logs to retain. - **PATRONI\_LOG\_FILE\_SIZE**: Size of patroni.log file (in bytes) that triggers a log rolling. - **PATRONI\_LOG\_LOGGERS**: Redefine logging level per python module. Example ``PATRONI_LOG_LOGGERS="{patroni.postmaster: WARNING, urllib3: DEBUG}"`` +- **PATRONI\_DEBUG\_MODE**: When set to a non-empty value, makes Patroni run in the special debug mode that enables stepping with a debugger through some execution paths within Patroni ` +Example ``PATRONI_DEBUG_MODE="on"`` Bootstrap configuration ----------------------- diff --git a/patroni.py b/patroni.py index f34ef133..dc216f4c 100755 --- a/patroni.py +++ b/patroni.py @@ -1,6 +1,14 @@ #!/usr/bin/env python from patroni import main +import os if __name__ == '__main__': + + if os.getenv("PATRONI_DEBUG_MODE"): + # XXX Visual Code specific https://github.com/microsoft/ptvsd/issues/1443 + # create processes by spawning new Python interpreters instead of forking the current one + import multiprocessing + multiprocessing.set_start_method('spawn', True) + main() diff --git a/patroni/__init__.py b/patroni/__init__.py index 8af4d6af..674bb5ca 100644 --- a/patroni/__init__.py +++ b/patroni/__init__.py @@ -32,6 +32,7 @@ class Patroni(object): self.postgresql = Postgresql(self.config['postgresql']) self.api = RestApiServer(self, self.config['restapi']) self.ha = Ha(self) + self.is_in_debug_mode = bool(os.getenv("PATRONI_DEBUG_MODE")) self.tags = self.get_tags() self.next_run = time.time() @@ -102,8 +103,9 @@ class Patroni(object): self.next_run = current_time # Release the GIL so we don't starve anyone waiting on async_executor lock time.sleep(0.001) - # Warn user that Patroni is not keeping up - logger.warning("Loop time exceeded, rescheduling immediately.") + # Warn user that Patroni is not keeping up or runs in debug + msg = "Patroni runs in the debug mode: keys' TTL is infinite, loop wait disabled" if self.is_in_debug_mode else "Loop time exceeded, rescheduling immediately." + logger.warning(msg) elif self.ha.watch(nap_time): self.next_run = time.time() diff --git a/patroni/config.py b/patroni/config.py index b73a6fea..5417cdf3 100644 --- a/patroni/config.py +++ b/patroni/config.py @@ -332,6 +332,11 @@ class Config(object): config['postgresql'][name] = deepcopy(value) elif name not in config or name in ['watchdog']: config[name] = deepcopy(value) if value else {} + + if os.getenv("PATRONI_DEBUG_MODE"): + config['ttl'] = 24 * 60 * 60 # practical infinity for a debugging session + config['loop_wait'] = -1 + # restapi server expects to get restapi.auth = 'username:password' if 'authentication' in config['restapi']: