Search code examples
elixirelixir-mix

Issue with simple elixir/mix project


Im learning Elixir and trying to compose a SIMPLE elixir hello world example but I keep running into this error when I do "mix run"

 (Mix) Could not start application collector:
       Collector.start(:normal, []) returned an error:
       shutdown: failed to start child: Collector.Sample
(EXIT) nil

What am I doing wrong? Here is my code minus the mix.exs and other non-critical files

defmodule Collector do
  use Application

  def start(_type, _args) do
    Collector.Supervisor.start_link
  end
end

defmodule Collector.Supervisor do
  use Supervisor

  def start_link do
    Supervisor.start_link(__MODULE__, :ok)
  end

  def init(:ok) do
    children = [
      supervisor(Collector.Sample, [])
    ]

    supervise(children, strategy: :one_for_one)
  end
end

defmodule Collector.Sample do
  use Application

  def start_link do

  end

  def run do
    IO.puts "Hello World"
  end

end

I just wanna dump "Hello World" when I run "mix run" in the console and I dont know how or where to call the run() method. Thank you


Solution

  • If you want to build a command line app maybe this blog post will help you.

    Other than that, supervisors are typically not used to run one-off processes, but rather to start workers like GenServers that can later be called. For example you could:

    defmodule Collector.Supervisor do
      # ...
    
      def init(:ok) do
        children = [
          worker(Collector.Sample, [])
        ]
    
        supervise(children, strategy: :one_for_one)
      end
    end
    

    Then implement Collector.Sample as GenServer:

    defmodule Collector.Sample do
      use GenServer
    
      # Client API
    
      def start_link do
        GenServer.start_link(__MODULE__, [], name: __MODULE__)
      end
    
      def run do
        GenServer.call __MODULE__, :run
      end
    
      # GenServer callbacks
    
      def handle_call(:run, _from, state) do
        IO.puts "Hello World"
        {:reply, :ok, state}
      end
    end
    

    You can call the run method directly from mix run with the -e flag

    mix run -e 'Collector.Sample.run'