Supervisor code from Elixir's Getting Started guides issue

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
1 Like