Skip to content

Commit

Permalink
[#189] All commands optionally support a dynamic cache as the first a…
Browse files Browse the repository at this point in the history
…rgument
  • Loading branch information
cabol committed Apr 1, 2023
1 parent 0fb0452 commit 10a0380
Show file tree
Hide file tree
Showing 26 changed files with 1,005 additions and 483 deletions.
6 changes: 3 additions & 3 deletions .formatter.exs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
locals_without_parens = [
# Nebulex.Helpers
# Nebulex.Utils
unwrap_or_raise: 1,
wrap_ok: 1,
wrap_error: 1,
wrap_error: 2,

# Nebulex.Cache
dynamic_cache: 2,
# Nebulex.Cache.Utils
defcacheapi: 2,

# Nebulex.Caching
cache_ref: 1,
Expand Down
4 changes: 2 additions & 2 deletions guides/creating-new-adapter.md
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ defmodule NebulexMemoryAdapter do
@behaviour Nebulex.Adapter
@behaviour Nebulex.Adapter.Queryable

import Nebulex.Helpers
import Nebulex.Utils

@impl Nebulex.Adapter
defmacro __before_compile__(_env), do: :ok
Expand Down Expand Up @@ -308,7 +308,7 @@ defmodule NebulexMemoryAdapter do
@behaviour Nebulex.Adapter.KV
@behaviour Nebulex.Adapter.Queryable

import Nebulex.Helpers
import Nebulex.Utils

@impl Nebulex.Adapter
defmacro __before_compile__(_env), do: :ok
Expand Down
24 changes: 12 additions & 12 deletions lib/nebulex/adapter/kv.ex
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ defmodule Nebulex.Adapter.KV do
specified `keys`. For every key that does not hold a value or does not exist,
it is ignored and not added into the returned map.
Returns `{:error, reason}` if an error occurs while executing the command.
Returns `{:error, Nebulex.Error.t()}` if an error occurs.
See `c:Nebulex.Cache.get_all/2`.
"""
Expand All @@ -64,7 +64,7 @@ defmodule Nebulex.Adapter.KV do
Returns `{:ok, true}` if the `value` with key `key` is successfully inserted,
otherwise, `{:ok, false}` is returned.
Returns `{:error, reason}` if an error occurs.
Returns `{:error, Nebulex.Error.t()}` if an error occurs.
## OnWrite
Expand Down Expand Up @@ -97,7 +97,7 @@ defmodule Nebulex.Adapter.KV do
Returns `{:ok, true}` if all the keys were inserted. If no key was inserted
(at least one key already existed), `{:ok, false}` is returned.
Returns `{:error, reason}` if an error occurs.
Returns `{:error, Nebulex.Error.t()}` if an error occurs.
## OnWrite
Expand All @@ -123,7 +123,7 @@ defmodule Nebulex.Adapter.KV do
@doc """
Deletes a single entry from cache.
Returns `{:error, reason}` if an error occurs.
Returns `{:error, Nebulex.Error.t()}` if an error occurs.
See `c:Nebulex.Cache.delete/2`.
"""
Expand All @@ -138,8 +138,8 @@ defmodule Nebulex.Adapter.KV do
If `key` is not present in the cache, `{:error, Nebulex.KeyError.t()}`
is returned.
Returns `{:error, Nebulex.Error.t()}` if any other error occurs while
executing the command.
Returns `{:error, Nebulex.Error.t()}` if any other error occurs executing
the command.
See `c:Nebulex.Cache.take/2`.
"""
Expand All @@ -153,7 +153,7 @@ defmodule Nebulex.Adapter.KV do
If `amount` < 0, the counter is decremented by the given `amount`.
If `amount` == 0, the counter is not updated.
Returns `{:error, reason}` if an error occurs.
Returns `{:error, Nebulex.Error.t()}` if an error occurs.
See `c:Nebulex.Cache.incr/3`.
See `c:Nebulex.Cache.decr/3`.
Expand All @@ -168,7 +168,7 @@ defmodule Nebulex.Adapter.KV do
More formally, returns `{:ok, true}` if the cache contains the given `key`.
If the cache doesn't contain `key`, `{:ok, :false}` is returned.
Returns `{:error, reason}` if an error occurs.
Returns `{:error, Nebulex.Error.t()}` if an error occurs.
See `c:Nebulex.Cache.has_key?/2`.
"""
Expand All @@ -183,8 +183,8 @@ defmodule Nebulex.Adapter.KV do
If `key` is not present in the cache, `{:error, Nebulex.KeyError.t()}`
is returned.
Returns `{:error, Nebulex.Error.t()}` if any other error occurs while
executing the command.
Returns `{:error, Nebulex.Error.t()}` if any other error occurs executing
the command.
See `c:Nebulex.Cache.ttl/2`.
"""
Expand All @@ -195,7 +195,7 @@ defmodule Nebulex.Adapter.KV do
Returns `{:ok, true}` if the given `key` exists and the new `ttl` was
successfully updated, otherwise, `{:ok, false}` is returned.
Returns `{:error, reason}` if an error occurs.
Returns `{:error, Nebulex.Error.t()}` if an error occurs.
See `c:Nebulex.Cache.expire/3`.
"""
Expand All @@ -205,7 +205,7 @@ defmodule Nebulex.Adapter.KV do
Returns `{:ok, true}` if the given `key` exists and the last access time was
successfully updated, otherwise, `{:ok, false}` is returned.
Returns `{:error, reason}` if an error occurs.
Returns `{:error, Nebulex.Error.t()}` if an error occurs.
See `c:Nebulex.Cache.touch/2`.
"""
Expand Down
8 changes: 5 additions & 3 deletions lib/nebulex/adapter/persistence.ex
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ defmodule Nebulex.Adapter.Persistence do
@doc """
Dumps a cache to the given file `path`.
Returns `:ok` if successful, or `{:error, reason}` if an error occurs.
Returns `:ok` if successful, or `{:error, Nebulex.Error.t()}`
if an error occurs.
See `c:Nebulex.Cache.dump/2`.
"""
Expand All @@ -37,7 +38,8 @@ defmodule Nebulex.Adapter.Persistence do
@doc """
Loads a dumped cache from the given `path`.
Returns `:ok` if successful, or `{:error, reason}` if an error occurs.
Returns `:ok` if successful, or `{:error, Nebulex.Error.t()}`
if an error occurs.
See `c:Nebulex.Cache.load/2`.
"""
Expand All @@ -51,7 +53,7 @@ defmodule Nebulex.Adapter.Persistence do
quote do
@behaviour Nebulex.Adapter.Persistence

import Nebulex.Helpers
import Nebulex.Utils, only: [wrap_error: 2]

@impl true
def dump(%{cache: cache}, path, opts) do
Expand Down
11 changes: 5 additions & 6 deletions lib/nebulex/adapter/queryable.ex
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ defmodule Nebulex.Adapter.Queryable do
This callback returns:
* `{:ok, query_result}` - the query is valid, then it is executed
and the result returned.
* `{:ok, query_result}` - The query was successfully executed,
the matched entries are returned.
* `{:error, reason}` - an error occurred while executing the command.
* `{:error, Nebulex.Error.t()}` - An error occurred executing the command.
## Operations
Expand All @@ -62,10 +62,9 @@ defmodule Nebulex.Adapter.Queryable do
This callback returns:
* `{:ok, stream}` - the query is valid, then the stream is built
and returned.
* `{:ok, stream}` - The query is valid, then the stream is returned.
* `{:error, reason}` - an error occurred while executing the command.
* `{:error, Nebulex.Error.t()}` - An error occurred executing the command.
See `c:Nebulex.Cache.stream/2`.
"""
Expand Down
20 changes: 9 additions & 11 deletions lib/nebulex/adapter/stats.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,22 @@ defmodule Nebulex.Adapter.Stats do
using [Erlang counters][https://erlang.org/doc/man/counters.html], with all
callbacks overridable.
See `Nebulex.Adapters.Local` for more information about how this can be used
from the adapter, and also [Nebulex Telemetry Guide][telemetry_guide] to learn
how to use the Cache with Telemetry.
See `Nebulex.Adapters.Local` adapter for more information about how to use
this implementation. Besides, see also the [Nebulex Telemetry][nbx_telemetry]
guide.
[telemetry_guide]: http://hexdocs.pm/nebulex/telemetry.html
[nbx_telemetry]: http://hexdocs.pm/nebulex/telemetry.html
"""

@doc """
Returns current stats values.
This function returns:
* `{:ok, Nebulex.Stats.t()}` - stats are enabled and available
for the cache.
* `{:ok, Nebulex.Stats.t()}` - If stats are enabled and supported by the
cache.
* `{:ok, nil}` - the stats are disabled for the cache.
* `{:error, reason}` - an error occurred while executing the command.
* `{:error, Nebulex.Error.t()}` - An error occurred executing the command.
The adapter may also include additional custom measurements,
as well as metadata.
Expand All @@ -40,7 +38,7 @@ defmodule Nebulex.Adapter.Stats do
@behaviour Nebulex.Adapter.Stats

import Nebulex.Adapter.Stats, only: [defspan: 2, defspan: 3]
import Nebulex.Helpers
import Nebulex.Utils, only: [wrap_error: 2]

@impl true
def stats(adapter_meta, _opts) do
Expand Down Expand Up @@ -93,7 +91,7 @@ defmodule Nebulex.Adapter.Stats do
@spec init(keyword) :: :counters.counters_ref() | nil
def init(opts) do
case Keyword.get(opts, :stats, false) do
true -> :counters.new(6, [:write_concurrency])
true -> :counters.new(5, [:write_concurrency])
false -> nil
end
end
Expand Down
53 changes: 27 additions & 26 deletions lib/nebulex/adapter/transaction.ex
Original file line number Diff line number Diff line change
Expand Up @@ -35,45 +35,46 @@ defmodule Nebulex.Adapter.Transaction do
Locking only the involved key (recommended):
MyCache.transaction [keys: [:counter]], fn ->
counter = MyCache.get(:counter)
MyCache.set(:counter, counter + 1)
end
MyCache.transaction [keys: [:alice, :bob]], fn ->
alice = MyCache.get(:alice)
bob = MyCache.get(:bob)
MyCache.set(:alice, %{alice | balance: alice.balance + 100})
MyCache.set(:bob, %{bob | balance: bob.balance + 100})
end
MyCache.transaction(
fn ->
counter = MyCache.get(:counter)
MyCache.set(:counter, counter + 1)
end,
[keys: [:counter]]
)
MyCache.transaction(
fn ->
alice = MyCache.get(:alice)
bob = MyCache.get(:bob)
MyCache.set(:alice, %{alice | balance: alice.balance + 100})
MyCache.set(:bob, %{bob | balance: bob.balance + 100})
end,
[keys: [:alice, :bob]]
)
"""

@doc """
Runs the given function inside a transaction.
A successful transaction returns the value returned by the function wrapped
in a tuple as `{:ok, value}`.
In case the transaction cannot be executed, then `{:error, reason}` is
returned.
If an Elixir exception occurs, the exception will bubble up from the
transaction function. If the transaction is aborted,
`{:error, Nebulex.Error.t()}` is returned.
If an unhandled error/exception occurs, the error will bubble up from the
transaction function.
If `transaction/2` is called inside another transaction, the function is
simply executed without wrapping the new transaction call in any way.
A successful transaction returns the value returned by the function wrapped
in a tuple as `{:ok, any()}`.
See `c:Nebulex.Cache.transaction/2`.
"""
@callback transaction(Nebulex.Adapter.adapter_meta(), Nebulex.Cache.opts(), (() -> any())) ::
any()
@callback transaction(Nebulex.Adapter.adapter_meta(), fun(), Nebulex.Cache.opts()) ::
Nebulex.Cache.ok_error_tuple(any())

@doc """
Returns `{:ok, true}` if the current process is inside a transaction,
otherwise, `{:ok, false}` is returned.
Returns `{:error, reason}` if an error occurs.
Returns `{:error, Nebulex.Error.t()}` if an error occurs.
See `c:Nebulex.Cache.in_transaction?/1`.
"""
Expand All @@ -85,10 +86,10 @@ defmodule Nebulex.Adapter.Transaction do
quote do
@behaviour Nebulex.Adapter.Transaction

import Nebulex.Helpers
import Nebulex.Utils, only: [wrap_ok: 1, wrap_error: 2]

@impl true
def transaction(%{cache: cache, pid: pid} = adapter_meta, opts, fun) do
def transaction(%{cache: cache, pid: pid} = adapter_meta, fun, opts) do
adapter_meta
|> do_in_transaction?()
|> do_transaction(
Expand Down
2 changes: 1 addition & 1 deletion lib/nebulex/adapters/nil.ex
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ defmodule Nebulex.Adapters.Nil do
# Inherit default transaction implementation
use Nebulex.Adapter.Transaction

import Nebulex.Helpers
import Nebulex.Utils, only: [wrap_error: 2]

## Nebulex.Adapter

Expand Down
Loading

0 comments on commit 10a0380

Please sign in to comment.