Quickstart example
Assuming you are using Ecto
and you want to use declarative caching:
# In the config/config.exs file
config :my_app, MyApp.PartitionedCache,
primary: [
gc_interval: :timer.hours(12),
backend: :shards,
partitions: 2
]
# Defining a Cache with a partitioned topology
defmodule MyApp.PartitionedCache do
use Nebulex.Cache,
otp_app: :my_app,
adapter: Nebulex.Adapters.Partitioned,
primary_storage_adapter: Nebulex.Adapters.Local
end
# Some Ecto schema
defmodule MyApp.Accounts.User do
use Ecto.Schema
schema "users" do
field(:username, :string)
field(:password, :string)
field(:role, :string)
end
def changeset(user, attrs) do
user
|> cast(attrs, [:username, :password, :role])
|> validate_required([:username, :password, :role])
end
end
# The Accounts context
defmodule MyApp.Accounts do
use Nebulex.Caching
alias MyApp.Accounts.User
alias MyApp.PartitionedCache, as: Cache
alias MyApp.Repo
@ttl :timer.hours(1)
@decorate cacheable(cache: Cache, key: {User, id}, opts: [ttl: @ttl])
def get_user!(id) do
Repo.get!(User, id)
end
@decorate cacheable(cache: Cache, key: {User, username}, opts: [ttl: @ttl])
def get_user_by_username(username) do
Repo.get_by(User, [username: username])
end
@decorate cache_put(
cache: Cache,
keys: [{User, user.id}, {User, user.username}],
match: &match_update/1,
opts: [ttl: @ttl]
)
def update_user(%User{} = user, attrs) do
user
|> User.changeset(attrs)
|> Repo.update()
end
@decorate cache_evict(
cache: Cache,
keys: [{User, user.id}, {User, user.username}]
)
def delete_user(%User{} = user) do
Repo.delete(user)
end
def create_user(attrs \\ %{}) do
%User{}
|> User.changeset(attrs)
|> Repo.insert()
end
defp match_update({:ok, value}), do: {true, value}
defp match_update({:error, _}), do: false
end
See more Nebulex examples.
Testing
Testing by default spawns nodes internally for distributed tests. To run tests
that do not require clustering, exclude the clustered
tag:
$ mix test --exclude clustered
If you have issues running the clustered tests try running:
$ epmd -daemon
before running the tests.
Benchmarks
Nebulex provides a set of basic benchmark tests using the library benchee, and they are located within the directory benchmarks.
To run a benchmark test you have to run:
$ MIX_ENV=test mix run benchmarks/{BENCH_TEST_FILE}
Where BENCH_TEST_FILE
can be any of:
local_with_ets_bench.exs
: benchmark for the local adapter using:ets
backend.local_with_shards_bench.exs
: benchmark for the local adapter using:shards
backend.partitioned_bench.exs
: benchmark for the partitioned adapter.
For example, for running the benchmark for the local adapter using :shards
backend:
$ MIX_ENV=test mix run benchmarks/local_with_shards_bench.exs
Additionally, you can also run performance tests using :basho_bench
.
See nebulex_bench example
for more information.