# `Finitomata.Cache`
[🔗](https://github.com/am-kantox/finitomata/blob/v0.35.0/lib/finitomata/cache.ex#L1)

The self-curing cache based on `Finitomata` implementation.

This implementation should not be chosen for typical caching scenarios,
  use [`cachex`](https://hexdocs.pm/cachex) and/or [`con_cache`](https://hexdocs.pm/con_cache)
  instead.

The use-case for this implementation would be somewhat like a self-updated local replica
  of the remote data. Unlike typical cache implementations, this one might keep the cached
  values up-to-date, configured by `ttl:` argument. Bsaed on processes (backed by `Finitomata`,)
  this implementation updates itself periodically, making the value retrieval almost instant.

Consider a remote service supplying currency exchange rates by polling. One might instruct
  `Finitomata.Cache` to retrieve values periodically (say, once per a minute,) and then
  the consumers of this cache would be able to retrieve the up-to-date values locally without
  a penalty of getting a value after a long period (cache miss.)

First of all, the `Finitomata.Cache` implementation should be added to a supervision tree

```elixir
  {Finitomata.Cache, [
    [id: MyCache, ttl: 60_000, live?: true, type: Infinitomata, getter: &MyMod.getter/1]]}
```

Once the supervisor is started, the values might be retrieven as

```elixir
  Finitomata.Cache.get(MyCache, :my_key_1, live?: false) # use default getter
  Finitomata.Cache.get(MyCache, :my_key, getter: fn _ -> ExtService.get(:my_key) end)
```

# `child_spec`
*since 0.26.0* 

```elixir
@spec child_spec(
  id: term(),
  type: term(),
  ttl: pos_integer(),
  live?: boolean(),
  getter: (term() -&gt; term()) | term()
) :: Supervisor.child_spec()
```

# `erase`
*since 0.26.0* 

```elixir
@spec erase(id :: Finitomata.id(), key :: any()) :: :ok
```

Erases the cache assotiated with `key`.

# `get`
*since 0.26.0* 

```elixir
@spec get(
  id :: Finitomata.id(),
  key :: key,
  opts :: [
    getter: (key -&gt; value),
    live?: boolean(),
    reset: boolean(),
    ttl: pos_integer()
  ]
) :: {DateTime.t(), value} | {:instant, value} | :error
when key: any(), value: any()
```

Retrieves the value either cached or via `getter/1` anonymous function and caches it.

Spawns the respective _Finitomata_ instance if needed.

# `start_link`
*since 0.26.0* 

```elixir
@spec start_link(
  id: term(),
  type: term(),
  ttl: pos_integer(),
  live?: boolean(),
  getter: (term() -&gt; term()) | term()
) :: Supervisor.on_start()
```

Supervision tree embedder.

## Options to `Finitomata.Cache.start_link/1`

* `:id` (`t:term/0`) - Required. The unique `ID` of this _Finitomata_ “branch,” when `nil` the `Finitomata.Cache` value would be used

* `:type` - The actual `Finitomata.Supervisor` implementation (typically, `Finitomata` or `Infinitomata`) The default value is `Infinitomata`.

* `:ttl` (`t:pos_integer/0`) - Required. The default time-to-live value in seconds, after which the value would be either revalidated or discarded

* `:live?` (`t:boolean/0`) - When `true`, the value will be automatically renewed upon expiration (and discarded otherwise) The default value is `false`.

* `:getter` - The shared for all instances getter returning a value based on the name of the instance, used as a key The default value is `nil`.

---

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