|
37 | 37 | PROCESS_TERMINATION_TIMEOUT = 10 |
38 | 38 | PROCESS_OUTPUT_THREAD_JOIN_TIMEOUT = 2 |
39 | 39 | PROCESS_OUTPUT_SELECT_TIMEOUT = 0.2 |
| 40 | +GRACEFUL_SERVER_SHUTDOWN_RPC_TIMEOUT = 3 |
40 | 41 | GRACEFUL_SERVER_SHUTDOWN_TIMEOUT = 5 |
41 | 42 | OUTPUT_READER_STOP_EVENT_ATTR = "_bec_output_reader_stop_event" |
42 | 43 |
|
@@ -141,19 +142,18 @@ def _terminate_plot_process(process, logger, timeout: float = PROCESS_TERMINATIO |
141 | 142 | process.wait(timeout=timeout) |
142 | 143 | return |
143 | 144 | except Exception as exc: |
144 | | - logger.warning( |
145 | | - f"Failed to terminate GUI process group: {exc}; terminating process only. " |
146 | | - f"{process_details}" |
147 | | - ) |
| 145 | + logger.warning("Failed to terminate GUI process group; terminating process only.") |
| 146 | + logger.info(f"GUI process termination failure details: {exc}. {process_details}") |
148 | 147 | process.terminate() |
149 | 148 |
|
150 | 149 | try: |
151 | 150 | process.wait(timeout=timeout) |
152 | 151 | return |
153 | 152 | except subprocess.TimeoutExpired: |
154 | | - logger.warning( |
155 | | - f"GUI process did not stop within {timeout}s; killing it. " |
156 | | - f"{process_details}\n{_process_group_snapshot(process)}" |
| 153 | + logger.warning(f"GUI process did not stop within {timeout}s; killing it.") |
| 154 | + logger.info( |
| 155 | + f"GUI process force-kill details: {process_details}\n" |
| 156 | + f"{_process_group_snapshot(process)}" |
157 | 157 | ) |
158 | 158 |
|
159 | 159 | try: |
@@ -196,10 +196,8 @@ def _join_process_output_thread(process, thread: threading.Thread | None, logger |
196 | 196 | logger.error(f"Failed to close stream {str(e)}") |
197 | 197 | thread.join(timeout=PROCESS_OUTPUT_THREAD_JOIN_TIMEOUT) |
198 | 198 | if thread.is_alive(): |
199 | | - logger.warning( |
200 | | - "GUI process output reader thread did not stop after process shutdown. " |
201 | | - f"{_process_details(process)}" |
202 | | - ) |
| 199 | + logger.warning("GUI process output reader thread did not stop after process shutdown.") |
| 200 | + logger.info(f"GUI process output reader thread details: {_process_details(process)}") |
203 | 201 |
|
204 | 202 |
|
205 | 203 | def _start_plot_process( |
@@ -630,19 +628,26 @@ def _request_server_shutdown(self) -> bool: |
630 | 628 | logger.info(f"Requesting graceful GUI shutdown {process_details}") |
631 | 629 | try: |
632 | 630 | self.launcher._run_rpc( # pylint: disable=protected-access |
633 | | - "system.shutdown", wait_for_rpc_response=False |
| 631 | + "system.shutdown", |
| 632 | + wait_for_rpc_response=True, |
| 633 | + timeout=GRACEFUL_SERVER_SHUTDOWN_RPC_TIMEOUT, |
634 | 634 | ) |
635 | 635 | except Exception as exc: |
636 | 636 | logger.warning( |
637 | | - f"Could not request graceful GUI shutdown via RPC: {exc}. " f"{process_details}" |
| 637 | + "Could not confirm graceful GUI shutdown via RPC; " |
| 638 | + "falling back to process termination." |
638 | 639 | ) |
| 640 | + logger.info(f"Graceful GUI shutdown RPC failure details: {exc}. {process_details}") |
639 | 641 | return False |
640 | 642 | if _wait_for_process_exit(self._process, GRACEFUL_SERVER_SHUTDOWN_TIMEOUT): |
641 | 643 | logger.info(f"GUI server exited after graceful shutdown {process_details}") |
642 | 644 | return True |
643 | 645 | logger.warning( |
644 | 646 | "GUI server did not exit after graceful shutdown request; " |
645 | | - f"falling back to process termination. {process_details}\n" |
| 647 | + "falling back to process termination." |
| 648 | + ) |
| 649 | + logger.info( |
| 650 | + f"Graceful GUI shutdown timeout details: {process_details}\n" |
646 | 651 | f"{_process_group_snapshot(self._process)}" |
647 | 652 | ) |
648 | 653 | return False |
|
0 commit comments