Не удалось запустить дочерний процесс RedisClientSupervisor - Elixir + Phoenix - PullRequest
2 голосов
/ 16 мая 2019

Я запускаю приложение с Elixir 1.7.2 и Phoenix, но оно случайно зависало с ошибками в одном из моих дочерних процессов.

Я использую модуль с именем redix - {:redix, ">= 0.6.1"}который обрабатывает мою связь с Redis.

Сбой произошел со следующей ошибкой:

2019-05-16T07:29:08.929601+00:00 app[web.1]: 07:29:08.929 [info] Running ReviewedoWeb.Endpoint with Cowboy using http://:::46402
2019-05-16T07:29:09.191365+00:00 app[web.1]: 07:29:09.191 [info] Application reviewedo exited: Reviewedo.Application.start(:normal, []) returned an error: shutdown: failed to start child: Reviewedo.RedisClientSupervisor
2019-05-16T07:29:09.191385+00:00 app[web.1]: ** (EXIT) shutdown: failed to start child: Reviewedo.Accounts.Cache
2019-05-16T07:29:09.191387+00:00 app[web.1]: ** (EXIT) an exception was raised:
2019-05-16T07:29:09.191393+00:00 app[web.1]: ** (ArgumentError) the user in the Redis URI is ignored and should not be present, got: "h"
2019-05-16T07:29:09.191394+00:00 app[web.1]: (redix) lib/redix/uri.ex:30: Redix.URI.password/1
2019-05-16T07:29:09.191396+00:00 app[web.1]: (redix) lib/redix/uri.ex:15: Redix.URI.opts_from_uri/1
2019-05-16T07:29:09.191397+00:00 app[web.1]: (redix) lib/redix.ex:290: Redix.start_link/2
2019-05-16T07:29:09.191398+00:00 app[web.1]: (stdlib) supervisor.erl:365: :supervisor.do_start_child/2
2019-05-16T07:29:09.191399+00:00 app[web.1]: (stdlib) supervisor.erl:348: :supervisor.start_children/3
2019-05-16T07:29:09.191400+00:00 app[web.1]: (stdlib) supervisor.erl:314: :supervisor.init_children/2
2019-05-16T07:29:09.191402+00:00 app[web.1]: (stdlib) gen_server.erl:365: :gen_server.init_it/2
2019-05-16T07:29:09.191403+00:00 app[web.1]: (stdlib) gen_server.erl:333: :gen_server.init_it/6
2019-05-16T07:29:10.716373+00:00 app[web.1]: {"Kernel pid terminated",application_controller,"{application_start_failure,reviewedo,{{shutdown,{failed_to_start_child,'Elixir.Reviewedo.RedisClientSupervisor',{shutdown,{failed_to_start_child,'Elixir.Reviewedo.Accounts.Cache',{'EXIT',{#{'__exception__' => true,'__struct__' => 'Elixir.ArgumentError',message => <<\"the user in the Redis URI is ignored and should not be present, got: \\"h\\"\">>},[{'Elixir.Redix.URI',password,1,[{file,\"lib/redix/uri.ex\"},{line,30}]},{'Elixir.Redix.URI',opts_from_uri,1,[{file,\"lib/redix/uri.ex\"},{line,15}]},{'Elixir.Redix',start_link,2,[{file,\"lib/redix.ex\"},{line,290}]},{supervisor,do_start_child,2,[{file,\"supervisor.erl\"},{line,365}]},{supervisor,start_children,3,[{file,\"supervisor.erl\"},{line,348}]},{supervisor,init_children,2,[{file,\"supervisor.erl\"},{line,314}]},{gen_server,init_it,2,[{file,\"gen_server.erl\"},{line,365}]},{gen_server,init_it,6,[{file,\"gen_server.erl\"},{line,333}]}]}}}}}},{'Elixir.Reviewedo.Application',start,[normal,[]]}}}"}
2019-05-16T07:29:10.717128+00:00 app[web.1]: Kernel pid terminated (application_controller) ({application_start_failure,reviewedo,{{shutdown,{failed_to_start_child,'Elixir.Reviewedo.RedisClientSupervisor',{shutdown,{failed_to_start_child,'Elixir
2019-05-16T07:29:10.719206+00:00 app[web.1]: 
2019-05-16T07:29:13.269465+00:00 heroku[web.1]: State changed from up to crashed
2019-05-16T07:29:13.189754+00:00 app[web.1]: Crash dump is being written to: erl_crash.dump...done
2019-05-16T07:29:13.256383+00:00 heroku[web.1]: Process exited with status 1

Я не внес никаких изменений в исходный код до сбоя, и поэтому я не уверен, в чем причина.

Я вижу следующую ошибку: https://github.com/whatyouhide/redix/blob/master/lib/redix/uri.ex#L31

Похоже, что он пытается разделить мой redis_url, чтобы получить пользователя и пароль, но он придумывает h для пользователя.redis_url, который был сгенерирован для меня, выглядит примерно так:

redis://h:pf851f7d83mf93nrand0mha5hsh8kgl3h4334k73d82580bba59d4c237f33f24752c76c@ec2-45-81-27-450.region.compute.amazonaws.com:18324

Вот модули, на которых он выдает ошибку:

defmodule Reviewedo.RedisClientSupervisor do
  @moduledoc """
  Initiates Redis
  """
  use Supervisor
  alias Reviewedo.Accounts.Cache

  def start_link do
    Supervisor.start_link(__MODULE__, [])
  end

  def init(_) do
    redis_url = System.get_env("REDIS_URL") || "redis://127.0.0.1:6379"

    children = [
      worker(Cache, [redis_url, :redix], [])
    ]

    supervise(children, strategy: :one_for_one)
  end
end
defmodule Reviewedo.Accounts.Cache do
  @moduledoc """
  Provides cache functionality
  """

  def start_link(connection, name) do
    Redix.start_link(connection, name: name)
  end

  def query(param), do: Redix.command(:redix, param)

  def get(key), do: query(["get", key])
  def set(key, value), do: query(["set", key, value])
  def expire(key, seconds), do: query(["expire", key, seconds])
  def del(key), do: query(["del", key])

  def all_keys!() do
    case query(["keys", "*"]) do
      {:ok, keys} -> keys
      _ -> raise Reviewedo.RedisConnectionError, query: "all_keys!/1"
    end
  end

  def flushdb do
    query(["flushdb"])
    :ok
  end
end

defmodule Reviewedo.RedisConnectionError do
  @moduledoc """
  Raised when a Cache query returns an error

  This exception is raised by `Reviewedo.Accounts.Cache` and `Reviewedo.Accounts.CacheAPI` which:
  """

  defexception [:message]

  def exception(query: query) do
    msg = "Redis connection error, calling query: `#{query}`"
    %Reviewedo.RedisConnectionError{message: msg}
  end
end

Похоже, он не может получить мой opts от uri, но я не совсем уверен, почему.Приложение работает нормально локально, поэтому оно должно быть как-то связано с конфигурацией Heroku.

Кто-нибудь сталкивался с чем-то подобным ранее или знает, в чем может быть проблема?

Заранее спасибо!

...