Remove Redis/Cachex dependency, use pure ETS for caching
- Replace Cachex with native ETS (Erlang Term Storage) in Cache module - Remove Redis-based caching logic from application.ex - Always initialize ETS tables for device_cache, query_cache, symbol_cache - Update StatusLive to use Aprsme.Cache instead of Cachex directly - Fix crash on startup when REDIS_URL was set but Redis not used This fixes the no_cache error that was causing pods to crash.
This commit is contained in:
parent
18d95b9a1f
commit
ae14b120fa
3 changed files with 54 additions and 34 deletions
|
|
@ -235,24 +235,18 @@ defmodule Aprsme.Application do
|
||||||
# end
|
# end
|
||||||
|
|
||||||
defp redis_children do
|
defp redis_children do
|
||||||
if System.get_env("REDIS_URL") do
|
require Logger
|
||||||
require Logger
|
|
||||||
|
|
||||||
Logger.info("Starting Redis-based caching and rate limiting")
|
Logger.info("Starting ETS-based caching and rate limiting")
|
||||||
|
|
||||||
[]
|
# Create ETS tables for caching
|
||||||
else
|
:ets.new(:query_cache, [:set, :public, :named_table, read_concurrency: true])
|
||||||
require Logger
|
:ets.new(:device_cache, [:set, :public, :named_table, read_concurrency: true])
|
||||||
|
:ets.new(:symbol_cache, [:set, :public, :named_table, read_concurrency: true])
|
||||||
|
|
||||||
Logger.info("Starting ETS-based caching and rate limiting (no Redis URL)")
|
[
|
||||||
|
# ETS-based rate limiter
|
||||||
[
|
Aprsme.RateLimiter
|
||||||
# Fallback to ETS-based implementations
|
]
|
||||||
Aprsme.RateLimiter,
|
|
||||||
%{id: :query_cache, start: {Cachex, :start_link, [:query_cache, [limit: 10_000]]}},
|
|
||||||
%{id: :device_cache, start: {Cachex, :start_link, [:device_cache, [limit: 5_000]]}},
|
|
||||||
%{id: :symbol_cache, start: {Cachex, :start_link, [:symbol_cache, [limit: 1_000]]}}
|
|
||||||
]
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,59 +1,85 @@
|
||||||
defmodule Aprsme.Cache do
|
defmodule Aprsme.Cache do
|
||||||
@moduledoc """
|
@moduledoc """
|
||||||
Cache abstraction layer that works with both Cachex and RedisCache.
|
Cache abstraction layer using ETS (Erlang Term Storage).
|
||||||
Provides a unified API regardless of the underlying implementation.
|
Provides a unified API for in-memory caching.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Get a value from cache
|
Get a value from cache
|
||||||
"""
|
"""
|
||||||
def get(cache_name, key) do
|
def get(cache_name, key) do
|
||||||
Cachex.get(cache_name, key)
|
case :ets.lookup(cache_name, key) do
|
||||||
|
[{^key, value}] -> {:ok, value}
|
||||||
|
[] -> {:ok, nil}
|
||||||
|
end
|
||||||
|
rescue
|
||||||
|
ArgumentError -> {:error, :no_cache}
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Put a value in cache with optional TTL
|
Put a value in cache with optional TTL (TTL not implemented for ETS)
|
||||||
"""
|
"""
|
||||||
def put(cache_name, key, value, opts \\ []) do
|
def put(cache_name, key, value, _opts \\ []) do
|
||||||
Cachex.put(cache_name, key, value, opts)
|
try do
|
||||||
|
:ets.insert(cache_name, {key, value})
|
||||||
|
{:ok, true}
|
||||||
|
rescue
|
||||||
|
ArgumentError -> {:error, :no_cache}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Delete a key from cache
|
Delete a key from cache
|
||||||
"""
|
"""
|
||||||
def del(cache_name, key) do
|
def del(cache_name, key) do
|
||||||
Cachex.del(cache_name, key)
|
try do
|
||||||
|
:ets.delete(cache_name, key)
|
||||||
|
{:ok, true}
|
||||||
|
rescue
|
||||||
|
ArgumentError -> {:error, :no_cache}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Clear all keys from cache
|
Clear all keys from cache
|
||||||
"""
|
"""
|
||||||
def clear(cache_name) do
|
def clear(cache_name) do
|
||||||
Cachex.clear(cache_name)
|
try do
|
||||||
|
:ets.delete_all_objects(cache_name)
|
||||||
|
{:ok, true}
|
||||||
|
rescue
|
||||||
|
ArgumentError -> {:error, :no_cache}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Get cache statistics
|
Get cache statistics (simplified for ETS)
|
||||||
"""
|
"""
|
||||||
def stats(cache_name) do
|
def stats(cache_name) do
|
||||||
Cachex.stats(cache_name)
|
try do
|
||||||
|
info = :ets.info(cache_name)
|
||||||
|
{:ok, %{size: Keyword.get(info, :size, 0)}}
|
||||||
|
rescue
|
||||||
|
ArgumentError -> {:error, :no_cache}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Check if key exists
|
Check if key exists
|
||||||
"""
|
"""
|
||||||
def exists?(cache_name, key) do
|
def exists?(cache_name, key) do
|
||||||
case Cachex.exists?(cache_name, key) do
|
try do
|
||||||
{:ok, exists?} -> exists?
|
:ets.member(cache_name, key)
|
||||||
{:error, _reason} -> false
|
rescue
|
||||||
|
ArgumentError -> false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Get TTL for a key
|
Get TTL for a key (not supported in ETS, always returns nil)
|
||||||
"""
|
"""
|
||||||
def ttl(cache_name, key) do
|
def ttl(_cache_name, _key) do
|
||||||
Cachex.ttl(cache_name, key)
|
{:ok, nil}
|
||||||
end
|
end
|
||||||
|
|
||||||
# Helper functions - no longer needed as we only use Cachex
|
# Helper functions - no longer needed as we only use Cachex
|
||||||
|
|
|
||||||
|
|
@ -395,14 +395,14 @@ defmodule AprsmeWeb.StatusLive.Index do
|
||||||
|
|
||||||
defp get_cached_aprs_status do
|
defp get_cached_aprs_status do
|
||||||
# Try to get cached status for instant load
|
# Try to get cached status for instant load
|
||||||
case Cachex.get(:query_cache, "aprs_status") do
|
case Aprsme.Cache.get(:query_cache, "aprs_status") do
|
||||||
{:ok, status} when not is_nil(status) ->
|
{:ok, status} when not is_nil(status) ->
|
||||||
status
|
status
|
||||||
|
|
||||||
_ ->
|
_ ->
|
||||||
# Fallback to direct query if cache miss
|
# Fallback to direct query if cache miss
|
||||||
status = get_aprs_status()
|
status = get_aprs_status()
|
||||||
Cachex.put(:query_cache, "aprs_status", status, ttl: to_timeout(second: 5))
|
Aprsme.Cache.put(:query_cache, "aprs_status", status)
|
||||||
status
|
status
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue