0
votes

In my Phoenix app I am using a Genserver (Paginator) to maintain state for pagination purposes.

I have this in my PageController:

def index(conn, params) do
  {page_entries, current_page} = case Map.get(params, "page_entries") do
                                  nil ->
                                    {:ok, page_entries} = Paginator.start_link()
                                    {page_entries, 1}
                                  page_entries ->
                                    {page_entries, Map.get(params, "current_page")}
                                 end
  # do some stuff
  render conn, "index.html", page_entries: page_entries, current_page: current_page
end

In my template index.html.eex I have this link:

link "Next→", to: page_path(@conn, :index, page_entries: @page_entries, current_page: @current_page+1)

But I get this error:

protocol Phoenix.Param not implemented for #PID<0.890.0>

From the docs:

By default, Phoenix implements this protocol for integers, binaries, atoms, maps and structs.

How do I send the process id across pages through links? Is there any way to do it without the process data appearing in the query string?

1
I would say that this sounds generally like a bad idea. What if the process goes down? Or in case you need to have multiple machines, what if the nest request goes to another one?michalmuskala

1 Answers

1
votes

You should not pass PID across. PID is not a long-lived entity, it changes when the process crashes and is restarted by the supervisor, it differs amongst different nodes. Pass either name or an id instead.

GenServer.start_link/3 has an optional opts parameter, where one might pass a name:

GenServer.start_link(__MODULE__, [], name: __MODULE__)

Later on, when you need to call this Paginator’s instance, just pass this name instead of PID:

GenServer.call(Paginator, {:blah, 42})