# SmartExit - Development Hints

## Logging System

The module uses consolidated logging with a `[smartexit]` prefix:

- **SmartExit instances**: Log cleanup and termination failures unless constructed with `{ silent: true }`.
- **ProcessLifecycle**: Logs the shutdown summary by default after `ProcessLifecycle.install()`.
- **Lifecycle silent mode**: Pass `{ silent: true }` to `ProcessLifecycle.install()` to disable lifecycle logging.

### Example output
```
[smartexit] Shutdown complete: 3 processes killed, 2 cleanup functions ran
```

### Usage

Default lifecycle summary logging:

```typescript
import { ProcessLifecycle, SmartExit } from '@push.rocks/smartexit';

const smartExit = new SmartExit();
ProcessLifecycle.install();
```

Fully silent application configuration:

```typescript
import { ProcessLifecycle, SmartExit } from '@push.rocks/smartexit';

const smartExit = new SmartExit({ silent: true });
ProcessLifecycle.install({ silent: true });
```

Custom POSIX termination grace:

```typescript
import { SmartExit } from '@push.rocks/smartexit';

const fastSmartExit = new SmartExit({ processTerminationGraceMs: 250 });
```

## killAll() Return Value

The `killAll()` method runs cleanup functions before snapshotting tracked process groups and returns stats about that pass:
```typescript
const { processesKilled, cleanupFunctionsRan } = await smartExit.killAll();
```

`processesKilled` counts each tracked root or process group at most once and only when at least one OS termination operation succeeds. Concurrent calls share one in-flight pass. PIDs registered after the snapshot remain tracked for the next pass.

Failed force-kills remain tracked for the synchronous exit safety net. `ProcessLifecycle` supplies a termination signal at its shutdown deadline so a long instance grace interval cannot keep the lifecycle pending. Calling `killAll()` from one of the same instance's cleanup functions is rejected to prevent self-deadlock.
