Hi Everyone,
I’m new to Elixir and programming in general. I’m attempting to make it through the Elixir-Lang guide and currently I’m up to http://elixir-lang.org/getting-started/mix-otp/supervisor-and-application.html.
Basically I’m creating a supervisor to setup monitoring that will alert the registry if there are any crashes or stopped buckets. I have implemented the code required (from the guide) to pass the test below. However, I still get the following error that I received before I added the Supervisor.ex page.
1) test removes buckets on exit (KV.RegistryTest)
test/registry_test.exs:9
Assertion with == failed
code: KV.Registry.lookup(registry, "shopping") == :error
left: {:ok, #PID<0.146.0>}
right: :error
stacktrace:
test/registry_test.exs:13: (test)
..
Finished in 0.09 seconds
4 tests, 1 failure
Any suggestions?
Here are the files I have:
registry.ex
defmodule KV.Registry do
use GenServer
## Client API
@doc """
Starts the registry with the given 'name.
"""
def start_link(name) do
GenServer.start_link(__MODULE__, :ok, name: name)
end
@doc """
Looks up the bucket pid for 'name' stored in 'server'.
Returns `{:ok, oid}` if the bucket exists, `:error` otherwise.
"""
def lookup(server, name) do
GenServer.call(server, {:lookup, name})
end
@doc """
ensures there is a bucket associated to the given 'name' in 'server'
"""
def create(server, name) do
GenServer.cast(server, {:create, name})
end
## Server Callbacks
def init(:ok) do
names = %{}
refs = %{}
{:ok, {names, refs}}
end
def handle_call({:lookup, name}, _from, {names, _} = state) do
{:reply, Map.fetch(names, name), state}
end
def handle_cast({:create, name}, {names, refs}) do
if Map.has_key?(names, name) do
{:noreply, {names, refs}}
else
{:ok, pid} = KV.Bucket.start_link
ref = Process.monitor(pid)
refs = Map.put(refs, ref, pid)
names = Map.put(names, name, pid)
{:noreply, {names, refs}}
end
end
def handle_info({:DOWN, ref, :process, _pid, _reason}, {names, refs}) do
{name, refs} = Map.pop(refs, ref)
names = Map.delete(names, name)
{:noreply, {names, refs}}
end
def handle_info(_msg, state) do
{:noreply, state}
end
end
registry_test.exs
defmodule KV.RegistryTest do
use ExUnit.Case, async: true
setup context do
{:ok, registry} = KV.Registry.start_link(context.test)
{:ok, registry: registry}
end
test "removes buckets on exit", %{registry: registry} do
KV.Registry.create(registry, "shopping")
{:ok, bucket} = KV.Registry.lookup(registry, "shopping")
Agent.stop(bucket)
assert KV.Registry.lookup(registry, "shopping") == :error
KV.Registry.create(registry, "shopping")
assert {:ok, bucket} = KV.Registry.lookup(registry, "shopping")
KV.Bucket.put(bucket, "milk", 1)
assert KV.Bucket.get(bucket, "milk") ==1
end
end
supervisor.ex
defmodule KV.Supervisor do
use Supervisor
def start_link do
Supervisor.start_link(__MODULE__, :ok)
end
def init(:ok) do
children = [
worker(KV.Registry, [KV.Registry])
]
supervise(children, strategy: :one_for_one)
end
end