Handling PID of Genserver in params and HTML.eex template

Following is my PID while printing in log

    IO.puts("++++++pid")
    IO.inspect(pid)

as result I am getting

++++++pid
#PID<0.9069.0>

I am pasisng this PID in following ways-
1- inserting into session and render to live view
2- From live view passing it to html
3- Then Html to a controller.
Now, what happens I am getting error as following-

protocol Phoenix.Param not implemented for #PID<0.9069.0>. This protocol is implemented for: Map, BitString, Atom, Integer, Any

Now, I want to pass this PID as I have to used it later on. And to do so, I must ensure that it pass well in params as well as other places. How can I do this? Any help will be appreciated.

PIDs are mainly opaque, even though you could send its textual representation to the client, you weren’t be able to get back a PID from it on the server side.

If you really need your client to know the “address” of a certain GenServer, rather than letting the server know which of the running GenServers is responsible for the users session, then use a symbolic name and Registry.

1 Like

I have identifier, so could I still get the PIDs. If yes, then tell me that way.

Then you can just use the identifier when calling GenServer.call/GenServer.cast.

Both functions can deal with pids or with whatever :name you gave the GenServer when starting it.

1 Like

Even, when I am passing them into map, still getting same above error message. I am passing like this-

    {_, process_id} = start_timer(job_opening, page, applied_opening, identifier)
    pid = %{"process_id" => process_id}
    IO.puts("++++++pid")
    IO.inspect(pid)

as result-

++++++pid
%{"process_id" => #PID<0.2944.0>}

Here is how I am passing into Live view-

      session: %{
        tenant: Repo.get_prefix(),
        duration: job_opening.duration,
        attempts: attempts,
        job_opening_hash: job_opening.share_url_route,
        job_opening_id: job_opening.id,
        user_id: user.id,
        state: applied_opening.state,
        identifier: identifier,
        pid: pid
      }

and In html-

<%= render_many @attempts.list, ApolloWeb.AttemptView, "answers/_type.html", conn: @conn, attempts: @attempts, page: @attempts.page, user: @user_id, job_opening: @job_opening_id, hash: @job_opening_hash, identifier: @identifier, pid: @pid, as: :attempt %>

Also, I have tried the function you mention- GenServer.call/GenServer.cast but they don’t accept identifier as parameter (here). Could you give example of it.

Again, you shall not use the pid to send it between client and server, it is not properly deserializable.

You can use though an atom as name for the GenServer though and send it to the client. But this does not scale well.

Better were to use Registry and :via tuples to name the GenServer on start. Then you can send the moving parts of the :via tuple to the client (perhaps a session id or something like that) and reconstruct the tuple on the server.

2 Likes