The Elixir app I’m working on needs to access an external API. The issue is that the API can only be called by one client at a time.
So I’ve created a queue (Myqueue) to store the parameters I want to use when I call the external API and a worker that checks the queue and call the external API when a message is passed.
This is the code for the worker.
defmodule UniqueWorker do
use Supervisor
def start_link do
Supervisor.start_link(__MODULE__, [])
end
def init([]) do
children = [
worker(UniqueWorker, [], restart: :permanent, id: "unique_worker", function: :do_task)
]
supervise(children, strategy: :one_for_one)
end
def do_task() do
pid=spawn_link(__MODULE__, :loop_do_task, [])
{:ok, pid}
end
def loop_do_task() do
case MyQueue.pop do
nil -> {:empty}
message -> IO.puts "Consume external API with #{message} "
end
loop_do_task()
end
end
I’m an total exlir newbie. Is this a correct way to solve my problem?
His post implied to me that the remote API only ever allows one job at a time. If possible to scale up later though then poolboy now would definitely be a better way to go (or one of the similar ones).
So, you’re right on target conceptually with the whole loop thing, but the idea with OTP behaviours is that they extract that common pattern and let you focus on individual functionality specific to your use case. It also lets the process handle debugging and other utility type messages without requiring any explicit handling on your part.
GenStage specifically is an OTP behaviour built to around the idea of handling the streaming of events between processes, and I think will fit your use case well.