Packages

A wrapper for Kafka clients that provies a testing sandbox implmentation for easier kafka tests.

Current section

Files

Jump to
ghost lib queue virtual_queue.ex
Raw

lib/queue/virtual_queue.ex

defmodule Ghost.VirtualQueue do
@behaviour Ghost.Queue
import Ghost.Kafka.Brod
@impl true
def produce_sync(client, topic, key, message) do
produce_sync(client, topic, nil, key, message)
end
@impl true
def produce_sync(_client, topic, _partition_selection_function, _key, message) do
queue = get_agent(topic)
put_message_in_queue(queue, message)
{:ok, :erlang.unique_integer([:monotonic, :positive])}
end
@impl true
def produce(client, topic, key, message) do
produce(client, topic, nil, key, message)
end
@impl true
def produce(_client, topic, _partition_selection_function, _key, message) do
queue = get_agent(topic)
put_message_in_queue(queue, message)
queue_length = fetch(queue, topic) |> Enum.count()
caller_ref = brod_call_ref(caller: self(), callee: queue, ref: make_ref())
send(
self(),
brod_produce_reply(
call_ref: caller_ref,
base_offset: queue_length,
result: :brod_produce_req_acked
)
)
{:ok, caller_ref}
end
@impl true
def fetch(pid, topic) do
case :global.whereis_name({pid, topic}) do
:undefined ->
[]
agent_pid ->
Agent.get(agent_pid, fn queue -> :queue.to_list(queue) end)
end
end
def get_agent(topic) do
case :global.whereis_name({self(), topic}) do
:undefined ->
{:ok, pid} = Agent.start_link(fn -> :queue.new() end, name: {:global, {self(), topic}})
pid
pid ->
pid
end
end
defp put_message_in_queue(pid, message) do
Agent.update(pid, fn queue -> :queue.in(message, queue) end)
end
end