View Source Plausible.Site.Cache (Plausible v0.0.1)

A "sites by domain" caching interface.

Serves as a thin wrapper around Cachex, but the underlying implementation can be transparently swapped.

Even though the Cachex process is started, cache access is disabled during tests via the :sites_by_domain_cache_enabled application env key. This can be overridden on case by case basis, using the child specs options.

NOTE: the cache allows lookups by both domain and domain_changed_from fields - this is to allow traffic from sites whose domains changed within a certain grace period (see: Plausible.Site.Transfer).

When Cache is disabled via application env, the get/1 function falls back to pure database lookups. This should help with introducing cached lookups in existing code, so that no existing tests should break.

To differentiate cached Site structs from those retrieved directly from the database, a virtual schema field from_cache?: true is set. This indicates the Plausible.Site struct is incomplete in comparison to its database counterpart -- to spare bandwidth and query execution time, only selected database columns are retrieved and cached.

There are two modes of refreshing the cache: :all and :updated_recently.

  • :all means querying the database for all Site entries and should be done periodically (via Cache.Warmer). All stale Cache entries are cleared upon persisting the new batch.

  • :updated_recently attempts to re-query sites updated within the last 15 minutes only, to account for most recent changes. This refresh is lighter on the database and is meant to be executed more frequently (via Cache.Warmer.RecentlyUpdated).

Refreshing the cache emits telemetry event defined as per telemetry_event_refresh/2.

The @cached_schema_fields attribute defines the list of DB columns queried on each cache refresh.

Also see tests for more comprehensive examples.

Summary

Types

Functions

@spec child_spec(Keyword.t()) :: Supervisor.child_spec()
@spec get(String.t(), Keyword.t()) :: t() | nil
Link to this function

get_site_id(domain, opts \\ [])

View Source
@spec get_site_id(String.t(), Keyword.t()) :: pos_integer() | nil
Link to this function

hit_rate(cache_name \\ :sites_by_domain)

View Source
Link to this function

merge(new_items, opts \\ [])

View Source
@spec merge(new_items :: [Plausible.Site.t()], opts :: Keyword.t()) :: :ok
@spec name() :: atom()
Link to this function

ready?(cache_name \\ :sites_by_domain)

View Source
@spec ready?(atom()) :: boolean()

Ensures the cache has non-zero size unless no sites exist. Useful for orchestrating app startup to prevent the service going up asynchronously with an empty cache.

@spec refresh_all(Keyword.t()) :: :ok
Link to this function

refresh_updated_recently(opts \\ [])

View Source
@spec refresh_updated_recently(Keyword.t()) :: :ok
Link to this function

size(cache_name \\ :sites_by_domain)

View Source
Link to this function

telemetry_event_refresh(cache_name \\ :sites_by_domain, mode)

View Source
@spec telemetry_event_refresh(atom(), atom()) :: [atom()]
@spec touch_site!(Plausible.Site.t(), DateTime.t()) :: Plausible.Site.t()