118 lines
2.9 KiB
Elixir
118 lines
2.9 KiB
Elixir
defmodule Aprsme.CachedQueries do
|
|
@moduledoc """
|
|
Caching layer for database queries to improve performance
|
|
"""
|
|
|
|
alias Aprsme.Packets
|
|
|
|
# 2 minutes for frequently changing data
|
|
@cache_ttl_short to_timeout(minute: 2)
|
|
# 15 minutes for moderately changing data
|
|
@cache_ttl_medium to_timeout(minute: 15)
|
|
|
|
@doc """
|
|
Get recent packets with caching
|
|
"""
|
|
def get_recent_packets_cached(opts) do
|
|
cache_key = generate_cache_key("recent_packets", opts)
|
|
|
|
case Cachex.get(:query_cache, cache_key) do
|
|
{:ok, result} when not is_nil(result) ->
|
|
result
|
|
|
|
_ ->
|
|
result = Packets.get_recent_packets_optimized(opts)
|
|
Cachex.put(:query_cache, cache_key, result, ttl: @cache_ttl_short)
|
|
result
|
|
end
|
|
end
|
|
|
|
@doc """
|
|
Get weather packets with caching
|
|
"""
|
|
def get_weather_packets_cached(callsign, start_time, end_time, opts) do
|
|
cache_key = generate_cache_key("weather", {callsign, start_time, end_time, opts})
|
|
|
|
case Cachex.get(:query_cache, cache_key) do
|
|
{:ok, result} when not is_nil(result) ->
|
|
result
|
|
|
|
_ ->
|
|
result = Packets.get_weather_packets(callsign, start_time, end_time, opts)
|
|
Cachex.put(:query_cache, cache_key, result, ttl: @cache_ttl_medium)
|
|
result
|
|
end
|
|
end
|
|
|
|
@doc """
|
|
Get packet count with caching
|
|
"""
|
|
def get_total_packet_count_cached do
|
|
cache_key = "total_packet_count"
|
|
|
|
case Cachex.get(:query_cache, cache_key) do
|
|
{:ok, result} when not is_nil(result) ->
|
|
result
|
|
|
|
_ ->
|
|
result = Packets.get_total_packet_count()
|
|
Cachex.put(:query_cache, cache_key, result, ttl: @cache_ttl_medium)
|
|
result
|
|
end
|
|
end
|
|
|
|
@doc """
|
|
Get latest packet for callsign with caching
|
|
"""
|
|
def get_latest_packet_for_callsign_cached(callsign) do
|
|
cache_key = generate_cache_key("latest_packet", callsign)
|
|
|
|
case Cachex.get(:query_cache, cache_key) do
|
|
{:ok, result} when not is_nil(result) ->
|
|
result
|
|
|
|
_ ->
|
|
result = Packets.get_latest_packet_for_callsign(callsign)
|
|
# Shorter TTL for latest packets as they change frequently
|
|
Cachex.put(:query_cache, cache_key, result, ttl: @cache_ttl_short)
|
|
result
|
|
end
|
|
end
|
|
|
|
@doc """
|
|
Invalidate cache entries for a specific callsign
|
|
"""
|
|
def invalidate_callsign_cache(callsign) do
|
|
# Pattern-based cache invalidation
|
|
patterns = [
|
|
"latest_packet:#{callsign}",
|
|
"weather:#{callsign}:*"
|
|
]
|
|
|
|
Enum.each(patterns, fn pattern ->
|
|
Cachex.del(:query_cache, pattern)
|
|
end)
|
|
end
|
|
|
|
@doc """
|
|
Invalidate all cached queries
|
|
"""
|
|
def invalidate_all_cache do
|
|
Cachex.clear(:query_cache)
|
|
end
|
|
|
|
@doc """
|
|
Get cache statistics
|
|
"""
|
|
def get_cache_stats do
|
|
{:ok, stats} = Cachex.stats(:query_cache)
|
|
stats
|
|
end
|
|
|
|
# Private helper functions
|
|
|
|
defp generate_cache_key(prefix, data) do
|
|
hash = :erlang.phash2(data)
|
|
"#{prefix}:#{hash}"
|
|
end
|
|
end
|