2017-04-30 2 views
0

J'ai un travailleur qui est initialisés comme suit:ne peut pas récupérer l'ID de processus pour le nom du processus global

defmodule GenServerDB.Worker do                                              
    use GenServer 

    def start_link(name) do                                               
    GenServer.start_link(__MODULE__, :ok, [name: {:global, {:name, name}}])                                   
    end 

    def init(:ok) do 
    {:ok, %{}} 
    end 

end 

Je peux alors créer les travailleurs que je compte être nommé à l'aide du module :global:

iex(3)> {:ok, pid} = Supervisor.start_link([Supervisor.Spec.worker(GenServerDB.Worker, [], [])], strategy: :simple_one_for_one)                       
{:ok, #PID<0.126.0>} 
iex(4)> Supervisor.start_child(pid, [[1]])                                           
Supervisor.start_child(pid, [[1]])                                             
{:ok, #PID<0.128.0>}                                      
iex(6)> Supervisor.start_child(pid, [[2]])                                           
Supervisor.start_child(pid, [[2]])                                             
{:ok, #PID<0.131.0>}                                                
iex(7)> Supervisor.start_child(pid, [[3]])                                           
Supervisor.start_child(pid, [[3]])                                             
{:ok, #PID<0.133.0>} 
iex(8)> Supervisor.which_children(pid)                                            
Supervisor.which_children(pid)                                              
[{:undefined, #PID<0.128.0>, :worker, [GenServerDB.Worker]},                                      
{:undefined, #PID<0.131.0>, :worker, [GenServerDB.Worker]},                                      
{:undefined, #PID<0.133.0>, :worker, [GenServerDB.Worker]}] 

Cependant quand j'essayer d'obtenir le pid pour un name donné, je reçois le texte suivant:

iex(9)> :global.whereis_name({:global, {:name, 1}})                                         
:global.whereis_name({:global, {:name, 1}})                                           
:undefined 

Ai-je raté quelque chose ici? Il semble que je n'ai pas nommé le processus correctement.

Répondre

2

Vous utilisez l'argument dans l'appel :global.whereis_name/1. Vous n'avez pas besoin de {:global ici et le nom du processus est réellement {:name, [1]}, vous devez donc appeler :global.whereis_name({:name, [1]}).

defmodule GenServerDB.Worker do 
    use GenServer 

    def start_link(name) do 
    GenServer.start_link(__MODULE__, :ok, [name: {:global, {:name, name}}]) 
    end 

    def init(:ok) do 
    {:ok, %{}} 
    end 
end 

{:ok, pid} = Supervisor.start_link([Supervisor.Spec.worker(GenServerDB.Worker, [], [])], strategy: :simple_one_for_one) 
Supervisor.start_child(pid, [[1]]) 
Supervisor.start_child(pid, [[2]]) 
Supervisor.start_child(pid, [[3]]) 
IO.inspect Supervisor.which_children(pid) 
IO.inspect :global.whereis_name({:name, [1]}) 

Sortie:

[{:undefined, #PID<0.77.0>, :worker, [GenServerDB.Worker]}, 
{:undefined, #PID<0.78.0>, :worker, [GenServerDB.Worker]}, 
{:undefined, #PID<0.79.0>, :worker, [GenServerDB.Worker]}] 
#PID<0.77.0> 
+0

Merci - sont là docs sur l'explication ci-dessus? Je n'ai pas pu trouver la documentation d'elixir sur la partie de {{: global, {: name, name}} 'est le nom actuel du processus. – category

+1

https://hexdocs.pm/elixir/GenServer.html#module-name-registration dit "{: global, ** term **} - le GenServer est enregistré globalement ** avec le terme donné ** en utilisant les fonctions de le: module global. " – Dogbert