Packages
mongodb_driver
1.6.4
1.6.4
1.6.3
1.6.2
1.6.1
1.6.0
1.5.6
1.5.5
1.5.4
1.5.2
1.5.1
1.5.0
1.4.1
1.4.0
1.2.1
1.2.0
1.1.0
1.0.3
1.0.2
1.0.1
1.0.0
0.9.2
0.9.1
0.9.0
0.9.0-rc.1
0.9.0-rc.0
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.4
0.7.3
0.7.2
0.7.1
0.7.0
0.6.5
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.7
0.5.6
0.5.5
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
The MongoDB driver for Elixir
Current section
Files
Jump to
Current section
Files
lib/mongo/pbkdf2_cache.ex
defmodule Mongo.PBKDF2Cache do
@moduledoc false
use GenServer
@name __MODULE__
def start_link(_ \\ nil) do
GenServer.start_link(__MODULE__, [], name: @name)
end
def pbkdf2(password, salt, iterations, digest) do
GenServer.call(@name, {password, salt, iterations, digest})
end
def init([]) do
{:ok, %{pending: %{}, cache: %{}}}
end
def handle_call(key, from, s) do
cond do
salted_password = s.cache[key] ->
{:reply, salted_password, s}
list = s.pending[key] ->
{:noreply, put_in(s.pending[key], [from | list])}
true ->
_ = run_task(key)
{:noreply, put_in(s.pending[key], [from])}
end
end
def handle_info({ref, {key, result}}, s) when is_reference(ref) do
Enum.each(s.pending[key], fn from ->
GenServer.reply(from, result)
end)
s = update_in(s.pending, &Map.delete(&1, key))
s = put_in(s.cache[key], result)
{:noreply, s}
end
def handle_info({:DOWN, _ref, :process, _pid, :normal}, s) do
{:noreply, s}
end
defp run_task({password, salt, iterations, :sha256} = key) do
Task.async(fn ->
result = Mongo.PBKDF2.generate(password, salt, iterations: iterations, length: 32, digest: :sha256)
{key, result}
end)
end
defp run_task({password, salt, iterations, :sha} = key) do
Task.async(fn ->
result = Mongo.PBKDF2.generate(password, salt, iterations: iterations, length: 20, digest: :sha)
{key, result}
end)
end
end