2017-11-11 3 views
0

Mit Porcelain und HTTPoison ich folgendes tun möchte:Prozessknoten starten in Elixier dann Ergebnis einer HTTP-Anfrage zurückgeben

  • einen Knoten Server

  • senden HTTP-Anforderung an den Knoten starten Prozess

  • herunterzufahren, den Prozess

  • Rückkehr das Ergebnis th e Anfrage

Ich habe so etwas wie die folgenden versucht:

require HTTPoison 
alias Porcelain.Process, as: Proc 
alias Porcelain.Result, as: Res 


def request do 
    cmd = "node node_app/src/index.js" 
    opts = [out: {:send, self()}] 
    proc = %Proc{pid: pid} = Porcelain.spawn_shell(cmd, opts) 

    receive do 
    {^pid, :data, :out, log} -> 
     IO.puts "Node log => #{log}" 
     # only if log contains "running" should I send the request 
     if String.contains?(log, "running") do 
     IO.puts "Requesting..." 
     %HTTPoison.Response{body: body} = HTTPoison.get! @root_url <> "/collection" 
     Proc.stop(proc) 
     end 
    {^pid, :result, %Res{status: status} = res} -> 
     nil 
    end 

    Proc.await proC# wait for the process to terminate 
    body # return body of request 
end 

Ein Problem ist, dass ich habe keine Kontrolle darüber, wann ich aus dem Empfang zurückkehren kann.

Ich bekomme eine Elixier-Warnung, dass Körper nicht definiert werden kann, was ich gerne vermeiden würde.

Gehe ich in die falsche Richtung? Gibt es einen schöneren Weg, dies zu tun?

Vielen Dank im Voraus für die Hilfe

Antwort

1

Es gibt zwei Pannen mit diesem Code: Zunächst einmal sollte man den erzeugten Prozess in jedem Fall stoppen.

Zweitens sollten Sie das gesamte Ergebnis von receive an die Variable binden. So etwas sollte (ungetestet) arbeiten:

result = receive do 
    {^pid, :data, :out, log} -> 
    IO.puts "Node log => #{log}" 
    # only if log contains "running" should I send the request 
    if String.contains?(log, "running") do 
     IO.puts "Requesting..." 
     HTTPoison.get! @root_url <> "/collection" 
    end 
    {^pid, :result, %Res{status: status} = res} -> 
    nil 
end 

Proc.stop(proc) 

with %HTTPoison.Response{body: body} <- result, do: body 

Die letzte Kernel.SpecialForms.with/1 effektiv etwas zurückgeben, die nicht die erwartete Response übereinstimmen oder body wenn Spiel gelungen.


Nebenbei bemerkt: die Warnung ist in der Tat ein zukünftiger Laufzeitfehler. body wurde im Bereich receive definiert, wodurch es für den Abschlussbereich unsichtbar ist.

Verwandte Themen