您可以使用ETS來緩存昂貴的計算。這裏的東西我最近寫的,它可能不是一個全面的緩存解決方案,但它工作得很好,對我來說:
defmodule Cache do
@table __MODULE__
def start do
:ets.new @table, [:named_table, read_concurrency: true]
end
def fetch(key, expires_in_seconds, fun) do
case lookup(key) do
{:hit, value} ->
value
:miss ->
value = fun.()
put(key, expires_in_seconds, value)
value
end
end
defp lookup(key) do
case :ets.lookup(@table, key) do
[{^key, expires_at, value}] ->
case now < expires_at do
true -> {:hit, value}
false -> :miss
end
_ ->
:miss
end
end
defp put(key, expires_in_seconds, value) do
expires_at = now + expires_in_seconds
:ets.insert(@table, {key, expires_at, value})
end
defp now do
:erlang.system_time(:seconds)
end
end
首先,你需要調用Cache.start
的地方,所以ETS表將被創建(例如你的應用程序的start
函數)。然後你可以使用它像這樣:
value = Cache.fetch cache_key, expires_in_seconds, fn ->
# expensive computation
end
例如:
Enum.each 1..100000, fn _ ->
message = Cache.fetch :slow_hello_world, 1, fn ->
:timer.sleep(1000) # expensive computation
"Hello, world at #{inspect :calendar.local_time}!"
end
IO.puts message
end