Nebulex v1.2.0 Nebulex.Cache behaviour View Source

Cache Main Interface.

A Cache maps to an underlying implementation, controlled by the adapter. For example, Nebulex ships with a default adapter that implements a local generational cache.

When used, the Cache expects the :otp_app and :adapter as options. The :otp_app should point to an OTP application that has the Cache configuration. For example, the Cache:

defmodule MyCache do
  use Nebulex.Cache,
    otp_app: :my_app,
    adapter: Nebulex.Adapters.Local
end

Could be configured with:

config :my_app, MyCache,
  version_generator: MyCache.VersionGenerator,
  stats: true,
  gc_interval: 3600

Most of the configuration that goes into the config is specific to the adapter, so check Nebulex.Adapters.Local documentation for more information. However, some configuration is shared across all adapters, they are:

  • :version_generator - this option specifies the module that implements the Nebulex.Object.Version interface. This interface defines only one callback generate/1 that is invoked by the adapters to generate new object versions. If this option is not set, then the version is set to nil by default.

  • :stats - a compile-time option that specifies if cache statistics is enabled or not (defaults to false).

Pre/Post hooks

The cache can also provide its own pre/post hooks implementation; see Nebulex.Hook behaviour. By default, pre/post hooks are empty lists, but you can override the functions of Nebulex.Hook behaviour.

Additionally, it is possible to configure the mode how the hooks are evaluated (synchronous, asynchronous and pipeline).

For more information about the usage, check out Nebulex.Hook.

Shared options

Almost all of the Cache operations below accept the following options:

  • :return - Selects return type: :value | :key | :object. If :value (the default) is set, only object's value is returned. If :key set, only object's key is returned. If :object is set, Nebulex.Object.t() is returned.

  • :version - The version of the object on which the operation will take place. The version can be any term (default: nil).

  • :ttl - Time To Live (TTL) or expiration time in seconds for a key (default: :infinity).

Such cases will be explicitly documented as well as any extra option.

Extended API

Some adapters might extend the API with additional functions, therefore, it is important to check out adapters' documentation.

Link to this section Summary

Types

Cache entries

Object key

Cache object

Cache action options

Return alternatives (value is the default)

t()

Object value

Callbacks

Returns the adapter tied to the cache.

Sets the given value under key into the cache, only if it does not already exist.

Similar to add/3 but raises Nebulex.KeyAlreadyExistsError if the key already exists.

When the key already exists, the cached value is replaced by value, otherwise the object is created at fisrt time.

Fetches all entries from cache matching the given query.

Returns the adapter configuration stored in the :otp_app environment.

Deletes the entry in cache for a specific key.

Dumps a cache to the given file path.

Returns the expiry timestamp for the given key, if the timeout ttl (in seconds) is successfully updated.

Flushes the cache.

Gets a value or object from Cache where the key matches the given key.

Similar to get/2 but raises KeyError if key is not found.

Gets the object/value from key and updates it, all in one pass.

Returns a map with the values or objects (check :return option) for all specified keys. For every key that does not hold a value or does not exist, that key is simply ignored. Because of this, the operation never fails.

Returns whether the given key exists in cache.

Returns true if the current process is inside a transaction.

A callback executed when the cache starts or when configuration is read.

Loads a dumped cache from the given path.

Returns the information associated with attr for the given key, or returns nil if key doesn't exist.

Alters the object stored under key, but only if the object already exists into the cache.

Similar to replace/3 but raises KeyError if key is not found.

Sets the given value under key into the cache.

Sets the given entries, replacing existing ones, just as regular set.

Returns the total number of cached entries.

Starts a supervision and return {:ok, pid} or just :ok if nothing needs to be done.

Shuts down the cache represented by the given pid.

Similar to all/2 but returns a lazy enumerable that emits all entries from the cache matching the given query.

Returns and removes the object with key key in the cache.

Similar to take/2 but raises KeyError if key is not found.

Runs the given function inside a transaction.

Updates the cached key with the given function.

Updates (increment or decrement) the counter mapped to the given key.

Link to this section Types

Link to this type

entries()

View Source
entries() :: map() | [{key(), value()}] | [object()]

Cache entries

Object key

Cache object

Cache action options

Link to this type

return()

View Source
return() :: key() | value() | object()

Return alternatives (value is the default)

Object value

Link to this section Callbacks

Returns the adapter tied to the cache.

Link to this callback

add(key, value, opts)

View Source
add(key(), value(), opts()) :: {:ok, return()} | :error

Sets the given value under key into the cache, only if it does not already exist.

If cache doesn't contain the given key, then {:ok, value} is returned. If cache contains key, :error is returned.

Options

See the "Shared options" section at the module documentation.

For add operation, the option :version is ignored.

Example

iex> MyCache.add("foo", "bar")
{ok, "bar"}

iex> MyCache.add("foo", "bar")
:error

# if the value is nil, it is not stored (operation is skipped)
iex> MyCache.add("foo", nil)
{ok, nil}
Link to this callback

add!(key, value, opts)

View Source
add!(key(), value(), opts()) :: return() | no_return()

Similar to add/3 but raises Nebulex.KeyAlreadyExistsError if the key already exists.

Options

See the "Shared options" section at the module documentation.

Example

MyCache.add!("foo", "bar")
Link to this callback

add_or_replace!(key, value, opts)

View Source
add_or_replace!(key(), value(), opts()) :: return() | no_return()

When the key already exists, the cached value is replaced by value, otherwise the object is created at fisrt time.

Returns the replaced or created value when the function is completed successfully. Because this function is a combination of replace/3 and add!/3 functions, there might be a race condition between them, in that case the last operation add!/3 fails with Nebulex.KeyAlreadyExistsError.

Options

Besides the "Shared options" section at the module documentation, it accepts:

  • :on_conflict - Same as callback set/3.

Example

MyCache.add_or_replace!("foo", "bar")
Link to this callback

all(query, opts)

View Source (optional)
all(query :: term() | nil, opts()) :: [any()]

Fetches all entries from cache matching the given query.

If the query is nil, it fetches all entries from cache; this is common for all adapters. However, the query could be any other value, which depends entirely on the adapter's implementation; check out the "Query" section below.

May raise Nebulex.QueryError if query validation fails.

Options

See the "Shared options" section at the module documentation.

Note that for this function, option :version is ignored.

Example

# set some entries
iex> :ok = Enum.each(1..5, &MyCache.set(&1, &1 * 2))

# fetch all (with default params)
iex> MyCache.all()
[1, 2, 3, 4, 5]

# fetch all entries and return values
iex> MyCache.all(nil, return: :value)
[2, 4, 6, 8, 10]

# fetch all entries and return objects
iex> [%Nebulex.Object{} | _] = MyCache.all(nil, return: :object)

# fetch all entries that match with the given query
# assuming we are using Nebulex.Adapters.Local adapter
iex> query = [{{:"$1", :"$2", :_, :_}, [{:>, :"$2", 5}], [:"$1"]}]
iex> MyCache.all(query)
[3, 4, 5]

Query

Query spec is defined by the adapter, hence, it is recommended to check out adapters documentation. For instance, the built-in Nebulex.Adapters.Local adapter supports nil | :all_unexpired | :all_expired | :ets.match_spec() as query value.

Examples

# additional built-in queries for Nebulex.Adapters.Local adapter
iex> all_unexpired = MyCache.all(:all_unexpired)
iex> all_expired = MyCache.all(:all_expired)

# if we are using Nebulex.Adapters.Local adapter, the stored entry
# is a tuple {key, value, version, expire_at}, then the match spec
# could be something like:
iex> spec = [{{:"$1", :"$2", :_, :_}, [{:>, :"$2", 5}], [{{:"$1", :"$2"}}]}]
iex> MyCache.all(spec)
[{3, 6}, {4, 8}, {5, 10}]

# the same previous query but using Ex2ms
iex> import Ex2ms
Ex2ms

iex> spec =
...>   fun do
...>     {key, value, _, _} when value > 5 -> {key, value}
...>   end

iex> MyCache.all(spec)
[{3, 6}, {4, 8}, {5, 10}]

To learn more, check out adapters' documentation.

Returns the adapter configuration stored in the :otp_app environment.

If the c:init/2 callback is implemented in the cache, it will be invoked.

Link to this callback

delete(key, opts)

View Source
delete(key(), opts()) :: return() | nil

Deletes the entry in cache for a specific key.

If the key does not exist, returns the result according to the :return option (for delete defaults to :key) but the cache is not altered.

Options

Besides the "Shared options" section at the module documentation, it accepts:

  • :on_conflict - It may be one of :raise (the default), :nothing, :override. See the "OnConflict" section for more information.

Note that for this function :return option hasn't any effect since it always returns the key either success or not.

Example

iex> MyCache.set(:a, 1)
1

iex> MyCache.delete(:a)
:a

iex> MyCache.get(:a)
nil

iex> MyCache.delete(:non_existent_key)
:non_existent_key

OnConflict

The :on_conflict option supports the following values:

  • :raise - raises if there is a conflicting key
  • :nothing - ignores the error in case of conflicts
  • :override - the command is executed ignoring the conflict, then the value on the existing key is deleted

Examples

# Set a value
iex> MyCache.set(:a, 1)
1

# Delete with an invalid version but do nothing on conflicts.
# Keep in mind that, although this returns successfully, the returned
# `key` does not reflect the data in the cache. For instance, in case
# of "on_conflict: :nothing", the returned `key` isn't deleted.
iex> MyCache.delete(:a, version: :invalid, on_conflict: :nothing)
:a

iex> MyCache.get(:a)
1

# Delete with the same invalid version but force to delete the current
# value on conflicts (if the entry exists).
iex> MyCache.delete(:a, version: :invalid, on_conflict: :override)
:a

iex> MyCache.get(:a)
nil
Link to this callback

dump(path, opts)

View Source (optional)
dump(path :: Path.t(), opts()) :: :ok | {:error, term()}

Dumps a cache to the given file path.

Returns :ok if successful, or {:error, reason} if an error occurs.

Options

This operation relies entirely on the adapter implementation, which means the options depend on each of them. For that reason, it is recommended to check the documentation of the adapter to be used. The built-in adapters inherit the default implementation from Nebulex.Adapter.Persistence, so check out the available options there.

Examples

# set some entries
iex> entries = for x <- 1..10, into: %{}, do: {x, x}
iex> MyCache.set_many(entries)
:ok

# dump cache to a file
iex> MyCache.dump("my_cache")
:ok

To learn more, check out adapters' documentation.

Link to this callback

expire(key, ttl)

View Source
expire(key(), ttl :: timeout()) :: timeout() | nil

Returns the expiry timestamp for the given key, if the timeout ttl (in seconds) is successfully updated.

If key doesn't exist, nil is returned.

Examples

iex> MyCache.set(:a, 1)
1

iex> MyCache.expire(:a, 5)
1540004049

iex> MyCache.expire(:a, :infinity)
:infinity

iex> MyCache.ttl(:b, 5)
nil

Flushes the cache.

Examples

iex> :ok = Enum.each(1..5, &MyCache.set(&1, &1))
iex> MyCache.flush()
:ok

iex> Enum.each(1..5, fn x ->
...>   nil = MyCache.get(x)
...> end)
Link to this callback

get(key, opts)

View Source
get(key(), opts()) :: return() | nil

Gets a value or object from Cache where the key matches the given key.

Returns nil if no result was found.

Options

Besides the "Shared options" section at the module documentation, it accepts:

  • :on_conflict - It may be one of :raise (the default), :nothing, :override. See the "OnConflict" section for more information.

Example

iex> MyCache.set("foo", "bar")
"bar"

iex>  MyCache.get("foo")
"bar"

iex>  MyCache.get("foo", return: :object)
%Nebulex.Object{key: "foo", value: "bar", version: nil, expire_at: nil}

 iex> MyCache.get(:non_existent_key)
 nil

OnConflict

The :on_conflict option supports the following values:

  • :raise - raises if there is a conflicting key
  • :nothing - ignores the error in case of conflicts
  • :override - same effect as :nothing

Examples

# Set a value
iex> MyCache.set(:a, 1)
1

# Gets with an invalid version but do nothing on conflicts.
# Keep in mind that, although this returns successfully, the returned
# struct does not reflect the data in the Cache. For instance, in case
# of "on_conflict: :nothing", it returns the latest version of the
# cached object.
iex> %Nebulex.Object{value: 1} =
...>   MyCache.get(:a, return: :object, version: :invalid, on_conflict: :nothing)
iex> MyCache.get(:a)
1
Link to this callback

get!(key, opts)

View Source
get!(key(), opts()) :: return() | no_return()

Similar to get/2 but raises KeyError if key is not found.

Options

See the "Shared options" section at the module documentation.

Example

MyCache.get!(:a)
Link to this callback

get_and_update(key, function, opts)

View Source
get_and_update(key(), (value() -> {get, update} | :pop), opts()) ::
  {get, update}
when get: value(), update: return()

Gets the object/value from key and updates it, all in one pass.

fun is called with the current cached value under key (or nil if key hasn't been cached) and must return a two-element tuple: the "get" value (the retrieved value, which can be operated on before being returned) and the new value to be stored under key. fun may also return :pop, which means the current value shall be removed from Cache and returned.

The returned value is a tuple with the "get" value returned by fun and the new updated value under key.

Options

Besides the "Shared options" section at the module documentation, it accepts:

  • :on_conflict - Same as callback set/3.

Examples

# update nonexistent key
iex> MyCache.get_and_update(:a, fn current_value ->
...>   {current_value, "value!"}
...> end)
{nil, "value!"}

# update existing key
iex> MyCache.get_and_update(:a, fn current_value ->
...>   {current_value, "new value!"}
...> end)
{"value!", "new value!"}

# pop/remove value if exist
iex> MyCache.get_and_update(:a, fn _ -> :pop end)
{"new value!", nil}

# pop/remove nonexistent key
iex> MyCache.get_and_update(:b, fn _ -> :pop end)
{nil, nil}

# update existing key but returning the object
iex> {"hello", %Object{key: :a, value: "hello world"}} =
...>   :a
...>   |> MyCache.set!("hello", return: :key)
...>   |> MyCache.get_and_update(fn current_value ->
...>        {current_value, "hello world"}
...>   end, return: :object)
Link to this callback

get_many(list, opts)

View Source
get_many([key()], opts()) :: map()

Returns a map with the values or objects (check :return option) for all specified keys. For every key that does not hold a value or does not exist, that key is simply ignored. Because of this, the operation never fails.

Options

See the "Shared options" section at the module documentation.

Note that for this function, option :version is ignored.

Example

iex> MyCache.set_many([a: 1, c: 3])
:ok

iex> MyCache.get_many([:a, :b, :c])
%{a: 1, c: 3}
Link to this callback

has_key?(key)

View Source
has_key?(key()) :: boolean()

Returns whether the given key exists in cache.

Examples

iex> MyCache.set(:a, 1)
1

iex> MyCache.has_key?(:a)
true

iex> MyCache.has_key?(:b)
false
Link to this callback

in_transaction?()

View Source (optional)
in_transaction?() :: boolean()

Returns true if the current process is inside a transaction.

Examples

MyCache.in_transaction?
#=> false

MyCache.transaction(fn ->
  MyCache.in_transaction? #=> true
end)
Link to this callback

init(config)

View Source (optional)
init(config :: Keyword.t()) :: {:ok, Keyword.t()} | :ignore

A callback executed when the cache starts or when configuration is read.

Link to this callback

load(path, opts)

View Source (optional)
load(path :: Path.t(), opts()) :: :ok | {:error, term()}

Loads a dumped cache from the given path.

Returns :ok if successful, or {:error, reason} if an error occurs.

Options

Similar to dump/2, this operation relies entirely on the adapter implementation, therefore, it is recommended to check the documentation of the adapter to be used. Similarly, the built-in adapters inherit the default implementation from Nebulex.Adapter.Persistence, so check out the available options there.

Examples

# set some entries
iex> entries = for x <- 1..10, into: %{}, do: {x, x}
iex> MyCache.set_many(entries)
:ok

# dump cache to a file
iex> MyCache.dump("my_cache")
:ok

# load the cache from a file
iex> MyCache.load("my_cache")
:ok

To learn more, check out adapters' documentation.

Link to this callback

object_info(key, attr)

View Source
object_info(key(), attr :: :ttl | :version) :: term() | nil

Returns the information associated with attr for the given key, or returns nil if key doesn't exist.

If attr is not one of the allowed values, ArgumentError is raised.

The following values are allowed for attr:

  • :ttl - Returns the remaining time to live for the given key, if it has a timeout, otherwise, :infinity is returned.

  • :version - Returns the current version for the given key.

Examples

iex> MyCache.set(:a, 1, ttl: 5)
1

iex> MyCache.set(:b, 2)
2

iex> MyCache.object_info(:a, :ttl)
5

iex> MyCache.ttl(:b)
:infinity

iex> MyCache.object_info(:a, :version)
nil
Link to this callback

replace(key, value, opts)

View Source
replace(key(), value(), opts()) :: {:ok, return()} | :error

Alters the object stored under key, but only if the object already exists into the cache.

If cache contains the given key, then {:ok, return} is returned. If cache doesn't contain key, :error is returned.

Options

Besides the "Shared options" section at the module documentation, it accepts:

  • :on_conflict - Same as callback set/3.

Example

iex> MyCache.replace("foo", "bar")
:error

iex> MyCache.set("foo", "bar")
"bar"

# update only current value
iex> MyCache.replace("foo", "bar2")
{:ok, "bar2"}

# update current value and TTL
iex> MyCache.replace("foo", "bar3", ttl: 10)
{:ok, "bar3"}
Link to this callback

replace!(key, value, opts)

View Source
replace!(key(), value(), opts()) :: return() | no_return()

Similar to replace/3 but raises KeyError if key is not found.

Options

Besides the "Shared options" section at the module documentation, it accepts:

  • :on_conflict - Same as callback set/3.

Example

MyCache.replace!("foo", "bar")
Link to this callback

set(key, value, opts)

View Source
set(key(), value(), opts()) :: return() | nil

Sets the given value under key into the cache.

If key already holds an object, it is overwritten. Any previous time to live associated with the key is discarded on successful set operation.

Returns either the value, key or the object, depending on :return option, if the action is completed successfully.

Options

Besides the "Shared options" section at the module documentation, it accepts:

  • :on_conflict - It may be one of :raise (the default), :nothing, :override. See the "OnConflict" section for more information.

Example

iex> MyCache.set("foo", "bar")
"bar"

iex> MyCache.set("foo", "bar", ttl: 10, return: :object)
%Nebulex.Object{key: "foo", value: "bar", version: nil, expire_at: 1540004049}

# if the value is nil, then it is not stored (operation is skipped)
iex> MyCache.set("foo", nil)
nil

OnConflict

The :on_conflict option supports the following values:

  • :raise - raises if there is a conflicting key
  • :nothing - ignores the error in case of conflicts
  • :override - the command is executed ignoring the conflict, then the value on the existing key is replaced with the given value

Examples

iex> %Nebulex.Object{version: v1} = MyCache.set(:a, 1, return: :object)
iex> MyCache.set(:a, 2, version: v1)
2

# Set with the same key and wrong version but do nothing on conflicts.
# Keep in mind in case of "on_conflict: :nothing", the returned object
# is the current cached object, if there is one
iex> MyCache.set(:a, 3, version: v1, on_conflict: :nothing)
2

# Set with the same key and wrong version but replace the current
# value on conflicts.
iex> MyCache.set(:a, 3, version: v1, on_conflict: :override)
3
Link to this callback

set_many(entries, opts)

View Source
set_many(entries(), opts()) :: :ok | {:error, failed_keys :: [key()]}

Sets the given entries, replacing existing ones, just as regular set.

Returns :ok if the all entries were successfully set, otherwise {:error, failed_keys}, where failed_keys contains the keys that could not be set.

Ideally, this operation should be atomic, so all given keys are set at once. But it depends purely on the adapter's implementation and the backend used internally by the adapter. Hence, it is recommended to checkout the adapter's documentation.

Options

See the "Shared options" section at the module documentation.

Note that for this function, option :version is ignored.

Example

iex> MyCache.set_many(apples: 3, bananas: 1)
:ok

iex> MyCache.set_many(%{"apples" => 1, "bananas" => 3})
:ok

# set a custom list of objects
iex> MyCache.set_many([
...>   %Nebulex.Object{key: :apples, value: 1},
...>   %Nebulex.Object{key: :bananas, value: 2, expire_at: 5}
...> ])
:ok

# for some reason `:c` couldn't be set, so we got an error
iex> MyCache.set_many([a: 1, b: 2, c: 3], ttl: 1000)
{:error, [:c]}

Returns the total number of cached entries.

Examples

iex> :ok = Enum.each(1..10, &MyCache.set(&1, &1))
iex> MyCache.size()
10

iex> :ok = Enum.each(1..5, &MyCache.delete(&1))
iex> MyCache.size()
5
Link to this callback

start_link(opts)

View Source
start_link(opts()) ::
  {:ok, pid()} | {:error, {:already_started, pid()}} | {:error, term()}

Starts a supervision and return {:ok, pid} or just :ok if nothing needs to be done.

Returns {:error, {:already_started, pid}} if the cache is already started or {:error, term} in case anything else goes wrong.

Options

See the configuration in the moduledoc for options shared between adapters, for adapter-specific configuration see the adapter's documentation.

Link to this callback

stop(pid, timeout)

View Source
stop(pid(), timeout()) :: :ok

Shuts down the cache represented by the given pid.

Link to this callback

stream(query, opts)

View Source (optional)
stream(query :: term() | nil, opts()) :: Enum.t()

Similar to all/2 but returns a lazy enumerable that emits all entries from the cache matching the given query.

May raise Nebulex.QueryError if query validation fails.

Options

Besides the "Shared options" section at the module documentation, it accepts:

  • :page_size - Positive integer (>= 1) that defines the page size for the stream (defaults to 10).

Examples

# set some entries
iex> :ok = Enum.each(1..5, &MyCache.set(&1, &1 * 2))

# stream all (with default params)
iex> MyCache.stream() |> Enum.to_list()
[1, 2, 3, 4, 5]

# stream all entries and return values
iex> MyCache.stream(nil, return: :value, page_size: 3) |> Enum.to_list()
[2, 4, 6, 8, 10]

# stream all entries and return objects
iex> stream = MyCache.stream(nil, return: :object, page_size: 3)
iex> [%Nebulex.Object{} | _] = Enum.to_list(stream)

# additional built-in queries for Nebulex.Adapters.Local adapter
all_unexpired_stream = MyCache.stream(:all_unexpired)
all_expired_stream = MyCache.stream(:all_expired)

# if we are using Nebulex.Adapters.Local adapter, the stored entry
# is a tuple {key, value, version, expire_at}, then the match spec
# could be something like:
iex> spec = [{{:"$1", :"$2", :_, :_}, [{:>, :"$2", 5}], [{{:"$1", :"$2"}}]}]
iex> MyCache.stream(spec, page_size: 3) |> Enum.to_list()
[{3, 6}, {4, 8}, {5, 10}]

# the same previous query but using Ex2ms
iex> import Ex2ms
Ex2ms

iex> spec =
...>   fun do
...>     {key, value, _, _} when value > 5 -> {key, value}
...>   end

iex> spec |> MyCache.stream(page_size: 3) |> Enum.to_list()
[{3, 6}, {4, 8}, {5, 10}]

To learn more, check out adapters' documentation.

Link to this callback

take(key, opts)

View Source
take(key(), opts()) :: return() | nil

Returns and removes the object with key key in the cache.

Returns nil if no result was found.

Options

Besides the "Shared options" section at the module documentation, it accepts:

  • :on_conflict - Same as callback set/3.

Examples

iex> MyCache.set(:a, 1)
1

iex> MyCache.take(:a)
1

iex> MyCache.take(:a)
nil

iex> :a |> MyCache.set(1, return: :key) |> MyCache.take(return: :object)
%Nebulex.Object{key: :a, value: 1, version: nil, expire_at: nil}
Link to this callback

take!(key, opts)

View Source
take!(key(), opts()) :: return() | no_return()

Similar to take/2 but raises KeyError if key is not found.

Options

See the "Shared options" section at the module documentation.

Example

MyCache.take!(:a)
Link to this callback

transaction(function, opts)

View Source (optional)
transaction(function :: (... -> any()), opts()) :: term()

Runs the given function inside a transaction.

A successful transaction returns the value returned by the function.

Options

See the "Shared options" section at the module documentation.

Examples

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

# locking only the involved key (recommended):
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]
Link to this callback

update(key, initial, function, opts)

View Source
update(key(), initial :: value(), (value() -> value()), opts()) :: return()

Updates the cached key with the given function.

If key is present in Cache with value value, fun is invoked with argument value and its result is used as the new value of key.

If key is not present in Cache, initial is inserted as the value of key.

Options

Besides the "Shared options" section at the module documentation, it accepts:

  • :on_conflict - Same as callback set/3.

Examples

iex> MyCache.update(:a, 1, &(&1 * 2))
1

iex> MyCache.update(:a, 1, &(&1 * 2))
2

iex> %Nebulex.Object{value: 4} =
...>   MyCache.update(:a, 1, &(&1 * 2), return: :object)
Link to this callback

update_counter(key, incr, opts)

View Source
update_counter(key(), incr :: integer(), opts()) :: integer()

Updates (increment or decrement) the counter mapped to the given key.

If incr >= 0 then the current value is incremented by that amount, otherwise the current value is decremented.

If incr is not a valid integer, then an ArgumentError exception is raised.

Options

See the "Shared options" section at the module documentation.

Note that for this function, option :version is ignored.

Examples

iex> MyCache.update_counter(:a)
1

iex> MyCache.update_counter(:a, 2)
3

iex> MyCache.update_counter(:a, -1)
2

iex> %Nebulex.Object{key: :a, value: 2} =
...>   MyCache.update_counter(:a, 0, return: :object)