Пример пула на основе имен в Elixir Redix - подпись супервизора не существует - PullRequest
0 голосов
/ 04 октября 2018

Так что у меня возникли проблемы следуя этому «супер простому» примеру.Впервые в Elixir (преимущественно из Ruby-фона).

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

This line:
start: {Supervisor, :start_link, [children_redix]}

 Gives me the following error:

** (Mix) Could not start application gametime: 
Gametime.Application.start(:normal, []) returned an error: shutdown: 
failed to start child: RedixSupervisor
** (EXIT) an exception was raised:
    ** (UndefinedFunctionError) function Supervisor.start_link/1 is undefined or private
        (elixir) Supervisor.start_link([%{id: {Redix, 0}, start: {Redix, :start_link, [[name: :redix_0]]}, type: :worker}, %{id: {Redix, 1}, start: {Redix, :start_link, [[name: :redix_1]]}, type: :worker}, %{id: {Redix, 2}, start: {Redix, :start_link, [[name: :redix_2]]}, type: :worker}, %{id: {Redix, 3}, start: {Redix, :start_link, [[name: :redix_3]]}, type: :worker}, %{id: {Redix, 4}, start: {Redix, :start_link, [[name: :redix_4]]}, type: :worker}])

, и если я уберу квадратные скобки из children_redix в приведенной выше строке, я получу:

 ** (UndefinedFunctionError) function Supervisor.start_link/5 is undefined or private

Thisэто следующая документация:

https://hexdocs.pm/redix/real-world-usage.html

Это функция запуска приложения:

   defmodule Gametime.Application do                                                            
      use Application                                                                            
      use Supervisor                                                                           


      def start(_type, _args) do                                                                 

        pool_size = 5                                                                            

        #creates redix children processes                                                                                   
        children_redix =                                                                         
          for i <- 0..(pool_size - 1) do                                                         
            Supervisor.child_spec({Redix, name: :"redix_#{i}"}, id: {Redix, i})                  
          end                                                                                    

        children = [                                                                             
          # child spec for the supervisor I am trying to add to the main supervision tree,                                                                                
          %{                                                                                     
            id: RedixSupervisor,                                                                 
            type: :supervisor,                                                                   
            start: {Supervisor, :start_link, [children_redix]}                                   
          },                                                                                     

          # This way is now deprecated  - although this was generated by phoenix so not going to touch this just yet.                                       
          supervisor(Gametime.Repo, []),                                                                                    
          supervisor(GametimeWeb.Endpoint, []),                                                  

          # Start your own worker by calling: Gametime.Worker.start_link(arg1, arg2, arg3)       
          # worker(Gametime.Worker, [arg1, arg2, arg3]),                                         
        ]                                                                                        


        opts = [strategy: :one_for_one, name: Gametime.Supervisor]                                                                                             
        Supervisor.start_link(children, opts)                                                    
      end 

Я просто не уверен, где я иду не так.Я чувствую, что в документах может быть сделано предположение о том, что я должен знать, но, к сожалению, я не знаю, чего не знаю.Любая помощь будет потрясающей - ура.

Ответы [ 2 ]

0 голосов
/ 04 октября 2018

Ого, так что, я думаю, документы устарели.Пережил некоторую боль, чтобы понять это - так думал, что я поделюсь.

...   %{                                                                                                
      id: RedixSupervisor,                                                                            
      type: :supervisor,                                                                              
      start: {Supervisor, :start_link, [  children_redix , [strategy: :one_for_one] ]}                                                                        
    },  ...

- это ответ.Документы, кажется, просто передают children_redix карты child_spec - но это не то, что Supervisor.start_link/2 ожидает в качестве подписи.

Возможно, я упускаю больше из истории, и опять может быть что-то в how to что я не понимаю из-за возможного предположения о том, что люди уже должны знать.

ура

0 голосов
/ 04 октября 2018

Вам, вероятно, нужно обернуть:

Supervisor.child_spec(%{ id: RedixSupervisor, type: :supervisor, start: {RedixSupervisor, :start_link, [children_redix]} })

И в кортеже start используйте модуль RedixSupervisor, а не общий Supervisor.От start_link/1, определенного в RedixSupervisor, где вы получите аргументы (в данном случае children_redix), где вы будете Supervisor.start_link, и будете использовать дочерние элементы, переданные в качестве аргумента в init функции

Примером может быть:

defmodule RedixSupervisor do
  use Supervisor
  require Logger

  def start_link(children_redix) do
    Logger.info("RedixSupervisor Start Link")
    Supervisor.start_link(__MODULE__, children_redix, name: __MODULE__)
  end

  def init(children_redix) do
    children = children_redix
    Supervisor.init(children, strategy: :one_for_one)
  end
end
...