2 votes

La perte de la connexion AMQP ne tue pas le processus parent, donc la reconnexion n'a jamais lieu.

J'ai la fonction init de mon GenServer. Le superviseur s'en occupe, et doit le redémarrer à la sortie.

  def init(_opts) do
    username = get_conf(:username)
    password = get_conf(:password)
    host = get_conf(:host)
    port = get_conf(:port)
    vhost = String.replace(get_conf(:vhost), "/", "%2f")
    {:ok, conn} = Connection.open("amqp://#{username}:#{password}@#{host}:#{port}/#{vhost}")
    {:ok, chan} = Channel.open(conn)
    state = %State{
      exchange: get_conf(:exchange),
      channel: chan,
      routing_key: get_conf(:routing_key)
    }
    {:ok, state}
  end

Lorsque je redémarre RabbitMQ avec sudo service rabbitmq-server restart une nouvelle connexion n'est pas établie.

Dans la barre de débogage, je vois ce qui suit : enter image description here Lorsque je clique sur la connexion pid <0.417.0>, j'obtiens un message indiquant que le processus n'existe plus. Il semble que le processus soit mort et que le parent AmqpTransport Je ne sais rien de tout cela. Comment puis-je faire AmqpTransport mourir avec son enfant Connection ?

1voto

Rudziankoŭ Points 605

Je l'ai corrigé en ajoutant trapping exits et le lien vers Connection processus. De plus, je vérifie les erreurs pendant la connexion pour éviter reached_max_restart_intensity .

  @restart_delay 2000 # 2 seconds

  def init(_opts) do
    Process.flag(:trap_exit, true)
    send(self(), :connect)
    {:ok, nil}
  end

  def handle_info(:connect, state) do
    #...
    case Connection.open("amqp://#{username}:#{password}@#{host}:#{port}/#{vhost}") do
      {:ok, conn} ->
        Process.link(conn.pid)
        # ...
        {:noreply, state}
      {:error, :econnrefused} ->
        Logger.error("amqp transport failed with connection refused")
        Process.send_after(self(), :connect, @restart_delay)
        {:noreply, nil}
    end

  end

  def handle_info({:EXIT, pid, reason}, state) do
    Logger.error("amqp transport failed with #{inspect(reason)}")
    Process.unlink(pid)
    Process.send_after(self(), :connect, @restart_delay)
    {:noreply, nil}
  end

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X