mac + windows standalone craching fixes
This commit is contained in:
@@ -251,25 +251,18 @@ REQUIRED_KEYS: dict[str, Any] = {
|
||||
}
|
||||
|
||||
|
||||
# audit_log = logging.getLogger("memory_audit")
|
||||
# audit_log.setLevel(logging.INFO)
|
||||
# audit_log.propagate = False # This prevents it from talking to other loggers
|
||||
|
||||
# # 2. Add a file handler specifically for this audit logger
|
||||
# if not audit_log.handlers:
|
||||
# fh = logging.FileHandler('flares_memory_audit.log')
|
||||
# fh.setFormatter(logging.Formatter('%(asctime)s | PID: %(process)d | %(message)s'))
|
||||
# audit_log.addHandler(fh)
|
||||
|
||||
import logging
|
||||
import os
|
||||
import psutil
|
||||
import traceback
|
||||
|
||||
audit_log = logging.getLogger("memory_audit")
|
||||
audit_log.setLevel(logging.INFO)
|
||||
audit_log.propagate = False # This prevents it from talking to other loggers
|
||||
|
||||
# 2. Add a file handler specifically for this audit logger
|
||||
if not audit_log.handlers:
|
||||
fh = logging.FileHandler('flares_memory_audit.log')
|
||||
fh.setFormatter(logging.Formatter('%(asctime)s | PID: %(process)d | %(message)s'))
|
||||
audit_log.addHandler(fh)
|
||||
|
||||
def get_mem_mb():
|
||||
return psutil.Process(os.getpid()).memory_info().rss / 1024 / 1024
|
||||
# def get_mem_mb():
|
||||
# return psutil.Process(os.getpid()).memory_info().rss / 1024 / 1024
|
||||
|
||||
|
||||
|
||||
@@ -375,10 +368,10 @@ def gui_entry(config: dict[str, Any], gui_queue: Queue, progress_queue: Queue) -
|
||||
max_workers = file_params.get("MAX_WORKERS", int(os.cpu_count()/4))
|
||||
|
||||
results = process_multiple_participants(
|
||||
file_paths, file_params, file_metadata, progress_queue, max_workers
|
||||
file_paths, file_params, file_metadata, progress_queue, gui_queue, max_workers
|
||||
)
|
||||
|
||||
gui_queue.put({"success": True, "result": results})
|
||||
gui_queue.put({"success": True})
|
||||
|
||||
except Exception as e:
|
||||
gui_queue.put({
|
||||
@@ -423,15 +416,15 @@ def process_participant_worker(file_path, file_params, file_metadata, result_que
|
||||
finally:
|
||||
# --- THE FIX: MANDATORY EXIT ---
|
||||
# Explicitly flush the logs and force the process to terminate
|
||||
audit_log.info(f"Worker for {file_name} calling hard exit.")
|
||||
#audit_log.info(f"Worker for {file_name} calling hard exit.")
|
||||
sys.stdout.flush()
|
||||
sys.stderr.flush()
|
||||
# We use os._exit(0) as a nuclear option if sys.exit() is being caught by a try/except
|
||||
os._exit(0)
|
||||
|
||||
|
||||
def process_multiple_participants(file_paths, file_params, file_metadata, progress_queue=None, max_workers=6):
|
||||
audit_log.info(f"--- SESSION START: {len(file_paths)} files ---")
|
||||
def process_multiple_participants(file_paths, file_params, file_metadata, progress_queue=None, gui_queue=None, max_workers=6):
|
||||
#audit_log.info(f"--- SESSION START: {len(file_paths)} files ---")
|
||||
|
||||
pending_files = list(file_paths)
|
||||
active_processes = [] # List of tuples: (Process object, file_path)
|
||||
@@ -454,16 +447,25 @@ def process_multiple_participants(file_paths, file_params, file_metadata, progre
|
||||
)
|
||||
p.start()
|
||||
active_processes.append((p, file_path))
|
||||
audit_log.info(f"Spawned worker. Active processes: {len(active_processes)}")
|
||||
#audit_log.info(f"Spawned worker. Active processes: {len(active_processes)}")
|
||||
|
||||
# 2. COLLECT RESULTS: Drain the queue continuously so workers don't deadlock
|
||||
while not result_queue.empty():
|
||||
try:
|
||||
res_path, result, error = result_queue.get_nowait()
|
||||
if not error:
|
||||
results_by_file[res_path] = result
|
||||
# SEND IMMEDIATELY TO THE MAIN GUI
|
||||
if gui_queue:
|
||||
gui_queue.put({
|
||||
"type": "file_done",
|
||||
"file": res_path,
|
||||
"success": error is None,
|
||||
"result": result if error is None else None,
|
||||
"error": error if error else None
|
||||
})
|
||||
else:
|
||||
audit_log.error(f"Worker failed on {os.path.basename(res_path)}: {error}")
|
||||
# Fallback if no GUI queue (e.g., CLI mode)
|
||||
results_by_file[res_path] = result
|
||||
|
||||
except Exception:
|
||||
break # Queue is empty or busy
|
||||
|
||||
@@ -472,12 +474,12 @@ def process_multiple_participants(file_paths, file_params, file_metadata, progre
|
||||
if not p.is_alive():
|
||||
p.join() # Formally close the process to free OS resources
|
||||
active_processes.remove((p, f_path))
|
||||
audit_log.info(f"Worker finished. Active processes dropping to: {len(active_processes)}")
|
||||
#audit_log.info(f"Worker finished. Active processes dropping to: {len(active_processes)}")
|
||||
|
||||
# Brief pause to prevent this while loop from pegging your CPU to 100%
|
||||
time.sleep(0.5)
|
||||
|
||||
audit_log.info("--- SESSION COMPLETE ---")
|
||||
#audit_log.info("--- SESSION COMPLETE ---")
|
||||
return results_by_file
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user