我不确定我做错了什么,但我创建了一个elixir应用程序,如果我运行它:
iex -S mix
应用程序加载主管,主管加载连接到rabbitmq的gen_server并继续监听消息,但是如果我用
运行应用程序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
答案 0 :(得分:5)
mix run
是正确的命令。与elixir
可执行文件一样,您需要传递--no-halt
:
mix run --no-halt