intellicrack.core.process_manager
Centralized process management for Intellicrack.
This module provides a singleton ProcessManager that tracks all spawned processes and ensures proper cleanup on application exit, signal handling, or exceptions.
- pid_is_running(pid)[source]
Report whether a live OS process exists for
pid.Public wrapper over the module’s PID-liveness probe, for callers outside this module that need to check a process they track by PID rather than by
Popenhandle.
- exception ProcessStateError[source]
Bases:
RuntimeErrorRaised when a tracked subprocess finishes in an unexpected state.
This error surfaces cases where a subprocess wrapped by
ProcessManagerleavesreturncodeunset aftercommunicatereturns, indicating the operating system failed to report the final exit status.
- class ProcessType[source]
Bases:
EnumType of process being tracked.
- SUBPROCESS = 'subprocess'
- ASYNC_SUBPROCESS = 'async_subprocess'
- EXTERNAL_TOOL = 'external_tool'
- SANDBOX = 'sandbox'
- DEBUGGER = 'debugger'
- class TrackedProcess[source]
Bases:
objectInformation about a tracked process.
- process_type: ProcessType
- registered_at: datetime
- property pid: int | None
Process ID if available.
- Returns:
The process ID, or None if not available.
- Return type:
int | None
- property is_running: bool
Check if process is still running.
- Returns:
True if the process is still running, False otherwise.
- Return type:
- check_running()[source]
Check if process is still running (non-cached version).
This method exists to avoid mypy’s type narrowing on property access. Use this when checking running state after an operation that may have changed the process state.
- Returns:
True if the process is still running, False otherwise.
- Return type:
- __init__(process, process_type, name, registered_at=<factory>, metadata=<factory>, cleanup_callback=None)
- class TrackedEntry[source]
Bases:
objectUnified, serializable view of a tracked process or external PID.
Produced by
ProcessManager.get_all_tracked_entries(), combining subprocess-backedTrackedProcessentries with PIDs registered viaProcessManager.register_external_pid()into a single shape so UI consumers (e.g. the Tracked tab) can render both categories without knowing which backing store an entry came from.- process_type: ProcessType
- class ProcessManager[source]
Bases:
objectCentralized manager for all spawned processes.
This singleton class tracks all processes spawned by Intellicrack and ensures proper cleanup on application exit. It handles: - Normal exit via atexit handlers - Signal-based termination (SIGINT, SIGTERM) - Graceful shutdown with timeout followed by forceful termination
- Variables:
- static __new__(cls)[source]
Create or return the singleton instance.
- Returns:
The singleton ProcessManager instance.
- Return type:
- classmethod get_instance()[source]
Get the singleton instance.
- Returns:
The singleton ProcessManager instance.
- Return type:
- prepare_for_teardown()[source]
Reset internal state in preparation for singleton teardown.
- Return type:
None
- install_handlers()[source]
Install signal handlers and atexit hook for cleanup.
This should be called once during application startup, typically in
main.pybefore any processes are spawned. The atexit hook is registered at most once per Python interpreter — even whenreset_instance()is invoked between calls — using a module-level guard so cleanup never executes twice on shutdown.- Return type:
None
- uninstall_handlers()[source]
Uninstall signal handlers (restore original handlers).
- Return type:
None
- run_atexit_cleanup()[source]
Public entry point that runs the at-exit cleanup once.
Delegates to
_atexit_cleanup(); provided so the global hook can invoke instance cleanup without violating member-access lint rules.- Return type:
None
- static terminate_tree(pid, graceful_timeout=5.0, force_timeout=3.0)[source]
Terminate a process tree using psutil.
Kills the root process and all its descendants. First sends SIGTERM and waits for graceful_timeout, then sends SIGKILL to any survivors and waits for force_timeout.
- register(process, name, process_type=ProcessType.SUBPROCESS, metadata=None, cleanup_callback=None)[source]
Register a process for tracking.
- Parameters:
name (str) – Human-readable name for the process.
process_type (ProcessType) – Type of process being tracked.
metadata (dict[str, Any] | None) – Optional metadata about the process.
cleanup_callback (Callable[[], Coroutine[Any, Any, None]] | None) – Optional async callback for custom cleanup.
- Returns:
The process ID used as the tracking key.
- Return type:
- unregister(pid)[source]
Unregister a process from tracking.
- Parameters:
pid (int) – The process ID to unregister.
- Returns:
The tracked process info if found, None otherwise.
- Return type:
TrackedProcess | None
- get_tracked(pid)[source]
Get tracked process information.
- Parameters:
pid (int) – The process ID to look up.
- Returns:
The tracked process info if found, None otherwise.
- Return type:
TrackedProcess | None
- get_all_tracked()[source]
Get all tracked processes.
- Returns:
List of all tracked processes.
- Return type:
- get_all_tracked_entries()[source]
Get a unified view of all tracked processes and external PIDs.
Combines subprocess-backed entries from
get_all_tracked()with PIDs registered viaregister_external_pid(), resolving live running state for each so UI consumers (e.g. the Tracked tab) can render both categories without querying two separate stores.- Returns:
Combined, serializable tracked-process entries.
- Return type:
- get_running_processes()[source]
Get all currently running tracked processes.
- Returns:
List of tracked processes that are still running.
- Return type:
- async terminate_process(pid, graceful_timeout=None, force_timeout=None)[source]
Terminate a specific process.
- async cleanup_all_async(graceful_timeout=None, force_timeout=None)[source]
Cleanup all tracked processes asynchronously.
- is_shutdown_requested()[source]
Check if shutdown has been requested via signal.
- Returns:
True if a shutdown signal has been received, False otherwise.
- Return type:
- request_shutdown()[source]
Request and perform an immediate shutdown of all tracked processes.
Sets the shutdown flag observed by
is_shutdown_requested(), then synchronously runs_sync_cleanup(), which walks every tracked subprocess and external PID (including descendant processes) and terminates them. This gives callers – such asMainWindow.closeEvent– a guaranteed, bounded final sweep that reaps any process left behind by a bridge whose owndetach/shutdown/stopteardown silently failed or timed out, rather than merely flipping a flag nothing else acts on.- Return type:
None
- property process_count: int
Number of tracked processes.
- Returns:
The total count of tracked processes.
- Return type:
- property running_count: int
Number of running tracked processes.
- Returns:
The count of currently running tracked processes.
- Return type:
- __repr__()[source]
Return string representation.
- Returns:
A string representation of the ProcessManager state.
- Return type:
- run_tracked(args, name, *, capture_output=True, text=True, timeout=None, cwd=None, env=None, check=False, creationflags=0)[source]
Execute a subprocess with ProcessManager tracking.
This method wraps subprocess execution to ensure the process is tracked and will be terminated during application shutdown.
- Parameters:
name (str) – Human-readable name for the process.
capture_output (bool) – Capture stdout and stderr.
text (bool) – Decode output as text (returns str); False returns bytes.
timeout (float | None) – Maximum time to wait for process.
cwd (str | None) – Working directory for the process.
env (dict[str, str] | None) – Environment variables for the process.
check (bool) – Raise CalledProcessError if process returns non-zero.
creationflags (int) – Windows process creation flags.
- Returns:
Execution results (stdout/stderr as str if text=True).
- Return type:
CompletedProcess[Any]
- Raises:
TimeoutExpired – If timeout exceeded.
CalledProcessError – If check=True and process failed.
ProcessStateError – If the subprocess returns without an exit status.
- async run_tracked_async(args, name, *, capture_output=True, text=True, process_timeout=None, cwd=None, env=None, check=False, creationflags=0)[source]
Execute a subprocess asynchronously with ProcessManager tracking.
This method wraps subprocess execution to ensure the process is tracked and will be terminated during application shutdown. It delegates to run_tracked via asyncio.to_thread.
- Parameters:
name (str) – Human-readable name for the process.
capture_output (bool) – Capture stdout and stderr.
text (bool) – Decode output as text.
process_timeout (float | None) – Maximum time to wait for process.
cwd (str | None) – Working directory for the process.
env (dict[str, str] | None) – Environment variables for the process.
check (bool) – Raise CalledProcessError if process returns non-zero.
creationflags (int) – Windows process creation flags.
- Returns:
Execution results with captured stdout/stderr.
- Return type:
CompletedProcess[Any]
- register_external_pid(pid, name, process_type=ProcessType.EXTERNAL_TOOL, metadata=None)[source]
Register an external process by PID for cleanup tracking.
Use this for processes not directly spawned by subprocess (e.g., daemonized processes) that should be terminated when the application exits. Verifies the PID corresponds to a live OS process via
_pid_exists()before registering.- Parameters:
- Raises:
ValueError – If
piddoes not correspond to a live process.- Return type:
None