2017-01-21 6 views
0

Ich kämpfe seit einiger Zeit, um einen GenServer in einer anderen Anwendung in meiner Regenschirm-App zu verwenden.Verwendung von GenServer aus einer anderen Anwendung

Struktur:
apps:

  • project_a
  • project_b

Project_a und project_b sind beide --sup Anwendungen und ich möchte die GenServer von project_a in project_b verwenden. Ich habe das Projekt in meine deps.exs-Datei aufgenommen, aber ich weiß nicht, was ich als nächstes tun soll ...

Wenn ich den Beobachter öffne, sehe ich beide Anwendungen im Menü, aber ich bekomme immer Fehler, weil project_b kann projekt_a nicht verwenden.

Weiß jemand, was ich vergesse?

+0

Bitte klären Sie, was meinst du mit "verwenden"? – mudasobwa

+0

@mudasobwa Ich meine 'verwenden' wie beim Aufruf der Methoden – Hatsjoem

+0

Haben Sie 'apps_path:" apps "' in der Projektdefinition des Regenschirms? – mudasobwa

Antwort

0

Während Ihre Antwort auf Ihre Frage richtig ist, kann ich Ihnen aus Erfahrung sagen, dass das Schreiben eines Adapters zu Ihrem Dienst in der anderen Anwendung eine gute Übung ist, um die zwei Anwendungen lose miteinander zu verbinden und zirkuläre Referenzen zu vermeiden.

Was meine ich damit? Nehmen Sie den öffentlichen API-Teil des GenServers, an den Sie eine Nachricht senden, und verschieben Sie ihn in ein anderes Modul in einer anderen Anwendung. Sie werden feststellen, dass dies dem Schreiben einer Fassade für eine HTTP-API sehr ähnlich ist. Der öffentliche API-Teil eines GenServers wird tatsächlich vom aufrufenden Prozess ausgeführt, auch wenn er sich innerhalb des GenServer-Moduls befindet. Daher ist es einfach in ein anderes Modul zu verschieben.

Bitte verzeihen Sie Syntaxfehler usw. im folgenden Code, da ich es aus meinem Kopf herausziehen werde.

ändern etwas wie folgt aus:

defmodule App1.Calculator do 
    use GenServer 

    def add(num1, num2), do: GenServer.call(App1.Caclculator, {:add, num1, num2}) 

    def handle_call({:add, num1, num2}, _from, state) do 
    {:reply, {:ok, num1+num2}, state} 
    end 
end 

An:

defmodule App1.Calculator do 
    use GenServer 

    def handle_call({:add, num1, num2}, _from, state) do 
    {:reply, {:ok, num1+num2}, state} 
    end 
end 

defmodule Service.Calculator do 
    def add(num1, num2), do: GenServer.call(process_name, {:add, num1, num2}) 

    # Just an example of how you might have named your node and calculator process 
    def process_name, do: {:calculator, :"[email protected]"} 
end 

Wo Service.Caclulator in einer dritten Anwendung ist Service genannt, die von App1 und App2, ohne eine zirkuläre Referenz hing werden kann.

Warum sollten Sie eine Zirkelreferenz erstellen? Sobald Sie die Dinge asynchron von App1 zu App2 mit cast tun, dann wird App2 haben eine Nachricht mit den Ergebnissen App1 zu schicken, und ohne die 3. Service Anwendung würden Sie einen zirkulären Verweis von App1 und App2 erstellen. Ganz zu schweigen von dem Zeitpunkt, an dem Sie zwei Knoten veröffentlichen (einen für jede App), müssen Sie nicht den gesamten kompilierten Code der anderen Apps hinzufügen, nur um einen Adapter für einen Dienst zu erhalten.

+0

Danke für die Eingabe! – Hatsjoem

0

Ich habe vergessen, project_a in der mix.exs Datei von project_b hinzuzufügen.

Es ist nicht genug, es als dep hinzuzufügen, aber es muss auch in de def application Teil hinzugefügt werden.

siehe: https://github.com/josevalim/kv_umbrella für ein Beispiel.

Verwandte Themen