summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZuul <zuul@review.opendev.org>2022-10-06 06:27:12 +0000
committerGerrit Code Review <review@openstack.org>2022-10-06 06:27:12 +0000
commit4d648bb8558860ffd602feb0f9746e11806a57ca (patch)
tree9c761ffb6a38e2f433f034f8c44afe91b343daaf
parentfb42f827e2c4ff15de4296f54bd49a94f6b4128a (diff)
parent1eda9ccf96a8924e67217d23746b04971c3bb48a (diff)
downloadzuul-4d648bb8558860ffd602feb0f9746e11806a57ca.tar.gz
Merge "Correct exit routine in web, merger"
-rwxr-xr-xzuul/cmd/merger.py2
-rwxr-xr-xzuul/cmd/scheduler.py1
-rwxr-xr-xzuul/cmd/web.py8
-rwxr-xr-xzuul/web/__init__.py55
4 files changed, 45 insertions, 21 deletions
diff --git a/zuul/cmd/merger.py b/zuul/cmd/merger.py
index f1e0bea88..57f39835e 100755
--- a/zuul/cmd/merger.py
+++ b/zuul/cmd/merger.py
@@ -16,7 +16,6 @@
# under the License.
import signal
-import sys
import zuul.cmd
import zuul.merger.server
@@ -34,7 +33,6 @@ class Merger(zuul.cmd.ZuulDaemonApp):
def exit_handler(self, signum, frame):
self.merger.stop()
self.merger.join()
- sys.exit(0)
def run(self):
self.handleCommands()
diff --git a/zuul/cmd/scheduler.py b/zuul/cmd/scheduler.py
index 7ed30b68e..a429d19f7 100755
--- a/zuul/cmd/scheduler.py
+++ b/zuul/cmd/scheduler.py
@@ -76,7 +76,6 @@ class Scheduler(zuul.cmd.ZuulDaemonApp):
def exit_handler(self, signum, frame):
self.sched.stop()
self.sched.join()
- sys.exit(0)
def run(self):
self.handleCommands()
diff --git a/zuul/cmd/web.py b/zuul/cmd/web.py
index bb9348c71..da3d9a85e 100755
--- a/zuul/cmd/web.py
+++ b/zuul/cmd/web.py
@@ -67,7 +67,13 @@ class WebServer(zuul.cmd.ZuulDaemonApp):
self.log.info('Zuul Web Server starting')
self.web.start()
- self.web.join()
+ try:
+ self.web.join()
+ except KeyboardInterrupt:
+ print("Ctrl + C: asking process to exit nicely...\n")
+ self.exit_handler(signal.SIGINT, None)
+ self.web.join()
+
self.log.info("Zuul Web Server stopped")
def configure_authenticators(self):
diff --git a/zuul/web/__init__.py b/zuul/web/__init__.py
index 995b28271..09706057b 100755
--- a/zuul/web/__init__.py
+++ b/zuul/web/__init__.py
@@ -1690,6 +1690,7 @@ class StreamManager(object):
log = logging.getLogger("zuul.web")
def __init__(self, statsd, metrics):
+ self.thread = None
self.statsd = statsd
self.metrics = metrics
self.hostname = normalize_statsd_name(socket.getfqdn())
@@ -1709,9 +1710,10 @@ class StreamManager(object):
self.thread.start()
def stop(self):
- self._stopped = True
- os.write(self.wake_write, b'\n')
- self.thread.join()
+ if self.thread:
+ self._stopped = True
+ os.write(self.wake_write, b'\n')
+ self.thread.join()
def run(self):
while not self._stopped:
@@ -1789,11 +1791,13 @@ class ZuulWeb(object):
connections,
authenticators: AuthenticatorRegistry,
info: WebInfo = None):
+ self._running = False
self.start_time = time.time()
self.config = config
self.tracing = tracing.Tracing(self.config)
self.metrics = WebMetrics()
self.statsd = get_statsd(config)
+ self.wsplugin = None
self.listen_address = get_default(self.config,
'web', 'listen_address',
@@ -1824,6 +1828,7 @@ class ZuulWeb(object):
self.component_registry = COMPONENT_REGISTRY.create(self.zk_client)
+ self.system_config_thread = None
self.system_config_cache_wake_event = threading.Event()
self.system_config_cache = SystemConfigCache(
self.zk_client,
@@ -2023,38 +2028,51 @@ class ZuulWeb(object):
return cherrypy.server.bound_addr[1]
def start(self):
- self.log.debug("ZuulWeb starting")
+ self.log.info("ZuulWeb starting")
+ self._running = True
self.component_info.state = self.component_info.INITIALIZING
+
+ self.log.info("Starting command processor")
+ self._command_running = True
+ self.command_socket.start()
+ self.command_thread = threading.Thread(target=self.runCommand,
+ name='command')
+ self.command_thread.daemon = True
+ self.command_thread.start()
+
# Wait for system config and layouts to be loaded
+ self.log.info("Waiting for system config from scheduler")
while not self.system_config_cache.is_valid:
- self.system_config_cache_wake_event.wait()
+ self.system_config_cache_wake_event.wait(1)
+ if not self._running:
+ return
# Initialize the system config
self.updateSystemConfig()
# Wait until all layouts/tenants are loaded
+ self.log.info("Waiting for all tenants to load")
while True:
self.system_config_cache_wake_event.clear()
self.updateLayout()
if (set(self.unparsed_abide.tenants.keys())
!= set(self.abide.tenants.keys())):
- self.system_config_cache_wake_event.wait()
+ while True:
+ self.system_config_cache_wake_event.wait(1)
+ if not self._running:
+ return
+ if self.system_config_cache_wake_event.is_set():
+ break
else:
break
+ self.log.info("Starting HTTP listeners")
self.stream_manager.start()
self.wsplugin = WebSocketPlugin(cherrypy.engine)
self.wsplugin.subscribe()
cherrypy.engine.start()
- self.log.debug("Starting command processor")
- self._command_running = True
- self.command_socket.start()
- self.command_thread = threading.Thread(target=self.runCommand,
- name='command')
- self.command_thread.daemon = True
- self.command_thread.start()
self.component_info.state = self.component_info.RUNNING
self.system_config_thread = threading.Thread(
@@ -2065,24 +2083,27 @@ class ZuulWeb(object):
self.system_config_thread.start()
def stop(self):
- self.log.debug("ZuulWeb stopping")
+ self.log.info("ZuulWeb stopping")
+ self._running = False
self.component_info.state = self.component_info.STOPPED
cherrypy.engine.exit()
# Not strictly necessary, but without this, if the server is
# started again (e.g., in the unit tests) it will reuse the
# same host/port settings.
cherrypy.server.httpserver = None
- self.wsplugin.unsubscribe()
+ if self.wsplugin:
+ self.wsplugin.unsubscribe()
self.stream_manager.stop()
self._system_config_running = False
self.system_config_cache_wake_event.set()
- self.system_config_thread.join()
- self.zk_client.disconnect()
+ if self.system_config_thread:
+ self.system_config_thread.join()
self.stopRepl()
self._command_running = False
self.command_socket.stop()
self.monitoring_server.stop()
self.tracing.stop()
+ self.zk_client.disconnect()
def join(self):
self.command_thread.join()