I'm just starting out in Elixir and wanted to build a very simple API with Plug. I used this guide to get a very simple API up and running.
Basically, the problem I'm facing is that the process that I registered as :qs doesn't seem to be found (and errors out), whenever I use the send/2 function in queue_service.ex. What I'm trying to achieve is a process that sticks around so that I can have state being maintained across requests.
In my router.ex file, I have:
defmodule SecondQueue.Router do
use Plug.Router
alias SecondQueue.Plug.VerifyParams
alias SecondQueue.QueueService
plug Plug.Parsers, parsers: [:urlencoded, :multipart]
plug :match
plug :dispatch
get "/receive-message" do
# gather query parameters from connection
queue = Map.get(conn.params, "queue")
message = Map.get(conn.params, "message")
# handle the params
QueueService.handle_incoming(queue, message)
send_resp(conn, 201, "Created")
end
end
Then inside queue_service.ex, I initiate the queues process, register it to an atom of :qs, and then want to be able to get at that process later via a function that a request calls. I have:
defmodule SecondQueue.QueueService do
alias SecondQueue.QueueStore
use Agent
{:ok, agent_pid} = QueueStore.start_queues_link()
Process.register(agent_pid, :qs)
def handle_incoming(queue, message) do
queue_atom = String.to_atom(queue)
send(:qs, {:put, queue_atom, "success"})
end
end
And then finally, in queue_store.ex, I actually define the process that I want to store the state, and run a loop so that it stays alive, and ready to receive messages. I have:
defmodule SecondQueue.QueueStore do
def start_queues_link() do
Task.start_link(fn -> queues_loop(%{}) end)
end
defp queues_loop(map) do
receive do
{:get, key, caller} ->
send caller, Map.get(map, key)
queues_loop(map)
{:put, key, value} ->
IO.puts("i am here")
queues_loop(Map.put(map, key, value))
end
end
end
Update:
Github repo: https://github.com/qarthandgi/test-second-queue
GenServeror anAgent. Tasks are not really meant to be used in this capacity.Agents andGenServers also have the benefit of not needing to roll your own loops for things, because there are corner cases that you will not think of.String.to_atom(queue)is potentially dangerous ifqueuecomes from the outside. It’s vulnerable to atoms DoS attack.