Hi Chris,
Ahhh, somehow missed that parts in the docs, glad it is in there! :)
The amount of messages that go out are significant lower, I would need to check for the exact numbers since lots are being filtered out but yeah
definitelty have to add some scaling support nonetheless but that should rather be "easy" with phoenix/elixir.
Back to the intercepting: I feel like the dispatch function could be extend to better support the case where one would like to only filter based on each socket
and phoenix could still support, for instance like this:
def dispatch(subscribers, from, %Broadcast{event: event} = msg) do
Enum.reduce(subscribers, %{}, fn
{pid, _}, cache when pid == from ->
cache
{pid, {:fastlane, fastlane_pid, serializer, event_intercepts}}, cache ->
cond do
event in event_intercepts ->
send(pid, msg)
cache
event in event_filtering ->
send? = GenServer.call(pid, {:filter, msg})
if send? do
case cache do
%{^serializer => encoded_msg} ->
send(fastlane_pid, encoded_msg)
cache
%{} ->
encoded_msg = serializer.fastlane!(msg)
send(fastlane_pid, encoded_msg)
Map.put(cache, serializer, encoded_msg)
end
else
cache
end
_ ->
case cache do
%{^serializer => encoded_msg} ->
send(fastlane_pid, encoded_msg)
cache
%{} ->
encoded_msg = serializer.fastlane!(msg)
send(fastlane_pid, encoded_msg)
Map.put(cache, serializer, encoded_msg)
end
end
{pid, _}, cache ->
send(pid, msg)
cache
end)
:ok
end
So instead of sending the message to each connected channel we add a more fine granular support for the case
when one only wants to filter messages based on some logic of the user which is connected. That way we would not
serialize a message multiple times if the message content stays the same.
Let me know what you think, I would happily start working on it if you have no concerns.
Best regards,
Dario