henriquesati

henriquesati

How to init a node long running process through Port?

I’m trying to stablish a long term node process using Port, but the gen server crashs saying

erlang.erl:4716: :erlang.open_port({:spawn, "ts-node c:/Users/pedri/Desktop/ashandphoenix/assets/js/pixparser.ts"}, [:binary, :exit_status])
            (testespay 0.1.0) lib/testespay/genservers/nodepix_processor.ex:17: Testespay.Genservers.NodepixProcessor.init/1

I’m able to open the process using {:spawn, "cmd /c ts-node.cmd #{@node_script_path}"}, on my init callback, but the process doesnt receive any messages, so i dont know if some logic is wrong on my gen server, or opening the process with this command blocks the connection in some way

full code:

defmodule Testespay.Genservers.NodepixProcessor do
  require Logger
  use GenServer

  @node_script_path Path.join([File.cwd!(), "assets", "js", "pixparser.ts"])

  def start_link(opts \\ []) do
    GenServer.start_link(__MODULE__, opts, name: __MODULE__)
  end

  def parse_pix(payload) do
    GenServer.call(__MODULE__, {:parse_pix, payload})
  end

  def init(_opts) do
    # Remova a chamada System.cmd desnecessária
    Logger.debug(@node_script_path)

    port = Port.open(
      {:spawn, "cmd /c ts-node.cmd #{@node_script_path}"},
      [:binary, :exit_status]
    )

    {:ok, %{port: port, buffer: "", current_ref: nil}}
  end
  def handle_call({:parse_pix, payload}, from, state) do
    # Envia o payload para o processo Node
    Port.command(state.port, "#{Jason.encode!(payload)}\n")
    {:noreply, %{state | current_ref: from}}
  end

  def handle_info({port, {:data, data}}, %{port: port, buffer: buffer} = state) do
    new_buffer = buffer <> data

    case String.split(new_buffer, "\n", parts: 2) do
      [message, rest] ->
        handle_node_message(message, state)
        {:noreply, %{state | buffer: rest}}

      _ ->
        {:noreply, %{state | buffer: new_buffer}}
    end
  end

  defp handle_node_message("READY", _state), do: :ok  # Ignora a mensagem de inicialização

  defp handle_node_message(message, %{current_ref: current_ref} = state) do
    case Jason.decode(message) do
      {:ok, %{"status" => "success"} = response} ->
        GenServer.reply(current_ref, {:ok, response})

      {:ok, %{"status" => "error"} = error} ->
        GenServer.reply(current_ref, {:error, error})

      _ ->
        GenServer.reply(current_ref, {:error, :invalid_response})
    end
  end
end

Where Next?

Popular in Questions Top

Fl4m3Ph03n1x
Background Let’s assume I have a typical GenServer that receives messages as requests, does some operation in a DB and returns responses....
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
Jim
As a follow up to my earlier question: I have the code compiling and running but not getting a successful login from the rest server. ...
New
sacepums
Hey guys. I'm new to elixir and im really stocked about it. But I ran into a bit of problem - I need to convert a date sting, for examp...
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
lucidguppy
I have a super simple question about elixir - how would I take a file like this foo bar baz and output a new file that enumerates th...
New

Other popular topics Top

minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
sorentwo
Hello! tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability. After spen...
977 41022 311
New
chrismccord
Phoenix 1.4.0 released Phoenix 1.4 is out! This release ships with exciting new features, most notably with HTTP2 support, improved deve...
688 30048 115
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
jerry
Good day to you all. I have been struggling to get a query involving like and ilike to work. Can anyone assist me on this, please? pro...
New
AstonJ
You’re a programmer, so you don’t need spoon feeding with the conventional drivel about “this is an integer.” No. You need to know what’s...
New
quazar
How to set Jason to encode all fields in ecto schema, I don’t care about security and implementing only is taking long list of attributes...
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
johnnyicon
Hi all, I've just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage. I'm trying to use Postg...
New
aesmail
Hello guys, I have finally made it. I created an admin interface for a framework. It’s been on my todo list for years and with the curre...
New

We're in Beta

About us Mission Statement