# `StaticMaps.TileCache`
[🔗](https://gitlab.com/tristanperalta/staticmaps/blob/v0.1.0/lib/static_maps/tile_cache.ex#L1)

Where fetched tiles are kept between renders.

A cache is a module implementing this behaviour. The default,
`StaticMaps.TileCache.ETS`, keeps tiles in memory up to a byte limit. Configure it, or
another implementation, with:

    config :staticmaps, :tile_cache,
      module: StaticMaps.TileCache.ETS,
      max_bytes: 64 * 1024 * 1024

`module: nil` turns caching off.

Only sources that implement `c:StaticMaps.Source.fetch_cacheable/3` are cached, which
includes every `StaticMaps.Source.HTTP` source, unless their `info/1` says
`cache: false`. Several commercial providers forbid keeping their tiles on a server;
see `guides/tile-providers.md`. A tile is kept for as long as the
server's `Cache-Control` or `Expires` allows, 7 days when it sends neither, and not at
all under `no-store`. An expired tile is revalidated with a conditional request, and
served stale if the server cannot be reached.

The cache never holds a tile that would fail to render: a response is stored only once
it has decoded as a complete image of the expected size.

# `entry`

```elixir
@type entry() :: %{
  body: binary(),
  expires_at: integer(),
  max_age: non_neg_integer(),
  etag: String.t() | nil,
  last_modified: String.t() | nil
}
```

* `:body` — the tile's bytes
* `:expires_at` — Unix time in seconds after which the tile must be revalidated
* `:max_age` — the lifetime the tile was stored with, kept for when a `304` renews it
  without saying
* `:etag`, `:last_modified` — validators for the conditional request, if the server
  sent them

# `key`

```elixir
@type key() :: term()
```

A cache key; opaque to the implementation.

# `get`

```elixir
@callback get(key()) :: {:ok, entry()} | :error
```

Returns the entry for `key`, fresh or not.

# `put`

```elixir
@callback put(key(), entry()) :: :ok
```

Stores `entry` under `key`, replacing any entry already there.

---

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