# `ConduitMcp.Session.Janitor`
[🔗](https://github.com/nyo16/conduit_mcp/blob/v0.11.0/lib/conduit_mcp/session/janitor.ex#L1)

Periodically prunes expired sessions from a `ConduitMcp.Session.Store`.

ETS-backed stores accumulate session entries indefinitely without an
explicit eviction loop. Without a janitor, every successful `initialize`
request adds a row to the session table that lives until the BEAM restarts;
for a public-facing MCP server this is an unbounded memory growth surface.

Stores backed by systems with native TTL (Redis with `EX`, Mnesia with TTL
indices, etc.) do not need this janitor.

## Usage

Add the janitor to your application supervision tree:

    children = [
      {ConduitMcp.Session.Janitor,
       store: ConduitMcp.Session.EtsStore,
       ttl: :timer.minutes(30),
       interval: :timer.minutes(1)},
      # ...
    ]

## Options

- `:store` (required) - module implementing `ConduitMcp.Session.Store`
  that defines a `cleanup/1` callback.
- `:ttl` - maximum session age in milliseconds (default: 30 minutes).
  Sessions whose `created_at` exceeds this age are evicted.
- `:interval` - interval between cleanup runs in milliseconds
  (default: 1 minute).
- `:name` - registered process name (default: module name).
- `:telemetry_event` - event emitted after each run (default
  `[:conduit_mcp, :session, :cleanup]`), with measurements
  `%{removed: count}` and metadata `%{store: store}`.
- `:noun` - what the swept rows are called in the debug log
  (default `"expired sessions"`).

The last two exist because `ConduitMcp.Application` reuses this janitor for
the cancellation table. Without them a consumer's
`[:conduit_mcp, :session, :cleanup]` handler would receive cancellation
evictions as session evictions once a minute, and the same count would be
published under two event names - one of them wrong.

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `start_link`

---

*Consult [api-reference.md](api-reference.md) for complete listing*
