Check if scheduler port is available before starting process to avoid zombies
authorThierry Florac <thierry.florac@onf.fr>
Fri, 09 Nov 2018 11:54:43 +0100
changeset 72 b3c277ed52d4
parent 71 19c49f85449e
child 73 0f124b1be6a1
Check if scheduler port is available before starting process to avoid zombies
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)