Reputation: 3661
Using Porcelain and HTTPoison I would like to do the following:
start a node server
send a http request to the node process
shut down the process
return the result of the request
I have been trying something like the following:
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
One problem is that I don't have control over when I can return out of the receive.
I get an elixir warning that body may not be defined which I would like to avoid.
Am I going about this the wrong way? Is there a nicer way to be doing this?
Thanks in advance for the help
Upvotes: 0
Views: 236
Reputation: 121010
There are two glitches with this code: first of all, one should stop the spawned process in any case.
Secondary, you should bind the whole result of receive
to the variable. Something like this should work (untested):
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
The last Kernel.SpecialForms.with/1
will effectively return anything that did not match the expected Response
, or body
if match succeeded.
Sidenote: the warning is indeed a future runtime error. body
was defined in the scope of receive
, which makes it invisible to the closing scope.
Upvotes: 1