I have discovered the following :gen_server.enter_loop/3
link. This can be used to change the behaviour module of a GenServer
. I am curious why this behaviour was never exposed in Elixir.
I am currently using it to turn a generic HTTP2 stream handler into a user specific one that can handle bi directional streaming. It’s turning out to be quite a nice API
defmodule Ace.HTTP2.StreamHandler do
use GenServer
def start_link(config, router) do
GenServer.start_link(__MODULE__, {config, router})
end
def handle_info({stream, message}, {config, router}) do
request = Ace.HTTP2.Request.from_headers(message.headers)
handler = try do
router.route(request)
rescue
_exception in FunctionClauseError ->
Ace.HTTP2.Stream.DefaultHandler
end
case handler.handle_info({stream, message}, config) do
{:noreply, state} ->
:gen_server.enter_loop(handler, [], state)
end
end
end