Current section
Files
Jump to
Current section
Files
lib/router/realms/session.ex
defmodule Wampex.Router.Realms.Session do
@moduledoc false
require Logger
@max_id 9_007_199_254_740_992
def register(db, realm, procedure, val) do
ClusterKV.put(db, realm, procedure, val)
ClusterKV.put(db, realm, "#{procedure}:callee_index", 0)
end
def unregister(db, realm, {id, _from} = value, regs) do
{_id, proc} = reg = get_registration(id, regs)
ClusterKV.update(db, realm, proc, value, :remove)
List.delete(regs, reg)
end
def callees(db, realm, procedure) do
case ClusterKV.get(db, realm, procedure, 500) do
:not_found ->
:not_found
{_key, callees} ->
{callees, 0}
end
end
def get_index(db, realm, proc) do
case ClusterKV.get(db, realm, "#{proc}:callee_index") do
{_key, [callee_index]} ->
callee_index
{_key, [_ | t]} ->
get_last_index(t)
end
end
def get_last_index([i]), do: i
def get_last_index([_ | t]), do: get_last_index(t)
def round_robin(db, realm, procedure, len) do
ClusterKV.update(db, realm, "#{procedure}:callee_index", len, :round_robin)
end
def subscribe(db, realm, topic, val, %{"match" => "wildcard"}) do
put_wildcard(db, realm, topic, val)
true
end
def subscribe(db, realm, topic, val, _) do
ClusterKV.put(db, realm, topic, val)
false
end
def unsubscribe(db, realm, {id, _from} = value, subscriptions) do
case get_subscription(id, subscriptions) do
{_id, topic, wc} = sub ->
key =
case wc do
true ->
get_wildcard_key(topic)
false ->
topic
end
ClusterKV.update(db, realm, key, value, :remove)
remove_val(sub, subscriptions)
_ ->
Logger.error("Unable to unsubscribe #{id} not present in subscriptions: #{inspect(subscriptions)}")
subscriptions
end
end
def subscriptions(db, realm, topic) do
{_, _, subs} =
{db, {realm, topic}, []}
|> get_subscribers()
|> get_prefix()
|> get_wildcard()
Enum.uniq(subs)
end
def get_id do
Enum.random(0..@max_id)
end
def get_request_id(current_id) when current_id == @max_id do
1
end
def get_request_id(current_id) do
current_id + 1
end
defp get_subscribers({db, {keyspace, key}, acc}) do
case ClusterKV.get(db, keyspace, key, 500) do
{_, subscribers} -> {db, {keyspace, key}, acc ++ subscribers}
_ -> {db, {keyspace, key}, acc}
end
end
defp get_prefix({db, {keyspace, key}, acc}) do
case ClusterKV.prefix(db, keyspace, key, ".", 2, 500) do
:not_found ->
{db, {keyspace, key}, acc}
subscribers ->
{db, {keyspace, key}, acc ++ Enum.flat_map(subscribers, fn {_, subscribers} -> subscribers end)}
end
end
defp get_wildcard({db, {keyspace, key}, acc}) do
case ClusterKV.wildcard(db, keyspace, key, ".", ":", "") do
:not_found -> {db, {keyspace, key}, acc}
l -> {db, {keyspace, key}, acc ++ Enum.map(l, fn {_, subscriber} -> subscriber end)}
end
end
defp get_registration(id, regs) do
Enum.find(regs, fn
{^id, _proc} -> true
_ -> false
end)
end
defp get_subscription(id, subscriptions) do
Enum.find(subscriptions, fn
{^id, _topic, _} -> true
_ -> false
end)
end
defp remove_val(val, values) do
List.delete(values, val)
end
defp put_wildcard(db, realm, topic, val), do: ClusterKV.put_wildcard(db, realm, topic, val, ".", ":", "")
defp get_wildcard_key(topic), do: ClusterKV.get_wildcard_key(topic, ".", ":", "")
end