Main master loop.
(self)
| 215 | self.SIG_QUEUE.put_nowait(sig) |
| 216 | |
| 217 | def run(self): |
| 218 | "Main master loop." |
| 219 | self.start() |
| 220 | util._setproctitle("master [%s]" % self.proc_name) |
| 221 | |
| 222 | try: |
| 223 | self.manage_workers() |
| 224 | |
| 225 | # Start control socket server after initial workers are spawned |
| 226 | # to avoid fork deadlocks with asyncio |
| 227 | self._start_control_server() |
| 228 | |
| 229 | while True: |
| 230 | self.maybe_promote_master() |
| 231 | |
| 232 | # Wait for and process signals |
| 233 | for sig in self.wait_for_signals(timeout=1.0): |
| 234 | if sig not in self.SIG_NAMES: |
| 235 | self.log.info("Ignoring unknown signal: %s", sig) |
| 236 | continue |
| 237 | |
| 238 | signame = self.SIG_NAMES.get(sig) |
| 239 | handler = getattr(self, "handle_%s" % signame, None) |
| 240 | if not handler: |
| 241 | self.log.error("Unhandled signal: %s", signame) |
| 242 | continue |
| 243 | # Log SIGCHLD at debug level since it's frequent |
| 244 | log_level = self.log.debug if sig == signal.SIGCHLD else self.log.info |
| 245 | log_level("Handling signal: %s", signame) |
| 246 | handler() |
| 247 | |
| 248 | self.murder_workers() |
| 249 | self.manage_workers() |
| 250 | self.manage_dirty_arbiter() |
| 251 | except (StopIteration, KeyboardInterrupt): |
| 252 | self.halt() |
| 253 | except HaltServer as inst: |
| 254 | self.halt(reason=inst.reason, exit_status=inst.exit_status) |
| 255 | except SystemExit: |
| 256 | raise |
| 257 | except Exception: |
| 258 | self.log.error("Unhandled exception in main loop", |
| 259 | exc_info=True) |
| 260 | self.stop(False) |
| 261 | if self.pidfile is not None: |
| 262 | self.pidfile.unlink() |
| 263 | sys.exit(-1) |
| 264 | |
| 265 | def signal_chld(self, sig, frame): |
| 266 | """SIGCHLD signal handler - NO LOGGING, just queue the signal.""" |
no test coverage detected