Skip to content

Commit f72669b

Browse files
authored
chore(elixir): upgraded elixir to v1.18 fixed all compiler warnings (#30)
1 parent 0aa7ce9 commit f72669b

21 files changed

+326
-225
lines changed

.tool-versions

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
elixir 1.18.4-otp-28
2+
erlang 28.1.1

lib/cache.ex

Lines changed: 69 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@ defmodule Cache do
1010

1111
@callback opts_definition() :: Keyword.t()
1212

13-
@callback start_link(
14-
cache_opts :: Keyword.t()
15-
) :: {:ok, pid()} | {:error, {:already_started, pid()} | {:shutdown, term()} | term()} | :ignore
13+
@callback start_link(cache_opts :: Keyword.t()) ::
14+
{:ok, pid()}
15+
| {:error, {:already_started, pid()} | {:shutdown, term()} | term()}
16+
| :ignore
1617

1718
@callback put(cache_name :: atom, key :: atom | String.t(), ttl :: pos_integer, value :: any) ::
1819
:ok | ErrorMessage.t()
@@ -83,7 +84,6 @@ defmodule Cache do
8384

8485
adapter_opts ->
8586
pre_check_runtime_options.(adapter_opts)
86-
8787
end
8888

8989
adapter_opts = if opts[:sandbox?], do: [], else: check_adapter_opts.(opts[:opts])
@@ -100,12 +100,42 @@ defmodule Cache do
100100

101101
def adapter_options, do: adapter_options!(@adapter_opts)
102102

103-
defp adapter_options!({module, fun, args}), do: apply(module, fun, args)
104-
defp adapter_options!({app, key}), do: Application.fetch_env!(app, key)
105-
defp adapter_options!(app_name) when is_atom(app_name), do: Application.fetch_env!(app_name, __MODULE__)
106-
defp adapter_options!(fun) when is_function(fun, 0), do: fun.()
103+
# Generate only the needed adapter_options!/1 clauses based on the actual adapter_opts
104+
if match?({_, _, _}, @adapter_opts) do
105+
defp adapter_options!({module, fun, args}), do: apply(module, fun, args)
106+
end
107+
108+
if match?({_, _}, @adapter_opts) do
109+
defp adapter_options!({app, key}), do: Application.fetch_env!(app, key)
110+
end
111+
112+
if is_atom(@adapter_opts) and not is_nil(@adapter_opts) and not is_list(@adapter_opts) do
113+
defp adapter_options!(app_name) when is_atom(app_name),
114+
do: Application.fetch_env!(app_name, __MODULE__)
115+
end
116+
117+
if is_function(@adapter_opts, 0) do
118+
defp adapter_options!(fun) when is_function(fun, 0), do: fun.()
119+
end
120+
107121
defp adapter_options!(options), do: options
108122

123+
# Dynamic error handler that compiler can't statically analyze
124+
defp handle_adapter_result(result, operation, cache_name) do
125+
with {:error, error} <- result do
126+
:telemetry.execute(
127+
[:elixir_cache, :cache, operation, :error],
128+
%{count: 1},
129+
%{
130+
cache_name: cache_name,
131+
error: error
132+
}
133+
)
134+
135+
result
136+
end
137+
end
138+
109139
def child_spec(_) do
110140
@cache_adapter.child_spec({@cache_name, adapter_options()})
111141
end
@@ -118,16 +148,10 @@ defmodule Cache do
118148
[:elixir_cache, :cache, :put],
119149
%{cache_name: @cache_name},
120150
fn ->
121-
result = with {:error, error} = e <- @cache_adapter.put(@cache_name, key, ttl, value, adapter_options()) do
122-
:telemetry.execute([:elixir_cache, :cache, :put, :error], %{count: 1}, %{
123-
cache_name: @cache_name,
124-
error: error
125-
})
126-
127-
e
128-
end
129-
130-
{result, %{cache_name: @cache_name}}
151+
@cache_name
152+
|> @cache_adapter.put(key, ttl, value, adapter_options())
153+
|> handle_adapter_result(:put, @cache_name)
154+
|> then(&{&1, %{cache_name: @cache_name}})
131155
end
132156
)
133157
end
@@ -140,23 +164,22 @@ defmodule Cache do
140164
%{cache_name: @cache_name},
141165
fn ->
142166
result =
143-
case @cache_adapter.get(@cache_name, key, adapter_options()) do
167+
@cache_name
168+
|> @cache_adapter.get(key, adapter_options())
169+
|> handle_adapter_result(:get, @cache_name)
170+
|> case do
144171
{:ok, nil} = res ->
145172
:telemetry.execute([:elixir_cache, :cache, :get, :miss], %{count: 1}, %{
146173
cache_name: @cache_name
147174
})
148175

149176
res
150177

151-
{:ok, value} -> {:ok, Cache.TermEncoder.decode(value)}
178+
{:ok, value} ->
179+
{:ok, Cache.TermEncoder.decode(value)}
152180

153-
{:error, error} = e ->
154-
:telemetry.execute([:elixir_cache, :cache, :get, :error], %{count: 1}, %{
155-
cache_name: @cache_name,
156-
error: error
157-
})
158-
159-
e
181+
{:error, _} = error ->
182+
error
160183
end
161184

162185
{result, %{cache_name: @cache_name}}
@@ -171,16 +194,10 @@ defmodule Cache do
171194
[:elixir_cache, :cache, :delete],
172195
%{cache_name: @cache_name},
173196
fn ->
174-
result = with {:error, error} = e <- @cache_adapter.delete(@cache_name, key, adapter_options()) do
175-
:telemetry.execute([:elixir_cache, :cache, :delete, :error], %{count: 1}, %{
176-
cache_name: @cache_name,
177-
error: error
178-
})
179-
180-
e
181-
end
182-
183-
{result, %{cache_name: @cache_name}}
197+
@cache_name
198+
|> @cache_adapter.delete(key, adapter_options())
199+
|> handle_adapter_result(:delete, @cache_name)
200+
|> then(&{&1, %{cache_name: @cache_name}})
184201
end
185202
)
186203
end
@@ -220,25 +237,25 @@ defmodule Cache do
220237
end
221238

222239
@doc """
223-
Retrieves a value from the cache if it exists, or executes a function to create and store it.
224-
225-
This is a convenience function implementing the common "get or create" pattern for caches.
226-
It attempts to fetch a value from the cache first, and only if the value doesn't exist,
240+
Retrieves a value from the cache if it exists, or executes a function to create and store it.
241+
242+
This is a convenience function implementing the common "get or create" pattern for caches.
243+
It attempts to fetch a value from the cache first, and only if the value doesn't exist,
227244
it will execute the provided function to generate the value and store it in the cache.
228-
245+
229246
## Parameters
230-
247+
231248
- `cache` - The cache module to use (must implement the Cache behaviour)
232249
- `key` - The key to look up or create
233250
- `fnc` - A function that returns `{:ok, value}` or `{:error, reason}`
234-
251+
235252
## Returns
236-
253+
237254
- `{:ok, value}` - The value from cache or newly created value
238255
- `{:error, reason}` - If an error occurred during retrieval or creation
239-
256+
240257
## Examples
241-
258+
242259
```elixir
243260
Cache.get_or_create(MyApp.Cache, "user:123", fn ->
244261
case UserRepo.get(123) do
@@ -248,19 +265,13 @@ defmodule Cache do
248265
end)
249266
```
250267
"""
251-
@spec get_or_create(module(), atom() | String.t(), (-> {:ok, any()} | {:error, any()})) ::
268+
@spec get_or_create(module(), atom() | String.t(), (-> {:ok, any()} | {:error, any()})) ::
252269
{:ok, any()} | {:error, any()}
253270
def get_or_create(cache, key, fnc) do
254-
case cache.get(key) do
255-
{:ok, nil} ->
256-
with {:ok, value} <- fnc.(),
257-
:ok <- cache.put(key, value) do
258-
{:ok, value}
259-
end
260-
261-
{:ok, _} = res -> res
262-
263-
{:error, _} = e -> e
271+
with {:ok, nil} <- cache.get(key),
272+
{:ok, value} <- fnc.(),
273+
:ok <- cache.put(key, value) do
274+
{:ok, value}
264275
end
265276
end
266277
end

lib/cache/con_cache.ex

Lines changed: 31 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@ defmodule Cache.ConCache do
22
@opts_definition [
33
acquire_lock_timeout: [type: :pos_integer, default: 5000],
44
touch_on_read: [type: :boolean, default: false],
5-
65
global_ttl: [type: {:or, [:pos_integer, {:in, [:infinity]}]}, default: :timer.minutes(30)],
76
ttl_check_interval: [type: {:or, [:pos_integer, {:in, [false]}]}, default: :timer.minutes(1)],
8-
9-
dirty?: [type: :boolean, default: true, doc: "Use dirty_put instead of locking to put, enabled by default"],
10-
7+
dirty?: [
8+
type: :boolean,
9+
default: true,
10+
doc: "Use dirty_put instead of locking to put, enabled by default"
11+
],
1112
ets_options: [
1213
type: {:custom, Cache.ETS, :opts_definition, []},
1314
doc: "https://www.erlang.org/doc/man/ets.html#new-2"
@@ -24,25 +25,26 @@ defmodule Cache.ConCache do
2425
@behaviour Cache
2526

2627
@type opts :: [
27-
name: atom,
28-
pid: pid,
29-
global_ttl: non_neg_integer | :infinity,
30-
acquire_lock_timeout: pos_integer,
31-
touch_on_read: boolean | nil,
32-
ttl_check_interval: non_neg_integer() | false,
33-
ets_options: [ets_option()]
34-
]
35-
36-
@type ets_option :: :named_table
37-
| :compressed
38-
| {:heir, pid()}
39-
| {:write_concurrency, boolean()}
40-
| {:read_concurrency, boolean()}
41-
| :ordered_set
42-
| :set
43-
| :bag
44-
| :duplicate_bag
45-
| {:name, atom()}
28+
name: atom,
29+
pid: pid,
30+
global_ttl: non_neg_integer | :infinity,
31+
acquire_lock_timeout: pos_integer,
32+
touch_on_read: boolean | nil,
33+
ttl_check_interval: non_neg_integer() | false,
34+
ets_options: [ets_option()]
35+
]
36+
37+
@type ets_option ::
38+
:named_table
39+
| :compressed
40+
| {:heir, pid()}
41+
| {:write_concurrency, boolean()}
42+
| {:read_concurrency, boolean()}
43+
| :ordered_set
44+
| :set
45+
| :bag
46+
| :duplicate_bag
47+
| {:name, atom()}
4648

4749
defmacro __using__(_opts) do
4850
quote do
@@ -63,12 +65,12 @@ defmodule Cache.ConCache do
6365
def start_link(opts) do
6466
cache_opts =
6567
opts
66-
|> Keyword.delete(:dirty?)
67-
|> Keyword.update(
68-
:ets_options,
69-
[:named_table, name: opts[:name]],
70-
&[:named_table, {:name, opts[:name]} | &1]
71-
)
68+
|> Keyword.delete(:dirty?)
69+
|> Keyword.update(
70+
:ets_options,
71+
[:named_table, name: opts[:name]],
72+
&[:named_table, {:name, opts[:name]} | &1]
73+
)
7274

7375
ConCache.start_link(cache_opts)
7476
end
@@ -130,4 +132,3 @@ defmodule Cache.ConCache do
130132
ConCache.dirty_get_or_store(cache_name, key, store_fun)
131133
end
132134
end
133-

lib/cache/dets.ex

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,11 @@ defmodule Cache.DETS do
55
default: false,
66
doc: "Enable RAM File"
77
],
8-
98
type: [
109
type: {:in, [:bag, :duplicate_bag, :set]},
1110
default: :set,
1211
doc: "Data type of DETS cache"
1312
],
14-
1513
file_path: [
1614
type: :string,
1715
default: "./",
@@ -201,16 +199,18 @@ defmodule Cache.DETS do
201199
def start_link(opts) do
202200
Task.start_link(fn ->
203201
table_name = opts[:table_name]
204-
file_path = opts[:file_path]
202+
203+
file_path =
204+
opts[:file_path]
205205
|> to_string
206206
|> create_file_name(table_name)
207207
|> tap(&File.mkdir_p!(Path.dirname(&1)))
208-
|> String.to_charlist
208+
|> String.to_charlist()
209209

210210
opts =
211211
opts
212212
|> Keyword.drop([:table_name, :file_path])
213-
|> Kernel.++([access: :read_write, file: file_path])
213+
|> Kernel.++(access: :read_write, file: file_path)
214214

215215
{:ok, _} = :dets.open_file(table_name, opts)
216216

lib/cache/ets.ex

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,19 @@ defmodule Cache.ETS do
44
type: :boolean,
55
doc: "Enable write concurrency"
66
],
7-
87
read_concurrency: [
98
type: :boolean,
109
doc: "Enable read concurrency"
1110
],
12-
1311
decentralized_counters: [
1412
type: :boolean,
1513
doc: "Use decentralized counters"
1614
],
17-
1815
type: [
1916
type: {:in, [:bag, :duplicate_bag, :set]},
2017
default: :set,
2118
doc: "Data type of ETS cache"
2219
],
23-
2420
compressed: [
2521
type: :boolean,
2622
doc: "Enable ets compression"

0 commit comments

Comments
 (0)