Skip to content

Commit

Permalink
Rely on con_cache telemetry (#4019)
Browse files Browse the repository at this point in the history
* Rely on con_cache telemetry

Now that sasa1977/con_cache#76
is released, we don't have to use low-level operations
to emit hit/miss events.

This PR also wraps cache processes with
a function returning appropriate child specs lists.

Ideally each cache will have its own supervisor/child specs
going forward. This is an intermediate step in that direction.

* Update lib/plausible/application.ex

Co-authored-by: Adrian Gruntkowski <[email protected]>

* Declare caches without warmers with plain child specs

---------

Co-authored-by: Adrian Gruntkowski <[email protected]>
  • Loading branch information
2 people authored and ruslandoga committed May 1, 2024
1 parent 42df4e0 commit 68b17db
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 174 deletions.
146 changes: 70 additions & 76 deletions lib/plausible/application.ex
Original file line number Diff line number Diff line change
Expand Up @@ -32,81 +32,56 @@ defmodule Plausible.Application do
ttl_check_interval: :timer.seconds(1),
global_ttl: :timer.minutes(30)
),
{Plausible.Site.Cache, ttl_check_interval: false},
{Plausible.Cache.Warmer,
[
child_name: Plausible.Site.Cache.All,
cache_impl: Plausible.Site.Cache,
interval: :timer.minutes(15) + Enum.random(1..:timer.seconds(10)),
warmer_fn: :refresh_all
]},
{Plausible.Cache.Warmer,
[
child_name: Plausible.Site.Cache.RecentlyUpdated,
cache_impl: Plausible.Site.Cache,
interval: :timer.seconds(30),
warmer_fn: :refresh_updated_recently
]},
{Plausible.Shield.IPRuleCache, ttl_check_interval: false},
{Plausible.Cache.Warmer,
[
child_name: Plausible.Shield.IPRuleCache.All,
cache_impl: Plausible.Shield.IPRuleCache,
interval: :timer.minutes(3) + Enum.random(1..:timer.seconds(10)),
warmer_fn: :refresh_all
]},
{Plausible.Cache.Warmer,
[
child_name: Plausible.Shield.IPRuleCache.RecentlyUpdated,
cache_impl: Plausible.Shield.IPRuleCache,
interval: :timer.seconds(35),
warmer_fn: :refresh_updated_recently
]},
{Plausible.Shield.CountryRuleCache, ttl_check_interval: false},
{Plausible.Cache.Warmer,
[
child_name: Plausible.Shield.CountryRuleCache.All,
cache_impl: Plausible.Shield.CountryRuleCache,
interval: :timer.minutes(3) + Enum.random(1..:timer.seconds(10)),
warmer_fn: :refresh_all
]},
{Plausible.Cache.Warmer,
[
child_name: Plausible.Shield.CountryRuleCache.RecentlyUpdated,
cache_impl: Plausible.Shield.CountryRuleCache,
interval: :timer.seconds(35),
warmer_fn: :refresh_updated_recently
]},
{Plausible.Shield.PageRuleCache, ttl_check_interval: false, ets_options: [:bag]},
{Plausible.Cache.Warmer,
[
child_name: Plausible.Shield.PageRuleCache.All,
cache_impl: Plausible.Shield.PageRuleCache,
interval: :timer.minutes(3) + Enum.random(1..:timer.seconds(10)),
warmer_fn: :refresh_all
]},
{Plausible.Cache.Warmer,
[
child_name: Plausible.Shield.PageRuleCache.RecentlyUpdated,
cache_impl: Plausible.Shield.PageRuleCache,
interval: :timer.seconds(35),
warmer_fn: :refresh_updated_recently
]},
{Plausible.Shield.HostnameRuleCache, ttl_check_interval: false, ets_options: [:bag]},
{Plausible.Cache.Warmer,
[
child_name: Plausible.Shield.HostnameRuleCache.All,
cache_impl: Plausible.Shield.HostnameRuleCache,
interval: :timer.minutes(3) + Enum.random(1..:timer.seconds(10)),
warmer_fn: :refresh_all
]},
{Plausible.Cache.Warmer,
[
child_name: Plausible.Shield.HostnameRuleCache.RecentlyUpdated,
cache_impl: Plausible.Shield.HostnameRuleCache,
interval: :timer.seconds(25),
warmer_fn: :refresh_updated_recently
]},
warmed_cache(Plausible.Site.Cache,
adapter_opts: [ttl_check_interval: false],
warmers: [
refresh_all:
{Plausible.Site.Cache.All,
interval: :timer.minutes(15) + Enum.random(1..:timer.seconds(10))},
refresh_updated_recently:
{Plausible.Site.Cache.RecentlyUpdated, interval: :timer.seconds(30)}
]
),
warmed_cache(Plausible.Shield.IPRuleCache,
adapter_opts: [ttl_check_interval: false],
warmers: [
refresh_all:
{Plausible.Shield.IPRuleCache.All,
interval: :timer.minutes(3) + Enum.random(1..:timer.seconds(10))},
refresh_updated_recently:
{Plausible.Shield.IPRuleCache.RecentlyUpdated, interval: :timer.seconds(35)}
]
),
warmed_cache(Plausible.Shield.CountryRuleCache,
adapter_opts: [ttl_check_interval: false],
warmers: [
refresh_all:
{Plausible.Shield.CountryRuleCache.All,
interval: :timer.minutes(3) + Enum.random(1..:timer.seconds(10))},
refresh_updated_recently:
{Plausible.Shield.CountryRuleCache.RecentlyUpdated, interval: :timer.seconds(35)}
]
),
warmed_cache(Plausible.Shield.PageRuleCache,
adapter_opts: [ttl_check_interval: false, ets_options: [:bag]],
warmers: [
refresh_all:
{Plausible.Shield.PageRuleCache.All,
interval: :timer.minutes(3) + Enum.random(1..:timer.seconds(10))},
refresh_updated_recently:
{Plausible.Shield.PageRuleCache.RecentlyUpdated, interval: :timer.seconds(35)}
]
),
warmed_cache(Plausible.Shield.HostnameRuleCache,
adapter_opts: [ttl_check_interval: false, ets_options: [:bag]],
warmers: [
refresh_all:
{Plausible.Shield.HostnameRuleCache.All,
interval: :timer.minutes(3) + Enum.random(1..:timer.seconds(10))},
refresh_updated_recently:
{Plausible.Shield.HostnameRuleCache.RecentlyUpdated, interval: :timer.seconds(25)}
]
),
{Plausible.Auth.TOTP.Vault, key: totp_vault_key()},
PlausibleWeb.Endpoint,
{Oban, Application.get_env(:plausible, Oban)},
Expand All @@ -123,7 +98,7 @@ defmodule Plausible.Application do
Location.load_all()
Plausible.Geo.await_loader()

Supervisor.start_link(children, opts)
Supervisor.start_link(List.flatten(children), opts)
end

def config_change(changed, _new, removed) do
Expand Down Expand Up @@ -222,4 +197,23 @@ defmodule Plausible.Application do
opts = Application.fetch_env!(:plausible, Plausible.Geo)
:ok = Plausible.Geo.load_db(opts)
end

defp warmed_cache(impl_mod, opts) when is_atom(impl_mod) and is_list(opts) do
warmers = Keyword.fetch!(opts, :warmers)

warmer_specs =
Enum.map(warmers, fn {warmer_fn, {warmer_id, warmer_opts}} ->
{Plausible.Cache.Warmer,
Keyword.merge(
[
child_name: warmer_id,
cache_impl: impl_mod,
warmer_fn: warmer_fn
],
warmer_opts
)}
end)

[{impl_mod, Keyword.fetch!(opts, :adapter_opts)} | warmer_specs]
end
end
2 changes: 0 additions & 2 deletions lib/plausible/cache.ex
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,6 @@ defmodule Plausible.Cache do
# credo:disable-for-this-file Credo.Check.Refactor.LongQuoteBlocks
defmacro __using__(_opts) do
quote do
require Logger

@behaviour Plausible.Cache
@modes [:all, :updated_recently]

Expand Down
39 changes: 2 additions & 37 deletions lib/plausible/cache/adapter.ex
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,7 @@ defmodule Plausible.Cache.Adapter do

@spec get(atom(), any()) :: any()
def get(cache_name, key) do
result = ConCache.get(cache_name, key)
if is_nil(result), do: miss(cache_name), else: hit(cache_name)
result
ConCache.get(cache_name, key)
catch
:exit, _ ->
Logger.error("Error retrieving key from '#{inspect(cache_name)}'")
Expand All @@ -47,16 +45,7 @@ defmodule Plausible.Cache.Adapter do

@spec get(atom(), any(), (-> any())) :: any()
def get(cache_name, key, fallback_fn) do
cache = ConCache.Owner.cache(cache_name)

case ConCache.Operations.get(cache, key) do
nil ->
get_or_store_isolated(cache, cache_name, key, fallback_fn)

value ->
hit(cache_name)
value
end
ConCache.get_or_store(cache_name, key, fallback_fn)
catch
:exit, _ ->
Logger.error("Error retrieving key from '#{inspect(cache_name)}'")
Expand Down Expand Up @@ -109,28 +98,4 @@ defmodule Plausible.Cache.Adapter do
Logger.error("Error retrieving key from '#{inspect(cache_name)}'")
[]
end

defp hit(cache_name) do
Plausible.Cache.Stats.record_hit(cache_name)
end

defp miss(cache_name) do
Plausible.Cache.Stats.record_miss(cache_name)
end

defp get_or_store_isolated(cache, cache_name, key, fun) do
ConCache.isolated(cache_name, key, fn ->
case ConCache.Operations.get(cache, key) do
nil ->
new_value = fun.()
ConCache.Operations.dirty_put(cache, key, new_value)
miss(cache_name)
new_value

existing ->
hit(cache_name)
existing
end
end)
end
end
16 changes: 4 additions & 12 deletions lib/plausible/cache/stats.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,14 @@ defmodule Plausible.Cache.Stats do

@hit :hit
@miss :miss
@telemetry_hit [:plausible, :cache, :adapter, @hit]
@telemetry_miss [:plausible, :cache, :adapter, @miss]
@telemetry_hit ConCache.Operations.telemetry_hit()
@telemetry_miss ConCache.Operations.telemetry_miss()
@telemetry_events [@telemetry_hit, @telemetry_miss]

def start_link(_opts) do
GenServer.start_link(__MODULE__, nil)
end

def record_hit(cache_name) do
:telemetry.execute(@telemetry_hit, %{}, %{cache_name: cache_name})
end

def record_miss(cache_name) do
:telemetry.execute(@telemetry_miss, %{}, %{cache_name: cache_name})
end

def init(nil) do
__MODULE__ =
:ets.new(__MODULE__, [
Expand All @@ -43,11 +35,11 @@ defmodule Plausible.Cache.Stats do
{:ok, nil}
end

def handle_telemetry_event(@telemetry_hit, _measurments, %{cache_name: cache_name}, _) do
def handle_telemetry_event(@telemetry_hit, _measurments, %{cache: %{name: cache_name}}, _) do
bump(cache_name, @hit)
end

def handle_telemetry_event(@telemetry_miss, _measurments, %{cache_name: cache_name}, _) do
def handle_telemetry_event(@telemetry_miss, _measurments, %{cache: %{name: cache_name}}, _) do
bump(cache_name, @miss)
end

Expand Down
2 changes: 1 addition & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ defmodule Plausible.MixProject do
{:ex_aws_s3, "~> 2.5"},
{:sweet_xml, "~> 0.7.4"},
{:zstream, "~> 0.6.4"},
{:con_cache, "~> 1.0"}
{:con_cache, "~> 1.1.0"}
]
end

Expand Down
2 changes: 1 addition & 1 deletion mix.lock
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"combination": {:hex, :combination, "0.0.3", "746aedca63d833293ec6e835aa1f34974868829b1486b1e1cb0685f0b2ae1f41", [:mix], [], "hexpm", "72b099f463df42ef7dc6371d250c7070b57b6c5902853f69deb894f79eda18ca"},
"combine": {:hex, :combine, "0.10.0", "eff8224eeb56498a2af13011d142c5e7997a80c8f5b97c499f84c841032e429f", [:mix], [], "hexpm", "1b1dbc1790073076580d0d1d64e42eae2366583e7aecd455d1215b0d16f2451b"},
"comeonin": {:hex, :comeonin, "5.4.0", "246a56ca3f41d404380fc6465650ddaa532c7f98be4bda1b4656b3a37cc13abe", [:mix], [], "hexpm", "796393a9e50d01999d56b7b8420ab0481a7538d0caf80919da493b4a6e51faf1"},
"con_cache": {:hex, :con_cache, "1.0.0", "6405e2bd5d5005334af72939432783562a8c35a196c2e63108fe10bb97b366e6", [:mix], [], "hexpm", "4d1f5cb1a67f3c1a468243dc98d10ac83af7f3e33b7e7c15999dc2c9bc0a551e"},
"con_cache": {:hex, :con_cache, "1.1.0", "45c7c6cd6dc216e47636232e8c683734b7fe293221fccd9454fa1757bc685044", [:mix], [{:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "8655f2ae13a1e56c8aef304d250814c7ed929c12810f126fc423ecc8e871593b"},
"cors_plug": {:hex, :cors_plug, "3.0.3", "7c3ac52b39624bc616db2e937c282f3f623f25f8d550068b6710e58d04a0e330", [:mix], [{:plug, "~> 1.13", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "3f2d759e8c272ed3835fab2ef11b46bddab8c1ab9528167bd463b6452edf830d"},
"cowboy": {:hex, :cowboy, "2.10.0", "ff9ffeff91dae4ae270dd975642997afe2a1179d94b1887863e43f681a203e26", [:make, :rebar3], [{:cowlib, "2.12.1", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "3afdccb7183cc6f143cb14d3cf51fa00e53db9ec80cdcd525482f5e99bc41d6b"},
"cowboy_telemetry": {:hex, :cowboy_telemetry, "0.4.0", "f239f68b588efa7707abce16a84d0d2acf3a0f50571f8bb7f56a15865aae820c", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7d98bac1ee4565d31b62d59f8823dfd8356a169e7fcbb83831b8a5397404c9de"},
Expand Down
45 changes: 0 additions & 45 deletions test/plausible/cache/stats_test.exs

This file was deleted.

0 comments on commit 68b17db

Please sign in to comment.