2015-07-03 3 views
3

Я не уверен, что я делаю неправильно, но я создал приложение эликсира, если я запускаю его:Мое приложение запускается, но он заканчивается сразу

iex -S mix 

приложение загружает супервайзер, руководитель загрузить gen_server, который подключается к RabbitMQ и прислушивался для сообщений, но если я запустить приложение с

mix app.start 

или

mix run 

супервизор загружен, работник запускается и подключается к RabbitMQ но заканчивается сразу же без каких-либо ошибок, примеры кода:

mix.exs

defmodule Sample.Mixfile do 
    use Mix.Project 

    def project do 
    [app: :sample, 
    version: "0.0.1", 
    elixir: "~> 1.0", 
    build_embedded: Mix.env == :prod, 
    start_permanent: Mix.env == :prod, 
    deps: deps] 
    end 

    # Configuration for the OTP application 
    # 
    # Type `mix help compile.app` for more information 
    def application do 
    [applications: [:logger, :rabbit_common, :ssl, :erlcloud, :amqp], 
    mod: {Sample, []}] 
    end 

    # Dependencies can be Hex packages: 
    # 
    # {:mydep, "~> 0.3.0"} 
    # 
    # Or git/path repositories: 
    # 
    # {:mydep, git: "https://github.com/elixir-lang/mydep.git", tag: "0.1.0"} 
    # 
    # Type `mix help deps` for more examples and options 
    defp deps do 
    [ 
     {:erlcloud, git: "https://github.com/gleber/erlcloud" }, 
     {:amqp, "~> 0.1.1"} 
    ] 
    end 
end 

sample.ex файл

defmodule Sample do 
    use Application 
    require Logger 

    def start(_type, _args) do 
    IO.puts("Starting App") 
    Sample.Supervisor.start_link 
    end 
end 

supervisor.ex

defmodule Sample.Supervisor do 
    use Supervisor 

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

    def init(:ok) do 
    children = [ 
     worker(Sample.Worker, [[name: :sample_worker]]) 
    ] 

    # one_for_one: If one process dies, the supervisor restarts it without affecting the others 
    supervise(children, strategy: :one_for_one) 
    end 
end 

и worker.ex

defmodule Sample.Worker do 
    use GenServer 
    use AMQP 

    @exchange "exchange_name" 
    @queue  "queue_name" 

    ### Client API 

    @doc """ 
    Starts the worker who consumes rabbitmq messages on exchange @exchange 
    """ 
    def start_link(opts \\ []) do 
    GenServer.start_link(__MODULE__, :ok, opts) 
    end 

    def stop do 
    GenServer.cast(__MODULE__, :stop) 
    end 

    ### Server Callbacks 

    def init(:ok) do 
    {:ok, connection} = Connection.open 
    {:ok, channel} = Channel.open(connection) 
    Queue.declare(channel, @queue, durable: true, arguments: []) 
    Exchange.direct(channel, @exchange, durable: true) 
    Queue.bind(channel, @queue, @exchange) 

    # Register the GenServer process as a consumer 
    {:ok, _consumer_tag} = Basic.consume(channel, @queue) 
    {:ok, channel} 
    end 

    # Confirmation sent by the broker after registering this process as a consumer 
    def handle_info({:basic_consume_ok, %{consumer_tag: consumer_tag}}, channel) do 
    IO.puts("#{__MODULE__} consumer connected") 
    {:noreply, channel} 
    end 

    # Sent by the broker when the consumer is unexpectedly cancelled (such as after a queue deletion) 
    def handle_info({:basic_cancel, %{consumer_tag: consumer_tag}}, channel) do 
    IO.puts("#{__MODULE__} consumer unexpectedly cancelled") 
    {:stop, :normal, channel} 
    end 

    # Confirmation sent by the broker to the consumer process after a Basic.cancel 
    def handle_info({:basic_cancel_ok, %{consumer_tag: consumer_tag}}, channel) do 
    IO.puts("#{__MODULE__} consumer Basic.cancel") 
    {:noreply, channel} 
    end 

    # Basic deliverying of a data package 
    def handle_info({:basic_deliver, payload, %{delivery_tag: tag, redelivered: redelivered}}, channel) do 
    spawn fn -> consume(channel, tag, redelivered, payload) end 
    {:noreply, channel} 
    end 

    # Catches all other messages   
    def handle_info(message, state) do 
    IO.puts("#{__MODULE__} handle_info called with #{message}") 
    {:noreply, state} 
    end 

    def handle_call(message, _from, state) do 
    IO.puts("#{__MODULE__} handle_call called with #{message}") 
    {:reply, :response, state} 
    end 

    def handle_cast(message, state) do 
    IO.puts("#{__MODULE__} handle_cast called with #{message}") 
    {:noreply, state} 
    end 

    ### Implementation 

    defp consume(channel, tag, redelivered, payload) do 
    try do 
     IO.puts("Consuming #{payload}") 
     Basic.ack channel, tag 
    rescue 
     exception -> 
     # Requeue unless it's a redelivered message.                           
     # This means we will retry consuming a message once in case of exception             
     # before we give up and have it moved to the error queue 
     Basic.reject channel, tag, requeue: not redelivered 
     IO.puts "Error received: #{exception}" 
    end 
    end 
end 

ответ

4

mix run - правильная команда. Как и elixir исполняемый файл, вам необходимо пройти --no-halt:

mix run --no-halt 
+0

Отлично работает, как ожидалось. Еще один вопрос, почему 'mix app.start -permanent' не продолжает работать, и вместо этого он запускается и заканчивается сразу? – rorra

+4

Поскольку '-permanent' не работает постоянно, это касается того, что произойдет, если ваше приложение выйдет из строя. –

+0

@ JoséValim Я столкнулся с той же проблемой. Если я хочу скомпилировать и запустить это приложение qs для развертываемого двоичного файла, что мне делать? У меня не будет микса или эликсира на другой машине, только мой двоичный файл. – svarlet

Смежные вопросы