Skip to content

Instantly share code, notes, and snippets.

@talentdeficit
Last active October 11, 2017 18:47
Show Gist options
  • Save talentdeficit/3c1b1cd95da978350a51117de146ea34 to your computer and use it in GitHub Desktop.
Save talentdeficit/3c1b1cd95da978350a51117de146ea34 to your computer and use it in GitHub Desktop.
defmodule Gateway do
use GenServer
@timeout 5000 # timeout in ms
def init(process), do: %{ process: process, q: :undefined }
def handle_call(call, from, %{ process: process, q: q }) do
# add call to priority queue
newq = add_to_q(q, :call, call, from)
# exit loop without sending reply to calling process, setting a timeout of 0
{ :noreply, %{ process: process, q: newq }, 0 }
end
def handle_cast(cast, %{ process: process, q: q }) do
# add cast to priority queue
newq = add_to_q(q, :call, call, :undefined)
# exit loop without sending reply to calling process, setting a timeout of 0
{ :noreply, %{ process: process, q: newq }, 0 }
end
def handle_info(:timeout, %{ process: process, q: q }) do
# no new messages waiting, process the most urgent message and return
case next_from_q(q) do
{ :call, from, call, newq } ->
reply = GenServer.call(process, call, @timeout)
GenServer.reply(from, reply)
{ :noreply, %{ process: process, q: newq }, 0 }
{ :cast, cast, newq } ->
:ok = GenServer.cast(process, cast, @timeout)
{ :noreply, %{ process: process, q: newq }, 0 }
end
end
defp add_to_q(q, :call, call, from) do
# you can inspect the call and insert it into whatever priority queue implementation you like here
end
defp next_from_q(q) do
# check the queue and return the next message to handle along with it's type (:cast or :call) and the
# waiting client if it's a :cast
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment