# `ConduitMcp.Ext.Tasks.EtsStore`
[🔗](https://github.com/nyo16/conduit_mcp/blob/v0.11.0/lib/conduit_mcp/ext/tasks/ets_store.ex#L1)

In-memory `ConduitMcp.Ext.Tasks.Store` (experimental, unstable — see
`ConduitMcp.Ext.Tasks`).

Records live in the `:public` named ETS table `:conduit_mcp_ext_tasks`,
owned by `ConduitMcp.Ext.Tasks.EtsStore.Owner` (a `ConduitMcp.EtsOwner`) which
`ConduitMcp.Application` starts when the extension is enabled with this
store. Reads and writes go straight to ETS from the calling process.

Every read-modify-write is a compare-and-swap: `:ets.select_replace/2`
replaces the row only if it still equals the record the change was
computed from, and retries otherwise, so a client's `tasks/update` and a
worker's `complete/2` cannot overwrite each other.

Single-node only. Rows are evicted by `cleanup/1` (the Ext.Tasks janitor)
and capped at `:max_rows` (default 10 000) so a client looping a
task-creating tool cannot grow the table without bound.

# `cleanup`

```elixir
@spec cleanup(non_neg_integer(), integer()) :: non_neg_integer()
```

Evicts expired records (see `c:ConduitMcp.Ext.Tasks.Store.cleanup/1`)
as of `now` (Unix milliseconds, default the system clock) and returns
the count.

---

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