diff --git a/mara_pipelines/execution.py b/mara_pipelines/execution.py index 60a4a32..2187ed1 100644 --- a/mara_pipelines/execution.py +++ b/mara_pipelines/execution.py @@ -378,7 +378,10 @@ def _create_exception_output_event(msg: str = None): # At least try to notify the UI for e in exception_events: - print(f"{repr(e)}", file=sys.stderr) + if isinstance(e, KeyboardInterrupt): + print(f"Interrupted", file=sys.stderr) + else: + print(f"{repr(e)}", file=sys.stderr) yield e events.notify_configured_event_handlers(e) # try to terminate the run_process which itself will also cleanup in an atexit handler diff --git a/mara_pipelines/logging/system_statistics.py b/mara_pipelines/logging/system_statistics.py index 485c4fb..c09547c 100644 --- a/mara_pipelines/logging/system_statistics.py +++ b/mara_pipelines/logging/system_statistics.py @@ -64,42 +64,46 @@ def mem_usage(): def swap_usage(): swap = psutil.swap_memory() return 100.0 * swap.used / swap.total if swap.total > 0 else None - - # immediately send event for current cpu, mem and swap usage - event_queue.put(SystemStatistics( - datetime.datetime.now(), cpu_usage=cpu_usage(), mem_usage=mem_usage(), swap_usage=swap_usage())) - period = config.system_statistics_collection_period() - - n = 0 - - # some counters on WSL1 return None because psutil thinks it's linux, - # but the linux kernel API is not implemented and fails - # This lets it always return 0 for all attributes on that counter and lets at least CPU show up - class _zero(): - def __getattr__(self, item): return 0 - zero = _zero() - - # capture current disc and net state for later diff - discs_last = psutil.disk_io_counters() or zero - nets_last = psutil.net_io_counters() or zero - mb = 1024 * 1024 - time.sleep(period) - while True: - discs_cur = psutil.disk_io_counters() or zero - nets_cur = psutil.net_io_counters() or zero + try: + # immediately send event for current cpu, mem and swap usage event_queue.put(SystemStatistics( - datetime.datetime.now(), - disc_read=(discs_cur.read_bytes - discs_last.read_bytes) / mb / period, - disc_write=(discs_cur.write_bytes - discs_last.write_bytes) / mb / period, - net_recv=(nets_cur.bytes_recv - nets_last.bytes_recv) / mb / period, - net_sent=(nets_cur.bytes_sent - nets_last.bytes_sent) / mb / period, - cpu_usage=cpu_usage(), mem_usage=mem_usage(), swap_usage=swap_usage())) - nets_last = nets_cur - discs_last = discs_cur - - # double period every 100 measurements in order to avoid sending too many requests to frontend - n += 1 - if n % 100 == 0: - period *= 2 - + datetime.datetime.now(), cpu_usage=cpu_usage(), mem_usage=mem_usage(), swap_usage=swap_usage())) + period = config.system_statistics_collection_period() + + n = 0 + + # some counters on WSL1 return None because psutil thinks it's linux, + # but the linux kernel API is not implemented and fails + # This lets it always return 0 for all attributes on that counter and lets at least CPU show up + class _zero(): + def __getattr__(self, item): return 0 + zero = _zero() + + # capture current disc and net state for later diff + discs_last = psutil.disk_io_counters() or zero + nets_last = psutil.net_io_counters() or zero + mb = 1024 * 1024 time.sleep(period) + + while True: + discs_cur = psutil.disk_io_counters() or zero + nets_cur = psutil.net_io_counters() or zero + event_queue.put(SystemStatistics( + datetime.datetime.now(), + disc_read=(discs_cur.read_bytes - discs_last.read_bytes) / mb / period, + disc_write=(discs_cur.write_bytes - discs_last.write_bytes) / mb / period, + net_recv=(nets_cur.bytes_recv - nets_last.bytes_recv) / mb / period, + net_sent=(nets_cur.bytes_sent - nets_last.bytes_sent) / mb / period, + cpu_usage=cpu_usage(), mem_usage=mem_usage(), swap_usage=swap_usage())) + nets_last = nets_cur + discs_last = discs_cur + + # double period every 100 measurements in order to avoid sending too many requests to frontend + n += 1 + if n % 100 == 0: + period *= 2 + time.sleep(period) + except KeyboardInterrupt: + # happens e.g. when someone shuts down the webserver... + # does not bubble up, so if this get caught here it might need a second ctr+c + return