Current section
Files
Jump to
Current section
Files
lib/utils/generator.ex
defmodule StarkBank.Utils.QueryGenerator do
@moduledoc false
alias StarkBank.Utils.Checks, as: Checks
alias StarkBank.Utils.JSON, as: JSON
def start_query(function, key, query) do
Task.start_link(fn -> yield([], function, key, query, true) end)
end
def get(pid) do
send(pid, self())
receive do
:halt -> :halt
{:ok, element} -> {:ok, element}
{:error, errors} -> {:error, errors}
end
end
defp yield([head | tail], function, key, query) do
receive do
caller ->
send(caller, {:ok, head})
yield(tail, function, key, query)
end
end
defp yield([], function, key, query, first \\ false) do
limit = query[:limit]
cursor = query[:cursor]
if (first or !is_nil(cursor)) and (is_nil(limit) or limit > 0) do
case function.(query |> Map.put(:limit, limit |> Checks.check_limit)) do
{:ok, result} ->
decoded = JSON.decode!(result)
yield(
decoded[key],
function,
key,
query |> Map.put(:cursor, decoded["cursor"]) |> Map.put(:limit, iterate_limit(limit))
)
{:error, error} -> yield_error(error)
end
else
receive do
caller ->
send(caller, :halt)
end
end
end
defp yield_error(error) do
receive do
caller ->
send(caller, {:error, error})
end
receive do
caller ->
send(caller, :halt)
end
end
defp iterate_limit(limit) when is_nil(limit) do
nil
end
defp iterate_limit(limit) do
limit - 100
end
end