Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for stats via Nebulex.Telemetry.StatsHandler #29

Merged
merged 3 commits into from
May 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions lib/nebulex_redis_adapter.ex
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,12 @@ defmodule NebulexRedisAdapter do
import Nebulex.Helpers
import NebulexRedisAdapter.Encoder

use Nebulex.Adapter.Stats

alias Nebulex.Adapter
alias Nebulex.Adapter.Stats
alias Nebulex.Telemetry
alias Nebulex.Telemetry.StatsHandler
alias NebulexRedisAdapter.{ClientCluster, Command, Connection, RedisCluster}

## Nebulex.Adapter
Expand Down Expand Up @@ -361,6 +366,9 @@ defmodule NebulexRedisAdapter do
{node_name, Keyword.get(node_opts, :pool_size, System.schedulers_online())}
end

# init stats
stats_counter = Stats.init(opts)

child_spec =
Nebulex.Adapters.Supervisor.child_spec(
name: normalize_module_name([name, Supervisor]),
Expand All @@ -374,14 +382,29 @@ defmodule NebulexRedisAdapter do
keyslot: keyslot,
nodes: nodes,
pool_size: pool_size,
stats_counter: stats_counter,
started_at: DateTime.utc_now(),
default_dt: Keyword.get(opts, :default_data_type, :object),
telemetry: Keyword.fetch!(opts, :telemetry),
telemetry_prefix: Keyword.fetch!(opts, :telemetry_prefix)
}

_ = maybe_attach_stats_handler(meta)

{:ok, child_spec, meta}
end

defp maybe_attach_stats_handler(%{stats_counter: nil}), do: :ok

defp maybe_attach_stats_handler(%{stats_counter: stats_counter} = meta) do
Telemetry.attach_many(
stats_counter,
[meta.telemetry_prefix ++ [:command, :stop]],
&StatsHandler.handle_event/4,
stats_counter
)
end

defp do_init(:standalone, name, pool_size, opts) do
{:ok, children} = Connection.init(name, pool_size, opts)
{children, ClientCluster.Keyslot}
Expand Down Expand Up @@ -622,6 +645,13 @@ defmodule NebulexRedisAdapter do
)
end

@impl Nebulex.Adapter.Stats
def stats(%{started_at: started_at} = adapter_meta) do
if stats = super(adapter_meta) do
%{stats | metadata: Map.put(stats.metadata, :started_at, started_at)}
end
end

## Private Functions

defp with_pipeline(adapter_meta, key, pipeline) do
Expand Down
42 changes: 42 additions & 0 deletions test/nebulex_redis_adapter/stats_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
defmodule NebulexRedisAdapter.StatsTest do
use ExUnit.Case, async: true

defmodule Cache do
use Nebulex.Cache,
otp_app: :nebulex,
adapter: NebulexRedisAdapter
end

setup do
{:ok, pid} = Cache.start_link(stats: true, conn_opts: [database: 1])

on_exit(fn ->
:ok = Process.sleep(100)
if Process.alive?(pid), do: Cache.stop(pid)
end)

{:ok, cache: Cache, name: Cache}
end

describe "c:NebulexRedisAdapter.stats/1" do
test "returns valid %Stats{}" do
size = Cache.count_all()
refute Cache.get("stats")
assert Cache.put("stats", "stats") == :ok
assert Cache.get("stats") == "stats"
assert Cache.put("stats", "stats") == :ok
assert Cache.take("stats") == "stats"
refute Cache.get("stats")
assert Cache.put_new("stats", "stats")
assert Cache.replace("stats", "stats stats")
assert Cache.delete_all() == size + 1

assert stats = Cache.stats()
assert stats.measurements.evictions == size + 2
assert stats.measurements.hits == 2
assert stats.measurements.misses == 2
assert stats.measurements.writes == 3
assert stats.measurements.updates == 1
end
end
end