Skip to content

Instantly share code, notes, and snippets.

@chrismccord
Last active April 19, 2024 10:19
Show Gist options
  • Star 23 You must be signed in to star a gist
  • Fork 7 You must be signed in to fork a gist
  • Save chrismccord/1c6b6fb086d5432d4e08 to your computer and use it in GitHub Desktop.
Save chrismccord/1c6b6fb086d5432d4e08 to your computer and use it in GitHub Desktop.
# in your app supervisor
:my_app_user_routes = :ets.new(:my_app_user_routes, [:named_table, :bag, :public])
defmodule DynamicDispatch do
def register(tab, host, path, plug, opts) do
true = :ets.insert(tab, {host, path, plug, opts})
end
def unregister(tab, host, path, plug) do
true = :ets.match_delete(my_app_user_routes, {host, path, plug, :_})
end
def init(tab), do: tab
def call(conn, tab) do
case :ets.match_object(tab, {conn.host, conn.requst_path, :_, :_}) do
[{host, path, plug, opts}] -> plug.call(conn, plug.init(opts)
[] -> conn
end
end
end
# in your existing router
forward "/", DynamicDispatch, :my_app_user_routes
# on app boot, pluck all routes from cold storage and register
for {host, path, plug, opts} <- user_routes_from_db do
:ok = DynamicDispatch.register(:my_app_user_routes, host, path, plug, opts)
end
# register your router/controller/plug at any time based on user actions
DynamicDispatch.register(:my_app_user_routes, "foo.com", "/foo", FooController, :show)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment