Skip to content

Commit 9d18c8f

Browse files
committed
fix(con cache): allow concache to accept ets options
1 parent 46dee00 commit 9d18c8f

File tree

4 files changed

+82
-1
lines changed

4 files changed

+82
-1
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# 0.3.13
2+
- fix: allow `Cache.ConCache` to accept `ets_options` (strict NimbleOptions validation + normalization)
3+
14
# 0.3.12
25
- chore: fix warnings
36

lib/cache/ets.ex

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,51 @@ defmodule Cache.ETS do
225225
@impl Cache
226226
def opts_definition, do: @opts_definition
227227

228+
def opts_definition(opts) when is_list(opts) do
229+
if Keyword.keyword?(opts) do
230+
validate_and_normalize_ets_options(opts)
231+
else
232+
{:error, "expected a keyword list"}
233+
end
234+
end
235+
236+
def opts_definition(_opts), do: {:error, "expected a keyword list"}
237+
238+
defp validate_and_normalize_ets_options(opts) do
239+
case NimbleOptions.validate(opts, @opts_definition) do
240+
{:ok, validated} ->
241+
{:ok, normalize_ets_options(opts, validated)}
242+
243+
{:error, %NimbleOptions.ValidationError{} = error} ->
244+
{:error, Exception.message(error)}
245+
end
246+
end
247+
248+
defp normalize_ets_options(original_opts, validated) do
249+
Enum.reject(
250+
[
251+
maybe_type(original_opts, validated),
252+
maybe_compressed(original_opts, validated),
253+
maybe_kv(original_opts, validated, :read_concurrency),
254+
maybe_kv(original_opts, validated, :write_concurrency),
255+
maybe_kv(original_opts, validated, :decentralized_counters)
256+
],
257+
&is_nil/1
258+
)
259+
end
260+
261+
defp maybe_type(original_opts, validated) do
262+
if Keyword.has_key?(original_opts, :type), do: validated[:type]
263+
end
264+
265+
defp maybe_compressed(original_opts, validated) do
266+
if Keyword.has_key?(original_opts, :compressed) and validated[:compressed], do: :compressed
267+
end
268+
269+
defp maybe_kv(original_opts, validated, key) do
270+
if Keyword.has_key?(original_opts, key), do: {key, validated[key]}
271+
end
272+
228273
@impl Cache
229274
def start_link(opts) do
230275
Task.start_link(fn ->

mix.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ defmodule ElixirCache.MixProject do
44
def project do
55
[
66
app: :elixir_cache,
7-
version: "0.3.12",
7+
version: "0.3.13",
88
elixir: "~> 1.11",
99
start_permanent: Mix.env() == :prod,
1010
description:

test/cache/con_cache_test.exs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,39 @@ defmodule Cache.ConCacheTest do
55
"""
66
use ExUnit.Case, async: true
77

8+
describe "ets_options validation" do
9+
test "accepts ets_options keyword list" do
10+
validated =
11+
NimbleOptions.validate!(
12+
[ets_options: [read_concurrency: true, write_concurrency: false]],
13+
Cache.ConCache.opts_definition()
14+
)
15+
16+
assert [
17+
{:read_concurrency, true},
18+
{:write_concurrency, false}
19+
] = validated[:ets_options]
20+
end
21+
22+
test "rejects unknown ets_options keys" do
23+
assert_raise NimbleOptions.ValidationError, fn ->
24+
NimbleOptions.validate!(
25+
[ets_options: [read_concurency: true]],
26+
Cache.ConCache.opts_definition()
27+
)
28+
end
29+
end
30+
31+
test "rejects invalid ets_options value types" do
32+
assert_raise NimbleOptions.ValidationError, fn ->
33+
NimbleOptions.validate!(
34+
[ets_options: [read_concurrency: :yes]],
35+
Cache.ConCache.opts_definition()
36+
)
37+
end
38+
end
39+
end
40+
841
defmodule ConCacheAdapter do
942
use Cache,
1043
adapter: Cache.ConCache,

0 commit comments

Comments
 (0)