# HG changeset patch # User Thierry Florac # Date 1541760883 -3600 # Node ID b3c277ed52d4d0acb73c1d257447ea3417cb2c02 # Parent 19c49f85449ef9714c84a315b4b02e7b1ea55d2f Check if scheduler port is available before starting process to avoid zombies diff -r 19c49f85449e -r b3c277ed52d4 src/pyams_scheduler/include.py --- a/src/pyams_scheduler/include.py Mon Jun 11 16:08:21 2018 +0200 +++ b/src/pyams_scheduler/include.py Fri Nov 09 11:54:43 2018 +0100 @@ -9,6 +9,8 @@ # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # FOR A PARTICULAR PURPOSE. # +from pyams_utils.protocol.tcp import is_port_in_use + __docformat__ = 'restructuredtext' @@ -65,46 +67,50 @@ settings = registry.settings start_handler = asbool(settings.get(SCHEDULER_STARTER_KEY, False)) if start_handler: - # get database connection - connection = get_connection_from_settings(settings) - root = connection.root() - # get application - application_name = settings.get(PYAMS_APPLICATION_SETTINGS_KEY, PYAMS_APPLICATION_DEFAULT_NAME) - application = root.get(application_name) - if application is not None: - sm = application.getSiteManager() - set_local_registry(sm) - process = None - try: - scheduler_util = sm.get(SCHEDULER_NAME) + # check if port is available + handler_address = settings.get(SCHEDULER_HANDLER_KEY, '127.0.0.1:5555') + hostname, port = handler_address.split(':') + if not is_port_in_use(int(port), hostname): + # get database connection + connection = get_connection_from_settings(settings) + root = connection.root() + # get application + application_name = settings.get(PYAMS_APPLICATION_SETTINGS_KEY, PYAMS_APPLICATION_DEFAULT_NAME) + application = root.get(application_name) + if application is not None: + sm = application.getSiteManager() + set_local_registry(sm) + process = None try: - zodb_name = scheduler_util.zodb_name - except ComponentLookupError: - pass - else: - # create scheduler process - process = SchedulerProcess(settings.get(SCHEDULER_HANDLER_KEY, '127.0.0.1:5555'), - SchedulerMessageHandler, - settings.get(SCHEDULER_AUTH_KEY), - settings.get(SCHEDULER_CLIENTS_KEY), - registry) - # load tasks - for task in scheduler_util.values(): - trigger = task.get_trigger(registry) - logger.debug("Adding scheduler job for task '{0.name}'".format(task)) - process.scheduler.add_job(task, trigger, - id=str(task.internal_id), - name=task.name, - kwargs={'zodb_name': zodb_name, - 'registry': registry}) - # start process - logger.info("Starting tasks scheduler {0!r}...".format(process)) - process.start() - if process.is_alive(): - atexit.register(process_exit_func, process=process) - logger.info("Started tasks scheduler with PID {0}.".format(process.pid)) - finally: - if process and not process.is_alive(): - process.terminate() - process.join() - set_local_registry(None) + scheduler_util = sm.get(SCHEDULER_NAME) + try: + zodb_name = scheduler_util.zodb_name + except ComponentLookupError: + pass + else: + # create scheduler process + process = SchedulerProcess(handler_address, + SchedulerMessageHandler, + settings.get(SCHEDULER_AUTH_KEY), + settings.get(SCHEDULER_CLIENTS_KEY), + registry) + # load tasks + for task in scheduler_util.values(): + trigger = task.get_trigger(registry) + logger.debug("Adding scheduler job for task '{0.name}'".format(task)) + process.scheduler.add_job(task, trigger, + id=str(task.internal_id), + name=task.name, + kwargs={'zodb_name': zodb_name, + 'registry': registry}) + # start process + logger.info("Starting tasks scheduler {0!r}...".format(process)) + process.start() + if process.is_alive(): + atexit.register(process_exit_func, process=process) + logger.info("Started tasks scheduler with PID {0}.".format(process.pid)) + finally: + if process and not process.is_alive(): + process.terminate() + process.join() + set_local_registry(None)