From 4c12f0da443909363b5cd8dd82cc0b4e5c836be9 Mon Sep 17 00:00:00 2001 From: cabol Date: Sun, 7 May 2023 11:37:12 +0200 Subject: [PATCH 1/8] [#199] Fix `Nebulex.Cache` docs --- lib/mix/tasks/nbx.gen.cache.ex | 2 -- lib/nebulex/cache.ex | 60 +++++++++++++--------------------- 2 files changed, 22 insertions(+), 40 deletions(-) diff --git a/lib/mix/tasks/nbx.gen.cache.ex b/lib/mix/tasks/nbx.gen.cache.ex index f5aeb14b..373a4bfe 100644 --- a/lib/mix/tasks/nbx.gen.cache.ex +++ b/lib/mix/tasks/nbx.gen.cache.ex @@ -83,8 +83,6 @@ defmodule Mix.Tasks.Nbx.Gen.Cache do {#{inspect(cache)}, []} - And for more information about configuration options, check - adapters documentation and Nebulex.Cache shared options. """) end diff --git a/lib/nebulex/cache.ex b/lib/nebulex/cache.ex index f2113630..512e09e9 100644 --- a/lib/nebulex/cache.ex +++ b/lib/nebulex/cache.ex @@ -689,9 +689,7 @@ defmodule Nebulex.Cache do Returns `nil` if no result was found. - ## Options - - See the "Shared options" section at the module documentation for more options. + See the configured adapter documentation for runtime options. ## Example @@ -710,9 +708,7 @@ defmodule Nebulex.Cache do @doc """ Similar to `c:get/2` but raises `KeyError` if `key` is not found. - ## Options - - See the "Shared options" section at the module documentation for more options. + See the configured adapter documentation for runtime options. ## Example @@ -727,9 +723,7 @@ defmodule Nebulex.Cache do If `keys` contains keys that are not in the Cache, they're simply ignored. - ## Options - - See the "Shared options" section at the module documentation for more options. + See the configured adapter documentation for runtime options. ## Example @@ -755,7 +749,7 @@ defmodule Nebulex.Cache do (or expiry time) for the given key in **milliseconds**. Defaults to `:infinity`. - See the "Shared options" section at the module documentation for more options. + See the configured adapter documentation for more runtime options. ## Example @@ -796,7 +790,7 @@ defmodule Nebulex.Cache do (or expiry time) for the given key in **milliseconds**. Defaults to `:infinity`. - See the "Shared options" section at the module documentation for more options. + See the configured adapter documentation for more runtime options. ## Example @@ -825,7 +819,7 @@ defmodule Nebulex.Cache do (or expiry time) for the given key in **milliseconds**. Defaults to `:infinity`. - See the "Shared options" section at the module documentation for more options. + See the configured adapter documentation for more runtime options. ## Example @@ -853,7 +847,7 @@ defmodule Nebulex.Cache do (or expiry time) for the given key in **milliseconds**. Defaults to `:infinity`. - See the "Shared options" section at the module documentation for more options. + See the configured adapter documentation for more runtime options. ## Example @@ -876,7 +870,7 @@ defmodule Nebulex.Cache do (or expiry time) for the given key in **milliseconds**. Defaults to `:infinity`. - See the "Shared options" section at the module documentation for more options. + See the configured adapter documentation for more runtime options. ## Example @@ -905,7 +899,7 @@ defmodule Nebulex.Cache do (or expiry time) for the given key in **milliseconds**. Defaults to `:infinity`. - See the "Shared options" section at the module documentation for more options. + See the configured adapter documentation for more runtime options. ## Example @@ -935,7 +929,7 @@ defmodule Nebulex.Cache do (or expiry time) for the given key in **milliseconds**. Defaults to `:infinity`. - See the "Shared options" section at the module documentation for more options. + See the configured adapter documentation for more runtime options. ## Example @@ -948,9 +942,7 @@ defmodule Nebulex.Cache do @doc """ Deletes the entry in Cache for a specific `key`. - ## Options - - See the "Shared options" section at the module documentation for more options. + See the configured adapter documentation for runtime options. ## Example @@ -973,9 +965,7 @@ defmodule Nebulex.Cache do Returns and removes the value associated with `key` in the Cache. If the `key` does not exist, then `nil` is returned. - ## Options - - See the "Shared options" section at the module documentation for more options. + See the configured adapter documentation for runtime options. ## Examples @@ -994,9 +984,7 @@ defmodule Nebulex.Cache do @doc """ Similar to `c:take/2` but raises `KeyError` if `key` is not found. - ## Options - - See the "Shared options" section at the module documentation for more options. + See the configured adapter documentation for runtime options. ## Example @@ -1040,7 +1028,7 @@ defmodule Nebulex.Cache do (or expiry time) for the given key in **milliseconds**. Defaults to `:infinity`. - See the "Shared options" section at the module documentation for more options. + See the configured adapter documentation for more runtime options. ## Examples @@ -1088,7 +1076,7 @@ defmodule Nebulex.Cache do (or expiry time) for the given key in **milliseconds**. Defaults to `:infinity`. - See the "Shared options" section at the module documentation for more options. + See the configured adapter documentation for more runtime options. ## Examples @@ -1117,7 +1105,7 @@ defmodule Nebulex.Cache do inserted as initial value of key before the it is incremented. Defaults to `0`. - See the "Shared options" section at the module documentation for more options. + See the configured adapter documentation for more runtime options. ## Examples @@ -1152,7 +1140,7 @@ defmodule Nebulex.Cache do inserted as initial value of key before the it is incremented. Defaults to `0`. - See the "Shared options" section at the module documentation for more options. + See the configured adapter documentation for more runtime options. ## Examples @@ -1307,7 +1295,7 @@ defmodule Nebulex.Cache do adapters, but it is recommended to see the adapter's documentation to confirm its compatibility with this option. - See the "Shared options" section at the module documentation for more options. + See the configured adapter documentation for more runtime options. ## Query return option @@ -1417,7 +1405,7 @@ defmodule Nebulex.Cache do back from the cache's backend. Defaults to `20`; it's unlikely this will ever need changing. - See the "Shared options" section at the module documentation for more options. + See the configured adapter documentation for more runtime options. ## Query return option @@ -1492,14 +1480,12 @@ defmodule Nebulex.Cache do May raise `Nebulex.QueryError` if query validation fails. + See the configured adapter documentation for runtime options. + ## Query values See `c:all/2` callback for more information about the query values. - ## Options - - See the "Shared options" section at the module documentation for more options. - ## Example Populate the cache with some entries: @@ -1646,9 +1632,7 @@ defmodule Nebulex.Cache do A successful transaction returns the value returned by the function. - ## Options - - See the "Shared options" section at the module documentation for more options. + See the configured adapter documentation for runtime options. ## Examples From b47726ee2b549915268af7a0f19ebb99f5b1049b Mon Sep 17 00:00:00 2001 From: cabol Date: Sun, 7 May 2023 12:03:24 +0200 Subject: [PATCH 2/8] [#195] Documenting that `nil` values are not stored for write operations --- lib/nebulex/cache.ex | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/lib/nebulex/cache.ex b/lib/nebulex/cache.ex index 512e09e9..9cfca475 100644 --- a/lib/nebulex/cache.ex +++ b/lib/nebulex/cache.ex @@ -743,6 +743,9 @@ defmodule Nebulex.Cache do time to live associated with the key is discarded on successful `put` operation. + By default, `nil` values are skipped, which means they are not stored; + the call to the adapter is bypassed. + ## Options * `:ttl` - (positive integer or `:infinity`) Defines the time-to-live @@ -813,6 +816,9 @@ defmodule Nebulex.Cache do Returns `true` if a value was set, otherwise, `false` is returned. + By default, `nil` values are skipped, which means they are not stored; + the call to the adapter is bypassed. + ## Options * `:ttl` - (positive integer or `:infinity`) Defines the time-to-live @@ -841,13 +847,7 @@ defmodule Nebulex.Cache do Similar to `c:put_new/3` but raises `Nebulex.KeyAlreadyExistsError` if the key already exists. - ## Options - - * `:ttl` - (positive integer or `:infinity`) Defines the time-to-live - (or expiry time) for the given key in **milliseconds**. Defaults - to `:infinity`. - - See the configured adapter documentation for more runtime options. + See `c:put_new/3` for general considerations and options. ## Example @@ -893,6 +893,9 @@ defmodule Nebulex.Cache do Returns `true` if a value was set, otherwise, `false` is returned. + By default, `nil` values are skipped, which means they are not stored; + the call to the adapter is bypassed. + ## Options * `:ttl` - (positive integer or `:infinity`) Defines the time-to-live @@ -923,13 +926,7 @@ defmodule Nebulex.Cache do @doc """ Similar to `c:replace/3` but raises `KeyError` if `key` is not found. - ## Options - - * `:ttl` - (positive integer or `:infinity`) Defines the time-to-live - (or expiry time) for the given key in **milliseconds**. Defaults - to `:infinity`. - - See the configured adapter documentation for more runtime options. + See `c:replace/3` for general considerations and options. ## Example @@ -965,6 +962,8 @@ defmodule Nebulex.Cache do Returns and removes the value associated with `key` in the Cache. If the `key` does not exist, then `nil` is returned. + If `key` is `nil`, the call to the adapter is bypassed, and `nil` is returned. + See the configured adapter documentation for runtime options. ## Examples @@ -984,7 +983,7 @@ defmodule Nebulex.Cache do @doc """ Similar to `c:take/2` but raises `KeyError` if `key` is not found. - See the configured adapter documentation for runtime options. + See `c:take/2` for general considerations and options. ## Example From b594b20b0c90e2d676c7c41cf39ed0477c5960bd Mon Sep 17 00:00:00 2001 From: cabol Date: Sun, 7 May 2023 14:03:45 +0200 Subject: [PATCH 3/8] [#200] Support returning storing options in the decorators `match` option --- lib/nebulex/caching/decorators.ex | 45 +++++++++++++++++++------------ test/nebulex/caching_test.exs | 15 +++++++++++ 2 files changed, 43 insertions(+), 17 deletions(-) diff --git a/lib/nebulex/caching/decorators.ex b/lib/nebulex/caching/decorators.ex index 5693dd07..3528ea7c 100644 --- a/lib/nebulex/caching/decorators.ex +++ b/lib/nebulex/caching/decorators.ex @@ -49,8 +49,8 @@ if Code.ensure_loaded?(Decorator.Define) do The default key generator is provided by the cache via the callback `c:Nebulex.Cache.__default_key_generator__/0` and it is applied only - if the option `key:` or `keys:` is not configured. By default it is - `Nebulex.unquote(__MODULE__).SimpleKeyGenerator`. But you can change the default + if the option `key:` or `keys:` is not configured. Defaults to + `Nebulex.Caching.SimpleKeyGenerator`. You can change the default key generator at compile time with the option `:default_key_generator`. For example, one can define a cache with a default key generator as: @@ -60,18 +60,18 @@ if Code.ensure_loaded?(Decorator.Define) do adapter: Nebulex.Adapters.Local, default_key_generator: __MODULE__ - @behaviour Nebulex.unquote(__MODULE__).KeyGenerator + @behaviour Nebulex.Caching.KeyGenerator @impl true def generate(mod, fun, args), do: :erlang.phash2({mod, fun, args}) end - The key generator module must implement the `Nebulex.unquote(__MODULE__).KeyGenerator` + The key generator module must implement the `Nebulex.Caching.KeyGenerator` behaviour. > **IMPORTANT:** There are some caveats to keep in mind when using the key generator, therefore, it is highly recommended to review - `Nebulex.unquote(__MODULE__).KeyGenerator` behaviour documentation before. + `Nebulex.Caching.KeyGenerator` behaviour documentation before. Also, you can provide a different key generator at any time (overriding the default one) when using any caching annotation @@ -235,13 +235,20 @@ if Code.ensure_loaded?(Decorator.Define) do * `:opts` - Defines the cache options that will be passed as argument to the invoked cache function (optional). - * `:match` - Match function `(term -> boolean | {true, term})` (optional). - This function is for matching and decide whether the code-block - evaluation result is cached or not. If `true` the code-block evaluation - result is cached as it is (the default). If `{true, value}` is returned, - then the `value` is what is cached (useful to control what is meant to - be cached). Returning `false` will cause that nothing is stored in the - cache. The default match function looks like this: + * `:match` - Match function `t:match_fun/0`. This function is for matching + and deciding whether the code-block evaluation result (which is received + as an argument) is cached or not. The function should return: + + * `true` - the code-block evaluation result is cached as it is + (the default). + * `{true, value}` - `value` is cached. This is useful to set what + exactly must be cached. + * `{true, value, opts}` - `value` is cached with the options given by + `opts`. This return allows us to set the value to be cached, as well + as the runtime options for storing it (e.g.: the `ttl`). + * `false` - Nothing is cached. + + The default match function looks like this: ```elixir fn @@ -302,7 +309,7 @@ if Code.ensure_loaded?(Decorator.Define) do The possible values for the `:key_generator` are: - * A module implementing the `Nebulex.unquote(__MODULE__).KeyGenerator` behaviour. + * A module implementing the `Nebulex.Caching.KeyGenerator` behaviour. * A MFA tuple `{module, function, args}` for a function to call to generate the key before the cache is invoked. A shorthand value of @@ -409,16 +416,16 @@ if Code.ensure_loaded?(Decorator.Define) do defrecordp(:keyref, :"$nbx_cache_ref", cache: nil, key: nil) @typedoc "Type spec for a key reference" - @type keyref :: record(:keyref, cache: Nebulex.Cache.t(), key: term) + @type keyref :: record(:keyref, cache: Nebulex.Cache.t(), key: any) @typedoc "Type for :on_error option" @type on_error_opt :: :raise | :nothing @typedoc "Match function type" - @type match_fun :: (term -> boolean | {true, term}) + @type match_fun :: (any -> boolean | {true, any} | {true, any, Keyword.t()}) @typedoc "Type spec for the option :references" - @type references :: (term -> term) | nil | term + @type references :: (any -> any) | nil | any ## API @@ -1045,7 +1052,6 @@ if Code.ensure_loaded?(Decorator.Define) do case run_cmd(cache, :get, [key, opts], on_error) do nil -> result = block.() - ref_key = eval_cacheable_ref(references, result) with true <- @@ -1119,6 +1125,11 @@ if Code.ensure_loaded?(Decorator.Define) do true + {true, value, match_opts} -> + :ok = cache_put(cache, key, value, Keyword.merge(opts, match_opts)) + + true + true -> :ok = cache_put(cache, key, result, opts) diff --git a/test/nebulex/caching_test.exs b/test/nebulex/caching_test.exs index 379550eb..07afb467 100644 --- a/test/nebulex/caching_test.exs +++ b/test/nebulex/caching_test.exs @@ -160,6 +160,15 @@ defmodule Nebulex.CachingTest do refute Cache.get({:ok, "hello"}) end + test "with match function and custom opts" do + refute Cache.get(300) + assert get_with_custom_ttl(300) == {:ok, %{ttl: 300}} + assert Cache.get(300) == {:ok, %{ttl: 300}} + + :ok = Process.sleep(400) + refute Cache.get(300) + end + test "with default key" do assert get_with_default_key(123, {:foo, "bar"}) == :ok assert [123, {:foo, "bar"}] |> :erlang.phash2() |> Cache.get() == :ok @@ -931,6 +940,11 @@ defmodule Nebulex.CachingTest do %{id: "referenced_id", name: name} end + @decorate cacheable(cache: Cache, key: ttl, match: &match_fun/1) + def get_with_custom_ttl(ttl) do + {:ok, %{ttl: ttl}} + end + ## Helpers # Custom key-generator function @@ -948,6 +962,7 @@ defmodule Nebulex.CachingTest do ## Private Functions defp match_fun({:ok, "true"}), do: true + defp match_fun({:ok, %{ttl: ttl}} = ok), do: {true, ok, [ttl: ttl]} defp match_fun({:ok, val}), do: {true, val} defp match_fun(_), do: false From 55c4714ea85ffd3740f26ecf7513df8b898d3e81 Mon Sep 17 00:00:00 2001 From: cabol Date: Sat, 13 May 2023 10:55:58 +0200 Subject: [PATCH 4/8] [#178] Rename `Nebulex.Caching.cache_ref/2` to `Nebulex.Caching.keyref/2` --- .formatter.exs | 18 +++++++++++- lib/nebulex/adapters/local/backend.ex | 12 ++------ lib/nebulex/caching.ex | 10 +++---- lib/nebulex/caching/decorators.ex | 29 +++++++++---------- mix.exs | 2 +- mix.lock | 24 +++++++-------- .../adapters/local/generation_test.exs | 4 +++ test/nebulex/adapters/local_shards_test.exs | 2 +- .../adapters/multilevel_exclusive_test.exs | 2 +- .../adapters/multilevel_inclusive_test.exs | 2 +- test/nebulex/caching_test.exs | 10 +++---- 11 files changed, 64 insertions(+), 51 deletions(-) diff --git a/.formatter.exs b/.formatter.exs index f8bb4242..bdf866e8 100644 --- a/.formatter.exs +++ b/.formatter.exs @@ -1,5 +1,21 @@ +locals_without_parens = [ + # Nebulex.Caching + keyref: 1, + keyref: 2, + + # Tests + deftests: 1, + deftests: 2, + setup_with_cache: 1, + setup_with_cache: 2, + setup_with_dynamic_cache: 2, + setup_with_dynamic_cache: 3 +] + [ import_deps: [:stream_data], inputs: ["{mix,.formatter}.exs", "{config,lib,test,benchmarks}/**/*.{ex,exs}"], - line_length: 100 + line_length: 100, + locals_without_parens: locals_without_parens, + export: [locals_without_parens: locals_without_parens] ] diff --git a/lib/nebulex/adapters/local/backend.ex b/lib/nebulex/adapters/local/backend.ex index 0ba56700..abea8f88 100644 --- a/lib/nebulex/adapters/local/backend.ex +++ b/lib/nebulex/adapters/local/backend.ex @@ -56,27 +56,21 @@ defmodule Nebulex.Adapters.Local.Backend do Helper function for returning the child spec for the given backend. """ def child_spec(backend, opts) do - backend - |> get_mod() - |> apply(:child_spec, [opts]) + get_mod(backend).child_spec(opts) end @doc """ Helper function for creating a new table for the given backend. """ def new(backend, meta_tab, tab_opts) do - backend - |> get_mod() - |> apply(:new, [meta_tab, tab_opts]) + get_mod(backend).new(meta_tab, tab_opts) end @doc """ Helper function for deleting a table for the given backend. """ def delete(backend, meta_tab, gen_tab) do - backend - |> get_mod() - |> apply(:delete, [meta_tab, gen_tab]) + get_mod(backend).delete(meta_tab, gen_tab) end defp get_mod(:ets), do: Nebulex.Adapters.Local.Backend.ETS diff --git a/lib/nebulex/caching.ex b/lib/nebulex/caching.ex index 0ab0e388..bd8aa3ca 100644 --- a/lib/nebulex/caching.ex +++ b/lib/nebulex/caching.ex @@ -29,16 +29,16 @@ if Code.ensure_loaded?(Decorator.Define) do alias Nebulex.Caching.Decorators @doc """ - A wrapper macro for `Nebulex.Caching.Decorators.cache_ref/2`. + A wrapper macro for `Nebulex.Caching.Decorators.build_keyref/2`. - This macro is imported automatically with `use Nebulex.Caching` which means - you don't need to do any additional `alias` or `import`. + This macro is imported automatically with `use Nebulex.Caching`, + which means you don't need to do any additional `alias` or `import`. See `cacheable/3` decorator for more information about its usage. """ - defmacro cache_ref(cache \\ nil, key) do + defmacro keyref(cache \\ nil, key) do quote do - Decorators.cache_ref(unquote(cache), unquote(key)) + Decorators.build_keyref(unquote(cache), unquote(key)) end end end diff --git a/lib/nebulex/caching/decorators.ex b/lib/nebulex/caching/decorators.ex index 3528ea7c..5c55716f 100644 --- a/lib/nebulex/caching/decorators.ex +++ b/lib/nebulex/caching/decorators.ex @@ -413,7 +413,7 @@ if Code.ensure_loaded?(Decorator.Define) do ## Types # Key reference spec - defrecordp(:keyref, :"$nbx_cache_ref", cache: nil, key: nil) + defrecordp(:keyref, :"$nbx_cache_keyref", cache: nil, key: nil) @typedoc "Type spec for a key reference" @type keyref :: record(:keyref, cache: Nebulex.Cache.t(), key: any) @@ -452,7 +452,7 @@ if Code.ensure_loaded?(Decorator.Define) do want to reference a key located in an external/different cache than the one defined with the options `:key` or `:key_generator`. In this scenario, you must return a special type `t:keyref/0`, which can be - build with the macro [`cache_ref/2`](`Nebulex.Caching.cache_ref/2`). + build with the macro [`keyref/2`](`Nebulex.Caching.keyref/2`). See the "External referenced keys" section below. * `any` - It could be an explicit term or value, for example, a fixed value or a function argument. @@ -611,7 +611,7 @@ if Code.ensure_loaded?(Decorator.Define) do @decorate cacheable( cache: LocalCache, key: email, - references: &cache_ref(RedisCache, &1.id) + references: &keyref(RedisCache, &1.id) ) def get_user_account_by_email(email) do # your logic ... @@ -620,7 +620,7 @@ if Code.ensure_loaded?(Decorator.Define) do @decorate cacheable( cache: LocalCache, key: token, - references: &cache_ref(RedisCache, &1.id) + references: &keyref(RedisCache, &1.id) ) def get_user_account_by_token(token) do # your logic ... @@ -636,11 +636,10 @@ if Code.ensure_loaded?(Decorator.Define) do `RedisCache` to store the real value in Redis while `get_user_account_by_email/1` and `get_user_account_by_token/1` use `LocalCache` to store the referenced keys. Then, with the option - `references: &cache_ref(RedisCache, &1.id)` we are telling the `cacheable` + `references: &keyref(RedisCache, &1.id)` we are telling the `cacheable` decorator the referenced key given by `&1.id` is located in the cache - `RedisCache`; underneath, the macro - [`cache_ref/2`](`Nebulex.Caching.cache_ref/2`) builds the - special return type for the external cache reference. + `RedisCache`; underneath, the macro [`keyref/2`](`Nebulex.Caching.keyref/2`) + builds the special return type for the external cache reference. """ def cacheable(attrs, block, context) do caching_action(:cacheable, attrs, block, context) @@ -781,20 +780,20 @@ if Code.ensure_loaded?(Decorator.Define) do cache provided via `:key` or `:key_generator` options (internal reference). **NOTE:** In case you need to build a reference, consider using the macro - `Nebulex.Caching.cache_ref/2` instead. + `Nebulex.Caching.keyref/2` instead. See `cacheable/3` decorator for more information about external references. ## Examples - iex> Nebulex.Caching.Decorators.cache_ref("my-key") - {:"$nbx_cache_ref", nil, "my-key"} - iex> Nebulex.Caching.Decorators.cache_ref(MyCache, "my-key") - {:"$nbx_cache_ref", MyCache, "my-key"} + iex> Nebulex.Caching.Decorators.build_keyref("my-key") + {:"$nbx_cache_keyref", nil, "my-key"} + iex> Nebulex.Caching.Decorators.build_keyref(MyCache, "my-key") + {:"$nbx_cache_keyref", MyCache, "my-key"} """ - @spec cache_ref(Nebulex.Cache.t(), term) :: keyref() - def cache_ref(cache \\ nil, key) do + @spec build_keyref(Nebulex.Cache.t(), term) :: keyref() + def build_keyref(cache \\ nil, key) do keyref(cache: cache, key: key) end diff --git a/mix.exs b/mix.exs index 894d84de..dc6f6d98 100644 --- a/mix.exs +++ b/mix.exs @@ -48,7 +48,7 @@ defmodule Nebulex.MixProject do defp deps do [ - {:shards, "~> 1.0", optional: true}, + {:shards, "~> 1.1", optional: true}, {:decorator, "~> 1.4", optional: true}, {:telemetry, "~> 0.4 or ~> 1.0", optional: true}, diff --git a/mix.lock b/mix.lock index 5e4743c6..1f8e278e 100644 --- a/mix.lock +++ b/mix.lock @@ -4,34 +4,34 @@ "benchee_json": {:hex, :benchee_json, "1.0.0", "cc661f4454d5995c08fe10dd1f2f72f229c8f0fb1c96f6b327a8c8fc96a91fe5", [:mix], [{:benchee, ">= 0.99.0 and < 2.0.0", [hex: :benchee, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "da05d813f9123505f870344d68fb7c86a4f0f9074df7d7b7e2bb011a63ec231c"}, "bunt": {:hex, :bunt, "0.2.1", "e2d4792f7bc0ced7583ab54922808919518d0e57ee162901a16a1b6664ef3b14", [:mix], [], "hexpm", "a330bfb4245239787b15005e66ae6845c9cd524a288f0d141c148b02603777a5"}, "certifi": {:hex, :certifi, "2.9.0", "6f2a475689dd47f19fb74334859d460a2dc4e3252a3324bd2111b8f0429e7e21", [:rebar3], [], "hexpm", "266da46bdb06d6c6d35fde799bcb28d36d985d424ad7c08b5bb48f5b5cdd4641"}, - "credo": {:hex, :credo, "1.6.7", "323f5734350fd23a456f2688b9430e7d517afb313fbd38671b8a4449798a7854", [:mix], [{:bunt, "~> 0.2.1", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "41e110bfb007f7eda7f897c10bf019ceab9a0b269ce79f015d54b0dcf4fc7dd3"}, + "credo": {:hex, :credo, "1.7.0", "6119bee47272e85995598ee04f2ebbed3e947678dee048d10b5feca139435f75", [:mix], [{:bunt, "~> 0.2.1", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "6839fcf63d1f0d1c0f450abc8564a57c43d644077ab96f2934563e68b8a769d7"}, "decorator": {:hex, :decorator, "1.4.0", "a57ac32c823ea7e4e67f5af56412d12b33274661bb7640ec7fc882f8d23ac419", [:mix], [], "hexpm", "0a07cedd9083da875c7418dea95b78361197cf2bf3211d743f6f7ce39656597f"}, "deep_merge": {:hex, :deep_merge, "1.0.0", "b4aa1a0d1acac393bdf38b2291af38cb1d4a52806cf7a4906f718e1feb5ee961", [:mix], [], "hexpm", "ce708e5f094b9cd4e8f2be4f00d2f4250c4095be93f8cd6d018c753894885430"}, - "dialyxir": {:hex, :dialyxir, "1.2.0", "58344b3e87c2e7095304c81a9ae65cb68b613e28340690dfe1a5597fd08dec37", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "61072136427a851674cab81762be4dbeae7679f85b1272b6d25c3a839aff8463"}, - "earmark_parser": {:hex, :earmark_parser, "1.4.29", "149d50dcb3a93d9f3d6f3ecf18c918fb5a2d3c001b5d3305c926cddfbd33355b", [:mix], [], "hexpm", "4902af1b3eb139016aed210888748db8070b8125c2342ce3dcae4f38dcc63503"}, + "dialyxir": {:hex, :dialyxir, "1.3.0", "fd1672f0922b7648ff9ce7b1b26fcf0ef56dda964a459892ad15f6b4410b5284", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "00b2a4bcd6aa8db9dcb0b38c1225b7277dca9bc370b6438715667071a304696f"}, + "earmark_parser": {:hex, :earmark_parser, "1.4.32", "fa739a0ecfa34493de19426681b23f6814573faee95dfd4b4aafe15a7b5b32c6", [:mix], [], "hexpm", "b8b0dd77d60373e77a3d7e8afa598f325e49e8663a51bcc2b88ef41838cca755"}, "erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"}, "ex2ms": {:hex, :ex2ms, "1.6.1", "66d472eb14da43087c156e0396bac3cc7176b4f24590a251db53f84e9a0f5f72", [:mix], [], "hexpm", "a7192899d84af03823a8ec2f306fa858cbcce2c2e7fd0f1c49e05168fb9c740e"}, - "ex_doc": {:hex, :ex_doc, "0.29.0", "4a1cb903ce746aceef9c1f9ae8a6c12b742a5461e6959b9d3b24d813ffbea146", [:mix], [{:earmark_parser, "~> 1.4.19", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "f096adb8bbca677d35d278223361c7792d496b3fc0d0224c9d4bc2f651af5db1"}, - "excoveralls": {:hex, :excoveralls, "0.15.0", "ac941bf85f9f201a9626cc42b2232b251ad8738da993cf406a4290cacf562ea4", [:mix], [{:hackney, "~> 1.16", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "9631912006b27eca30a2f3c93562bc7ae15980afb014ceb8147dc5cdd8f376f1"}, + "ex_doc": {:hex, :ex_doc, "0.29.4", "6257ecbb20c7396b1fe5accd55b7b0d23f44b6aa18017b415cb4c2b91d997729", [:mix], [{:earmark_parser, "~> 1.4.31", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "2c6699a737ae46cb61e4ed012af931b57b699643b24dabe2400a8168414bc4f5"}, + "excoveralls": {:hex, :excoveralls, "0.16.1", "0bd42ed05c7d2f4d180331a20113ec537be509da31fed5c8f7047ce59ee5a7c5", [:mix], [{:hackney, "~> 1.16", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "dae763468e2008cf7075a64cb1249c97cb4bc71e236c5c2b5e5cdf1cfa2bf138"}, "file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"}, - "hackney": {:hex, :hackney, "1.18.1", "f48bf88f521f2a229fc7bae88cf4f85adc9cd9bcf23b5dc8eb6a1788c662c4f6", [:rebar3], [{:certifi, "~>2.9.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~>6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~>1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~>1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "a4ecdaff44297e9b5894ae499e9a070ea1888c84afdd1fd9b7b2bc384950128e"}, - "idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"}, + "hackney": {:hex, :hackney, "1.18.1", "f48bf88f521f2a229fc7bae88cf4f85adc9cd9bcf23b5dc8eb6a1788c662c4f6", [:rebar3], [{:certifi, "~> 2.9.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~> 6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~> 1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~> 1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~> 1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "a4ecdaff44297e9b5894ae499e9a070ea1888c84afdd1fd9b7b2bc384950128e"}, + "idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"}, "inch_ex": {:hex, :inch_ex, "2.0.0", "24268a9284a1751f2ceda569cd978e1fa394c977c45c331bb52a405de544f4de", [:mix], [{:bunt, "~> 0.2", [hex: :bunt, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "96d0ec5ecac8cf63142d02f16b7ab7152cf0f0f1a185a80161b758383c9399a8"}, "jason": {:hex, :jason, "1.4.0", "e855647bc964a44e2f67df589ccf49105ae039d4179db7f6271dfd3843dc27e6", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "79a3791085b2a0f743ca04cec0f7be26443738779d09302e01318f97bdb82121"}, "makeup": {:hex, :makeup, "1.1.0", "6b67c8bc2882a6b6a445859952a602afc1a41c2e08379ca057c0f525366fc3ca", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "0a45ed501f4a8897f580eabf99a2e5234ea3e75a4373c8a52824f6e873be57a6"}, - "makeup_elixir": {:hex, :makeup_elixir, "0.16.0", "f8c570a0d33f8039513fbccaf7108c5d750f47d8defd44088371191b76492b0b", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "28b2cbdc13960a46ae9a8858c4bebdec3c9a6d7b4b9e7f4ed1502f8159f338e7"}, + "makeup_elixir": {:hex, :makeup_elixir, "0.16.1", "cc9e3ca312f1cfeccc572b37a09980287e243648108384b97ff2b76e505c3555", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "e127a341ad1b209bd80f7bd1620a15693a9908ed780c3b763bccf7d200c767c6"}, "makeup_erlang": {:hex, :makeup_erlang, "0.1.1", "3fcb7f09eb9d98dc4d208f49cc955a34218fc41ff6b84df7c75b3e6e533cc65f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "174d0809e98a4ef0b3309256cbf97101c6ec01c4ab0b23e926a9e17df2077cbb"}, "meck": {:hex, :meck, "0.9.2", "85ccbab053f1db86c7ca240e9fc718170ee5bda03810a6292b5306bf31bae5f5", [:rebar3], [], "hexpm", "81344f561357dc40a8344afa53767c32669153355b626ea9fcbc8da6b3045826"}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"}, "mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"}, "mock": {:hex, :mock, "0.3.7", "75b3bbf1466d7e486ea2052a73c6e062c6256fb429d6797999ab02fa32f29e03", [:mix], [{:meck, "~> 0.9.2", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm", "4da49a4609e41fd99b7836945c26f373623ea968cfb6282742bcb94440cf7e5c"}, - "nimble_parsec": {:hex, :nimble_parsec, "1.2.3", "244836e6e3f1200c7f30cb56733fd808744eca61fd182f731eac4af635cc6d0b", [:mix], [], "hexpm", "c8d789e39b9131acf7b99291e93dae60ab48ef14a7ee9d58c6964f59efb570b0"}, + "nimble_parsec": {:hex, :nimble_parsec, "1.3.1", "2c54013ecf170e249e9291ed0a62e5832f70a476c61da16f6aac6dca0189f2af", [:mix], [], "hexpm", "2682e3c0b2eb58d90c6375fc0cc30bc7be06f365bf72608804fb9cffa5e1b167"}, "parse_trans": {:hex, :parse_trans, "3.3.1", "16328ab840cc09919bd10dab29e431da3af9e9e7e7e6f0089dd5a2d2820011d8", [:rebar3], [], "hexpm", "07cd9577885f56362d414e8c4c4e6bdf10d43a8767abb92d24cbe8b24c54888b"}, - "shards": {:hex, :shards, "1.0.1", "1bdbbf047db27f3c3eb800a829d4a47062c84d5543cbfebcfc4c14d038bf9220", [:make, :rebar3], [], "hexpm", "2c57788afbf053c4024366772892beee89b8b72e884e764fb0a075dfa7442041"}, - "sobelow": {:hex, :sobelow, "0.11.1", "23438964486f8112b41e743bbfd402da3e5b296fdc9eacab29914b79c48916dd", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "9897363a7eff96f4809304a90aad819e2ad5e5d24db547af502885146746a53c"}, + "shards": {:hex, :shards, "1.1.0", "ed3032e63ae99f0eaa6d012b8b9f9cead48b9a810b3f91aeac266cfc4118eff6", [:make, :rebar3], [], "hexpm", "1d188e565a54a458a7a601c2fd1e74f5cfeba755c5a534239266d28b7ff124c7"}, + "sobelow": {:hex, :sobelow, "0.12.2", "45f4d500e09f95fdb5a7b94c2838d6b26625828751d9f1127174055a78542cf5", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "2f0b617dce551db651145662b84c8da4f158e7abe049a76daaaae2282df01c5d"}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.6", "cf344f5692c82d2cd7554f5ec8fd961548d4fd09e7d22f5b62482e5aeaebd4b0", [:make, :mix, :rebar3], [], "hexpm", "bdb0d2471f453c88ff3908e7686f86f9be327d065cc1ec16fa4540197ea04680"}, "statistex": {:hex, :statistex, "1.0.0", "f3dc93f3c0c6c92e5f291704cf62b99b553253d7969e9a5fa713e5481cd858a5", [:mix], [], "hexpm", "ff9d8bee7035028ab4742ff52fc80a2aa35cece833cf5319009b52f1b5a86c27"}, "stream_data": {:hex, :stream_data, "0.5.0", "b27641e58941685c75b353577dc602c9d2c12292dd84babf506c2033cd97893e", [:mix], [], "hexpm", "012bd2eec069ada4db3411f9115ccafa38540a3c78c4c0349f151fc761b9e271"}, - "telemetry": {:hex, :telemetry, "1.1.0", "a589817034a27eab11144ad24d5c0f9fab1f58173274b1e9bae7074af9cbee51", [:rebar3], [], "hexpm", "b727b2a1f75614774cff2d7565b64d0dfa5bd52ba517f16543e6fc7efcc0df48"}, + "telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"}, "unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"}, } diff --git a/test/nebulex/adapters/local/generation_test.exs b/test/nebulex/adapters/local/generation_test.exs index 611563f1..8f2f42c7 100644 --- a/test/nebulex/adapters/local/generation_test.exs +++ b/test/nebulex/adapters/local/generation_test.exs @@ -236,6 +236,7 @@ defmodule Nebulex.Adapters.Local.GenerationTest do end for task <- tasks, do: Task.shutdown(task) + :ok = LocalWithSizeLimit.stop() end end @@ -324,6 +325,9 @@ defmodule Nebulex.Adapters.Local.GenerationTest do # assert not crashed assert LocalWithSizeLimit.count_all() == 4 + + # Stop the cache + :ok = LocalWithSizeLimit.stop() end end diff --git a/test/nebulex/adapters/local_shards_test.exs b/test/nebulex/adapters/local_shards_test.exs index 7e138975..53c7366a 100644 --- a/test/nebulex/adapters/local_shards_test.exs +++ b/test/nebulex/adapters/local_shards_test.exs @@ -28,7 +28,7 @@ defmodule Nebulex.Adapters.LocalWithShardsTest do {:ok, _pid} = CustomPartitions.start_link() assert CustomPartitions.newer_generation() - |> :shards.meta() + |> :shards.table_meta() |> :shards_meta.partitions() == 2 :ok = CustomPartitions.stop() diff --git a/test/nebulex/adapters/multilevel_exclusive_test.exs b/test/nebulex/adapters/multilevel_exclusive_test.exs index 16e4c0e2..287242fb 100644 --- a/test/nebulex/adapters/multilevel_exclusive_test.exs +++ b/test/nebulex/adapters/multilevel_exclusive_test.exs @@ -39,7 +39,7 @@ defmodule Nebulex.Adapters.MultilevelExclusiveTest do test "returns partitions for L1 with shards backend", %{name: name} do assert :"#{name}_l1" |> Generation.newer() - |> :shards.meta() + |> :shards.table_meta() |> :shards_meta.partitions() == 2 end diff --git a/test/nebulex/adapters/multilevel_inclusive_test.exs b/test/nebulex/adapters/multilevel_inclusive_test.exs index 97fad3bf..2647fb91 100644 --- a/test/nebulex/adapters/multilevel_inclusive_test.exs +++ b/test/nebulex/adapters/multilevel_inclusive_test.exs @@ -39,7 +39,7 @@ defmodule Nebulex.Adapters.MultilevelInclusiveTest do test "returns partitions for L1 with shards backend", %{name: name} do assert :"#{name}_l1" |> Generation.newer() - |> :shards.meta() + |> :shards.table_meta() |> :shards_meta.partitions() == 2 end diff --git a/test/nebulex/caching_test.exs b/test/nebulex/caching_test.exs index 07afb467..45c11bcf 100644 --- a/test/nebulex/caching_test.exs +++ b/test/nebulex/caching_test.exs @@ -219,7 +219,7 @@ defmodule Nebulex.CachingTest do test "with referenced key" do # Expected values - referenced_key = cache_ref("referenced_id") + referenced_key = keyref "referenced_id" result = %{id: "referenced_id", name: "referenced_name"} # Nothing is cached yet @@ -268,7 +268,7 @@ defmodule Nebulex.CachingTest do test "with referenced key from args" do # Expected values - referenced_key = cache_ref("id") + referenced_key = keyref "id" result = %{attrs: %{id: "id"}, name: "name"} # Nothing is cached yet @@ -291,7 +291,7 @@ defmodule Nebulex.CachingTest do test "returns fixed referenced" do # Expected values - referenced_key = cache_ref("fixed_id") + referenced_key = keyref "fixed_id" result = %{id: "fixed_id", name: "name"} # Nothing is cached yet @@ -314,7 +314,7 @@ defmodule Nebulex.CachingTest do test "returns referenced key by calling referenced cache" do # Expected values - referenced_key = cache_ref(YetAnotherCache, "referenced_id") + referenced_key = keyref YetAnotherCache, "referenced_id" result = %{id: "referenced_id", name: "referenced_name"} # Nothing is cached yet @@ -935,7 +935,7 @@ defmodule Nebulex.CachingTest do %{id: "fixed_id", name: name} end - @decorate cacheable(cache: Cache, key: name, references: &cache_ref(YetAnotherCache, &1.id)) + @decorate cacheable(cache: Cache, key: name, references: &keyref(YetAnotherCache, &1.id)) def get_with_ref_key_with_cache(name) do %{id: "referenced_id", name: name} end From 0f0ddad4db96697c608390c6630c86fa967716ac Mon Sep 17 00:00:00 2001 From: cabol Date: Sat, 13 May 2023 15:49:59 +0200 Subject: [PATCH 5/8] Release v2.5.0 --- CHANGELOG.md | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++ mix.exs | 2 +- 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 76f6defc..6f85d813 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,75 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [v2.5.0](https://github.com/cabol/nebulex/tree/v2.5.0) (2023-05-13) + +[Full Changelog](https://github.com/cabol/nebulex/compare/v2.4.2...v2.5.0) + +**Implemented enhancements:** + +- Support for functions that can set TTL in Decorator similar to Match + [#200](https://github.com/cabol/nebulex/issues/200) +- Improve default match function in decorators to cover more scenarios + [#177](https://github.com/cabol/nebulex/issues/177) +- Adapters implementation guide + [#96](https://github.com/cabol/nebulex/issues/96) + +**Fixed bugs:** + +- Issue with keys set to `false` when calling `get_all` in local adapter + [#187](https://github.com/cabol/nebulex/issues/187) + +**Closed issues:** + +- Is there any way to get the size of the cache? + [#203](https://github.com/cabol/nebulex/issues/203) +- Where to use load/2, dump/2 + [#201](https://github.com/cabol/nebulex/issues/201) +- `Nebulex.Cache` callbacks mention "Shared Options" section that do not exist + [#199](https://github.com/cabol/nebulex/issues/199) +- Errors when storing nil values + [#195](https://github.com/cabol/nebulex/issues/195) +- Unregistering cache in registry happens after cache shuts down + [#194](https://github.com/cabol/nebulex/issues/194) +- Is there a good way to evict multiple caches at once by some conditions? + [#192](https://github.com/cabol/nebulex/issues/192) +- Unable to use module attributes when specifying a MFA cache within the decorator + [#191](https://github.com/cabol/nebulex/issues/191) +- Nebulex crash when `gc_interval` is not set + [#182](https://github.com/cabol/nebulex/issues/182) +- `ArgumentError` * 1st argument: the table identifier does not refer to an existing ETS table + [#181](https://github.com/cabol/nebulex/issues/181) +- Feedback for `NebulexLocalDistributedAdapter` + [#180](https://github.com/cabol/nebulex/issues/180) +- Multilevel invalidation + [#179](https://github.com/cabol/nebulex/issues/179) +- External cache-key references on `cacheable` decorator + [#178](https://github.com/cabol/nebulex/issues/178) +- [multiple clause functions] Cannot use ignored variables in decorator keys + [#173](https://github.com/cabol/nebulex/issues/173) +- Ability for referencing a key in the `cacheable` decorator via `:references` option + [#169](https://github.com/cabol/nebulex/issues/169) +- Multi level caching suggestion? + [#168](https://github.com/cabol/nebulex/issues/168) + +**Merged pull requests:** + +- Fix `Local.get_all` with false values + [#186](https://github.com/cabol/nebulex/pull/186) + ([renatoaguiar](https://github.com/renatoaguiar)) +- Add NebulexLocalMultilevelAdapter to the list + [#185](https://github.com/cabol/nebulex/pull/185) + ([martosaur](https://github.com/martosaur)) +- Fix the crash when `gc_interval` is not set + [#183](https://github.com/cabol/nebulex/pull/183) + ([dongfuye](https://github.com/dongfuye)) +- [#169] Reference a key in `cacheable` decorator via `:references` option + [#176](https://github.com/cabol/nebulex/pull/176) + ([cabol](https://github.com/cabol)) +- Creating New Adapter guide + [#175](https://github.com/cabol/nebulex/pull/175) + ([martosaur](https://github.com/martosaur)) + ## [v2.4.2](https://github.com/cabol/nebulex/tree/v2.4.2) (2022-11-04) [Full Changelog](https://github.com/cabol/nebulex/compare/v2.4.1...v2.4.2) diff --git a/mix.exs b/mix.exs index dc6f6d98..538c8f7d 100644 --- a/mix.exs +++ b/mix.exs @@ -2,7 +2,7 @@ defmodule Nebulex.MixProject do use Mix.Project @source_url "https://github.com/cabol/nebulex" - @version "2.4.2" + @version "2.5.0" def project do [ From 909b9675600feba86a4af17d1e32a7af5bb99c12 Mon Sep 17 00:00:00 2001 From: Hissssst <37012324+hissssst@users.noreply.github.com> Date: Tue, 16 May 2023 13:34:22 +0000 Subject: [PATCH 6/8] Example fixed (#204) --- lib/mix/tasks/nbx.gen.cache.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/mix/tasks/nbx.gen.cache.ex b/lib/mix/tasks/nbx.gen.cache.ex index 373a4bfe..54e31c1f 100644 --- a/lib/mix/tasks/nbx.gen.cache.ex +++ b/lib/mix/tasks/nbx.gen.cache.ex @@ -12,7 +12,7 @@ defmodule Mix.Tasks.Nbx.Gen.Cache do Besides, you can also specify the adapter you want to use, like so: - mix nbx.gen.cache -c MyApp.PartitionedCache -a Nebulex.Adapters.Local + mix nbx.gen.cache -c MyApp.LocalCache -a Nebulex.Adapters.Local mix nbx.gen.cache -c MyApp.PartitionedCache -a Nebulex.Adapters.Partitioned mix nbx.gen.cache -c MyApp.ReplicatedCache -a Nebulex.Adapters.Replicated mix nbx.gen.cache -c MyApp.MultilevelCache -a Nebulex.Adapters.Multilevel From c6d8d18bddad4515e6fc42c483fdab7188c82623 Mon Sep 17 00:00:00 2001 From: 1100x1100 <134586935+1100x1100@users.noreply.github.com> Date: Thu, 25 May 2023 12:19:14 +0200 Subject: [PATCH 7/8] Fix `nil` check in `Nebulex.Adapters.Multilevel.get/3` (#205) Co-authored-by: Niels Henrik Egsgaard --- lib/nebulex/adapters/multilevel.ex | 8 +++++--- test/nebulex/adapters/multilevel_inclusive_test.exs | 8 ++++++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/lib/nebulex/adapters/multilevel.ex b/lib/nebulex/adapters/multilevel.ex index e604123a..8fce5453 100644 --- a/lib/nebulex/adapters/multilevel.ex +++ b/lib/nebulex/adapters/multilevel.ex @@ -313,10 +313,12 @@ defmodule Nebulex.Adapters.Multilevel do @impl true defspan get(adapter_meta, key, opts) do fun = fn level, {default, prev} -> - if value = with_dynamic_cache(level, :get, [key, opts]) do - {:halt, {value, [level | prev]}} - else + value = with_dynamic_cache(level, :get, [key, opts]) + + if is_nil(value) do {:cont, {default, [level | prev]}} + else + {:halt, {value, [level | prev]}} end end diff --git a/test/nebulex/adapters/multilevel_inclusive_test.exs b/test/nebulex/adapters/multilevel_inclusive_test.exs index 2647fb91..810455d1 100644 --- a/test/nebulex/adapters/multilevel_inclusive_test.exs +++ b/test/nebulex/adapters/multilevel_inclusive_test.exs @@ -68,6 +68,14 @@ defmodule Nebulex.Adapters.MultilevelInclusiveTest do assert Multilevel.get(3, level: 2) == 3 end + test "get boolean" do + :ok = Multilevel.put(1, true, level: 1) + :ok = Multilevel.put(2, false, level: 1) + + assert Multilevel.get(1) == true + assert Multilevel.get(2) == false + end + test "fetched value is replicated with TTL on previous levels" do assert Multilevel.put(:a, 1, ttl: 1000) == :ok assert Multilevel.ttl(:a) > 0 From 974f54e53ac91bf4906c35fcbd8b67166a86895b Mon Sep 17 00:00:00 2001 From: cabol Date: Sat, 27 May 2023 09:05:21 +0200 Subject: [PATCH 8/8] Release v2.5.1 --- CHANGELOG.md | 13 +++++++++++++ README.md | 4 ++-- guides/creating-new-adapter.md | 6 +++--- guides/getting-started.md | 2 +- mix.exs | 2 +- 5 files changed, 20 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f85d813..c2647774 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,19 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [v2.5.1](https://github.com/cabol/nebulex/tree/v2.5.1) (2023-05-27) + +[Full Changelog](https://github.com/cabol/nebulex/compare/v2.5.0...v2.5.1) + +**Merged pull requests:** + +- Fix `nil` check in `Nebulex.Adapters.Multilevel.get/3` + [#205](https://github.com/cabol/nebulex/pull/205) + ([1100x1100](https://github.com/1100x1100)) +- `mix nbx.gen.cache` example fixed + [#204](https://github.com/cabol/nebulex/pull/204) + ([hissssst](https://github.com/hissssst)) + ## [v2.5.0](https://github.com/cabol/nebulex/tree/v2.5.0) (2023-05-13) [Full Changelog](https://github.com/cabol/nebulex/compare/v2.4.2...v2.5.0) diff --git a/README.md b/README.md index c660d543..e95ab1c1 100644 --- a/README.md +++ b/README.md @@ -68,8 +68,8 @@ For example, if you want to use a built-in cache, add to your `mix.exs` file: ```elixir def deps do [ - {:nebulex, "~> 2.4"}, - {:shards, "~> 1.0"}, #=> When using :shards as backend + {:nebulex, "~> 2.5"}, + {:shards, "~> 1.1"}, #=> When using :shards as backend {:decorator, "~> 1.4"}, #=> When using Caching Annotations {:telemetry, "~> 1.0"} #=> When using the Telemetry events (Nebulex stats) ] diff --git a/guides/creating-new-adapter.md b/guides/creating-new-adapter.md index 4b4d8ffb..64b02e2d 100644 --- a/guides/creating-new-adapter.md +++ b/guides/creating-new-adapter.md @@ -23,7 +23,7 @@ Now let's modify `mix.exs` so that we could fetch Nebulex repository. defmodule NebulexMemoryAdapter.MixProject do use Mix.Project - @nbx_vsn "2.4.2" + @nbx_vsn "2.5.0" @version "0.1.0" def project do @@ -231,10 +231,10 @@ mix test 54) test put_all/2 puts the given entries using different data types at once (NebulexMemoryAdapterTest) test/nebulex_memory_adapter_test.exs:128 ** (UndefinedFunctionError) function NebulexMemoryAdapter.TestCache.delete_all/0 is undefined or private. Did you mean: - + * delete/1 * delete/2 - + stacktrace: (nebulex_memory_adapter 0.1.0) NebulexMemoryAdapter.TestCache.delete_all() test/nebulex_memory_adapter_test.exs:9: NebulexMemoryAdapterTest.__ex_unit_setup_0/1 diff --git a/guides/getting-started.md b/guides/getting-started.md index b3e3455c..0f4f47c1 100644 --- a/guides/getting-started.md +++ b/guides/getting-started.md @@ -29,7 +29,7 @@ changing the `deps` definition in that file to this: ```elixir defp deps do [ - {:nebulex, "~> 2.4"}, + {:nebulex, "~> 2.5"}, {:shards, "~> 1.0"}, #=> When using :shards as backend {:decorator, "~> 1.4"}, #=> When using Caching Annotations {:telemetry, "~> 1.0"} #=> When using the Telemetry events (Nebulex stats) diff --git a/mix.exs b/mix.exs index 538c8f7d..97aebe3c 100644 --- a/mix.exs +++ b/mix.exs @@ -2,7 +2,7 @@ defmodule Nebulex.MixProject do use Mix.Project @source_url "https://github.com/cabol/nebulex" - @version "2.5.0" + @version "2.5.1" def project do [