Packages
phoenix_kit
1.7.31
1.7.207
1.7.206
1.7.205
1.7.204
1.7.203
1.7.202
1.7.201
1.7.200
1.7.199
1.7.198
1.7.197
1.7.196
1.7.194
1.7.193
1.7.192
1.7.191
1.7.190
1.7.189
1.7.187
1.7.186
1.7.185
1.7.184
1.7.183
1.7.182
1.7.181
1.7.180
1.7.179
1.7.178
1.7.177
1.7.176
1.7.175
1.7.174
1.7.173
1.7.172
1.7.171
1.7.170
1.7.169
1.7.168
1.7.167
1.7.166
1.7.165
1.7.164
1.7.162
1.7.161
1.7.160
1.7.159
1.7.157
1.7.156
1.7.155
1.7.154
1.7.153
1.7.152
1.7.151
1.7.150
1.7.149
1.7.146
1.7.145
1.7.144
1.7.143
1.7.138
1.7.133
1.7.132
1.7.131
1.7.130
1.7.128
1.7.126
1.7.125
1.7.121
1.7.120
1.7.119
1.7.118
1.7.117
1.7.116
1.7.115
1.7.114
1.7.113
1.7.112
1.7.111
1.7.110
1.7.109
1.7.108
1.7.107
1.7.106
1.7.105
1.7.104
1.7.103
1.7.102
1.7.101
1.7.100
1.7.99
1.7.98
1.7.97
1.7.96
1.7.95
1.7.94
1.7.93
1.7.92
1.7.91
1.7.90
1.7.89
1.7.88
1.7.87
1.7.86
1.7.85
1.7.84
1.7.83
1.7.82
1.7.81
1.7.80
1.7.79
1.7.78
1.7.77
1.7.76
1.7.75
1.7.74
1.7.71
1.7.70
1.7.69
1.7.66
1.7.65
1.7.64
1.7.63
1.7.62
1.7.61
1.7.59
1.7.58
1.7.57
1.7.56
1.7.55
1.7.54
1.7.53
1.7.52
1.7.51
1.7.49
1.7.44
1.7.43
1.7.42
1.7.41
1.7.39
1.7.38
1.7.37
1.7.36
1.7.34
1.7.33
1.7.31
1.7.30
1.7.29
1.7.28
1.7.27
1.7.26
1.7.25
1.7.24
1.7.23
1.7.22
1.7.21
1.7.20
1.7.19
1.7.18
1.7.17
1.7.16
1.7.15
1.7.14
1.7.13
1.7.12
1.7.11
1.7.10
1.7.9
1.7.8
1.7.7
1.7.6
1.7.5
1.7.4
1.7.3
1.7.2
1.7.1
1.7.0
1.6.20
1.6.19
1.6.18
1.6.17
1.6.16
1.6.15
1.6.14
1.6.13
1.6.12
1.6.11
1.6.10
1.6.9
1.6.8
1.6.7
1.6.6
1.6.5
1.6.4
1.6.3
1.5.2
1.5.1
1.5.0
1.4.9
1.4.8
1.4.7
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.2
1.3.1
1.3.0
1.2.10
1.2.9
1.2.8
1.2.7
1.2.5
1.2.4
1.2.2
1.2.1
1.2.0
1.1.0
1.0.0
A foundation for building Elixir Phoenix apps — SaaS, social networks, ERP systems, marketplaces, and more
Current section
Files
Jump to
Current section
Files
lib/modules/sitemap/cache.ex
defmodule PhoenixKit.Modules.Sitemap.Cache do
@moduledoc """
Caching layer for sitemap generation.
Manages both ETS cache (for entries/HTML) and file storage (for XML).
When invalidated, clears both ETS cache and deletes the sitemap file,
forcing regeneration on next request.
## Architecture
- **XML Storage**: File-based (`priv/static/sitemap.xml`)
- **Entries Cache**: ETS (in-memory, cleared on invalidate)
- **HTML Cache**: Generated on-demand, not persisted
## Usage
# Clear cache when content changes (deletes file + clears ETS)
Cache.invalidate()
# Check if ETS cache has entries
Cache.has?(:entries)
## Cache Keys
- `:entries` - Collected sitemap entries
- `:parts` - Sitemap index parts for large sitemaps
"""
alias PhoenixKit.Modules.Sitemap
alias PhoenixKit.Modules.Sitemap.FileStorage
@table_name :sitemap_cache
@doc """
Initializes the ETS cache table.
Creates a public named table with read concurrency for optimal performance.
Safe to call multiple times - returns :ok if table already exists.
## Examples
iex> Cache.init()
:ok
iex> Cache.init()
:ok # Idempotent
"""
@spec init() :: :ok
def init do
unless table_exists?() do
:ets.new(@table_name, [
:named_table,
:public,
:set,
read_concurrency: true,
write_concurrency: false
])
end
:ok
end
@doc """
Retrieves a cached value by key.
## Examples
iex> Cache.get(:xml)
{:ok, "<?xml version=..."}
iex> Cache.get(:nonexistent)
:error
"""
@spec get(atom()) :: {:ok, any()} | :error
def get(key) when is_atom(key) do
init()
case :ets.lookup(@table_name, key) do
[{^key, value}] -> {:ok, value}
[] -> :error
end
end
@doc """
Stores a value in cache with the given key.
## Examples
iex> Cache.put(:xml, xml_content)
:ok
iex> Cache.put(:html, html_content)
:ok
"""
@spec put(atom(), any()) :: :ok
def put(key, value) when is_atom(key) do
init()
:ets.insert(@table_name, {key, value})
:ok
end
@doc """
Clears all cached data and deletes the sitemap file.
Should be called when sitemap content changes (new pages, updated content, etc).
Next request to sitemap.xml will trigger fresh generation.
## Examples
iex> Cache.invalidate()
:ok
"""
@spec invalidate() :: :ok
def invalidate do
# Delete sitemap file (primary XML storage)
FileStorage.delete()
# Clear generation stats (last_generated, url_count)
# This indicates sitemap doesn't exist until regenerated
Sitemap.clear_generation_stats()
# Clear ETS caches
if table_exists?() do
# Clear entries (primary cache key)
:ets.delete(@table_name, :entries)
# Clear parts for sitemap index
:ets.delete(@table_name, :parts)
# Clear legacy keys for backward compatibility
:ets.delete(@table_name, :xml)
:ets.delete(@table_name, :html_table)
:ets.delete(@table_name, :html_cards)
:ets.delete(@table_name, :html_minimal)
:ets.delete(@table_name, :xml_table)
:ets.delete(@table_name, :xml_cards)
:ets.delete(@table_name, :xml_minimal)
end
:ok
end
@doc """
Checks if a cached value exists for the given key.
## Examples
iex> Cache.has?(:xml)
true
iex> Cache.has?(:nonexistent)
false
"""
@spec has?(atom()) :: boolean()
def has?(key) when is_atom(key) do
init()
case :ets.lookup(@table_name, key) do
[{^key, _}] -> true
[] -> false
end
end
@doc """
Deletes a specific cache entry.
## Examples
iex> Cache.delete(:xml)
:ok
"""
@spec delete(atom()) :: :ok
def delete(key) when is_atom(key) do
if table_exists?() do
:ets.delete(@table_name, key)
end
:ok
end
@doc """
Returns cache statistics.
## Examples
iex> Cache.stats()
%{size: 2, memory: 1024}
"""
@spec stats() :: map()
def stats do
if table_exists?() do
info = :ets.info(@table_name)
%{
size: Keyword.get(info, :size, 0),
memory: Keyword.get(info, :memory, 0)
}
else
%{size: 0, memory: 0}
end
end
# Private helpers
defp table_exists? do
:ets.whereis(@table_name) != :undefined
end
end