# Erlang REDI: an ETS cache without REDIS
Copyright (c) 2019-24 Renaud Mariana.
[![hex.pm badge](https://img.shields.io/badge/Package%20on%20hex.pm-informational)](https://hex.pm/packages/redi)
[![Erlang CI](https://github.com/bougueil/erlang-redi/actions/workflows/ci.yml/badge.svg)](https://github.com/bougueil/erlang-redi/actions/workflows/ci.yml)
## Erlang Redi
An erlang ETS cache with TTL.
The typical usage is:
```
case redi:get(..) of
[] ->
get the value from slow storage
redi:set(..)
[value] ->
use value ...
end
```
This service ensures that data hold by the cache are `fresh enough` (<= TTL) and ***doesn't guarantee*** that data before their TTL expiration are still in sync with the underlying storage, but this is good enough for our use cases.
Redi is a gen_server that could be added to a supervision tree.
### Example:
Its usage is very simple :
```erlang
$ rebar3 shell
Bucket = test,
{ok, Pid} = redi:start_link(#{bucket_name => Bucket,
entry_ttl_ms=> 30000}),
redi:set(Pid, <<"key1">>, <<"data11">>),
redi:set(Pid, <<"key1">>, <<"data12">>),
redi:set(Pid, <<"key2">>, <<"moredata">>),
redi:delete(Pid, <<"key2">>),
redi:get(Bucket, <<"key1">>).
%% working with several buckets
redi:add_bucket(Pid, another_bucket, bag),
redi:set(Pid, <<"keyx">>, <<"data.aaay">>, another_bucket),
redi:get(another_bucket, <<"keyx">>).
...
```
### Performance
Excerpt from a run of the unit test (i5-1235U)
- throughput 363464 writes/s.
- throughput **3478260** reads/s.
### Registering to keys that are GCed
```erlang
redi:gc_client(Redi_Pid, self(), Opts).
receive
{redi_gc, _, Keys} -> ok
%% see more examples in unit tests
```
## Elixir
Redi requires Elixir v1.15 or later. Then add Redi as a dependency:
```elixir
def deps do
[
{:redi, "~> 0.8"},
]
end
```
### Starting Redi inside a supervisor :
```elixir
# application.ex
children = [
{:redi,
[:redi_dns, #
%{bucket_name: :dns, entry_ttl_ms: :timer.minutes(5)} ]}
]
```
then Redi can be used as:
```elixir
:redi.set(Process.whereis(:redi_dns), "mykey", "a_value")
:redi.get(:dns, "mykey")
```