2017-06-05 3 views
1

Ich baue einen Service, der Anfragen an zwei externe APIs stellen wird. Die Ergebnisse werden in der lokalen Datenbank beibehalten.Verbessern Sie die Service-Methode mit Elixir-Prozessen und Supervisors

Grob gesagt, sollte die Methode wie folgt funktionieren:

def make_requests(conn, params) do 
    case Service1.request(params) do 
    {:ok, response1 } -> 
     case Service2.request(params) do 
     {:ok, response2 } -> 
      conn 
      |> Repo.insert(response1) 
      |> Repo.insert(response2) 
      |> render("show.json") 
     {:error, message} -> 
      conn |> render("error.json") 
     end 
    {:error, message } -> 
     conn |> render("error.json") 
    end 
end 

Neu bei Elixier, ich habe über Prozesse und Supervisors gelesen. Meine Frage ist: Macht es Sinn, sie hier zu benutzen? Könnte ich die Methode beschleunigen, leistungsfähiger machen oder vielleicht die Fehlertoleranz verbessern, indem ich sie hier implementiere?

Antwort

0

Da Sie speziell gefragt haben, ob dies die Leistung oder Fehlertoleranz verbessern könnte, denke ich, die Antwort, wenn ja. Sie können Task.async verwenden, um die Anforderungen parallel auszuführen, da es nicht so aussieht, als ob die Anforderungen voneinander abhängig sind. Gleiches gilt für die Datenbankeinfügungen. Ich würde wahrscheinlich eine Task.Supervisor hier verwenden. Sie können es auch so konfigurieren, dass es im Falle eines Fehlers erneut versucht. Achten Sie jedoch darauf, dass Sie nicht mit Duplikaten enden, indem Sie sicherstellen, dass die Anforderungen und Datenbankeinfügungen identisch sind.

Zum Beispiel

import Supervisor.Spec 

children = [ 
    supervisor(Task.Supervisor, [[name: ExampleApp.TaskSupervisor, restart: :transient]]), 
] 

{:ok, pid} = Supervisor.start_link(children, strategy: :one_for_one) 

Dann

{:ok, pid} = Task.Supervisor.start_child(ExampleApp.TaskSupervisor, fn -> 
    {:ok, response} = Service1.request(params) 
    Repo.insert(response) 
end) 
{:ok, pid} = Task.Supervisor.start_child(ExampleApp.TaskSupervisor, fn -> 
    {:ok, response} = Service2.request(params) 
    Repo.insert(response) 
end) 
+0

dank Jesse, ist dies eine gute Information. – ntonnelier

Verwandte Themen