View Source SimpleMemCache (simple_mem_cache v1.0.1)
In-memory key-value cache with expiration-time after creation/modification/access, automatic value loading and time travel support.
Prepare ETS table to be used by SimpleMemCache
Example 1: plain ETS:
tid = :ets.new(__MODULE__, [:set,
:public,
{:read_concurrency, true},
{:write_concurrency, true}
])
Example 2: use Eternal to create the ETS table:
defmodule MyProject do
use Application
def start(_type, _args) do
import Supervisor.Spec, warn: false
Eternal.start_link(SimpleMemCache,
[:set,
{:read_concurrency, true},
{:write_concurrency, true}
])
Only ETS types: set and ordered_set are supported.
Usage
Keep in cache for a limited time, automatically load new value after that
Example: scrape news and keep it 10 minutes in cache
us_news = SimpleMemCache.cache(SimpleMemCache, "news_us", 10, &Scraper.scrape_news_us/0)
or with anonymous function:
def news(country) do SimpleMemCache.cache(SimpleMemCache, "news_" <> country, 10, fn -> Scraper.scrape_news(country) end) end
Note about automatically new value loading:
- How long does this function take to get the new value, and is this acceptable when the old value is expired? If it takes too long, consider to use an scheduler to regularly recalculate the new value and update the cache with that.
Keep in cache for a limited time but extend life-time everytime it is accessed
Example: cache http response of countries rest service for at least 20 minutes
countries_response = SimpleMemCache.cache(SimpleMemCache, "countries_response", 20, true, fn -> HTTPoison.get! "http://restcountries.eu/rest/v1/" end)
Keep as long as the ETS table exists
Example: Cache products retrieved from csv file. Not a good example, because nowadays files are stored on SSD and there will be no performance gain.
products = SimpleMemCache.cache(SimpleMemCache, "products", fn -> "products.csv" |> File.stream! |> CSV.parse_stream |> Enum.to_list end)
updates are still possible:
SimpleMemCache.put(SimpleMemCache, "products", new_value)
or you can force an automatically load at first access by invalidating the cached item.
Invalidate cached item
Example: remove products from cache
old_value = SimpleMemCache.remove(SimpleMemCache, "products")
Summary
Functions
Cache value returned by the supplied function.
Get status and value of cached item. Status can be :ok, :expired or :not_cached
Get value of cached item. Nil if is not cached or when value is nil.
Returns function that generates Unix/Posix UTC time in seconds.
Create or update an item in cache.
Remove an item from cache. Returns the value of the removed object.
Remove expired entries. This is automatically called once a minute during SimpleMemCache usage.
Time travel for SimpleMemCache.
Delete the ETS table.
Types
The table id (Tid) or table name
Functions
cache(table, key, minutes_valid \\ nil, keep_alive \\ false, f_new_value)
View SourceCache value returned by the supplied function.
table
- Name of the ETS table.key
- Key nameminutes_valid
- Minutes to keep the item in cache. Default: nil - do not expire.keep_alive
- Keep the item in cache if it still accessed. It expires if it is not retrieved inminutes_valid
minutes. Default: falsef_new_value
- function that supplies the value. Enables automatic value loading. Whenminutes_valid
is not nil andkeep_alive
is false, this function can be launched in a new Erlang process, and it can do this proactively up to 30 seconds before expiration.
Examples
products = SimpleMemCache.cache(SimpleMemCache, "products", 30, true,
fn() -> File.read!(filename) end
)
news_page = SimpleMemCache.cache(SimpleMemCache, "news", 10, &scrape_news/0)
Get status and value of cached item. Status can be :ok, :expired or :not_cached
The minutes_keep_alive
parameter is the number of minutes to keep the item at least in cache.
Does not shorten a previously set expiration time (use put for that). However,
if there wasn't an expiration time it will take the new value. Default: nil - do not change the expire time.
Example
iex(1)> products = SimpleMemCache.get(SimpleMemCache, "products", 20)
{:expired, "Fret dots"}
Get value of cached item. Nil if is not cached or when value is nil.
Returns function that generates Unix/Posix UTC time in seconds.
Create or update an item in cache.
Remove an item from cache. Returns the value of the removed object.
@spec remove_expired_entries(table()) :: :ok
Remove expired entries. This is automatically called once a minute during SimpleMemCache usage.
Time travel for SimpleMemCache.
The f_system_time
parameter is meant for time travel support.
You can provide a function that returns the Unix/Posix UTC time in seconds.
Set nil to restore the normal system time.
@spec stop(table()) :: :ok
Delete the ETS table.