@@ -2,6 +2,8 @@ defmodule Phoenix.Channel.Server do
22 @ moduledoc false
33 use GenServer , restart: :temporary
44
5+ @ behaviour Phoenix.PubSub.Sender
6+
57 require Logger
68
79 alias Phoenix.PubSub
@@ -89,52 +91,44 @@ defmodule Phoenix.Channel.Server do
8991 ## Channel API
9092
9193 @ doc """
92- Hook invoked by Phoenix.PubSub dispatch.
94+ Hook invoked by Phoenix.PubSub to deliver a message to a channel subscription.
95+
96+ Broadcasts not intercepted by the channel are encoded once per
97+ serializer and sent directly to the transport process.
9398 """
94- def dispatch ( subscribers , from , % Broadcast { event: event } = msg ) do
95- Enum . reduce ( subscribers , % { } , fn
96- { pid , _ } , cache when pid == from ->
97- cache
98-
99- { pid , { :fastlane , fastlane_pid , serializer , event_intercepts } } , cache ->
100- if event in event_intercepts do
101- send ( pid , msg )
99+ def send ( pid , { transport_pid , serializer , intercepts } , % Broadcast { event: event } = msg , cache ) do
100+ if event in intercepts do
101+ send ( pid , msg )
102+ cache
103+ else
104+ case cache do
105+ % { ^ serializer => encoded_msg } ->
106+ send ( transport_pid , encoded_msg )
102107 cache
103- else
104- case cache do
105- % { ^ serializer => encoded_msg } ->
106- send ( fastlane_pid , encoded_msg )
107- cache
108-
109- % { } ->
110- encoded_msg = serializer . fastlane! ( msg )
111- send ( fastlane_pid , encoded_msg )
112- Map . put ( cache , serializer , encoded_msg )
113- end
114- end
115-
116- { pid , _ } , cache ->
117- send ( pid , msg )
118- cache
119- end )
120-
121- :ok
122- end
123108
124- def dispatch ( entries , :none , message ) do
125- for { pid , _ } <- entries do
126- send ( pid , message )
109+ _ ->
110+ encoded_msg = serializer . fastlane! ( msg )
111+ send ( transport_pid , encoded_msg )
112+ Map . put ( cache || % { } , serializer , encoded_msg )
113+ end
127114 end
115+ end
128116
129- :ok
117+ def send ( pid , _meta , msg , cache ) do
118+ send ( pid , msg )
119+ cache
130120 end
131121
122+ # TODO: Remove in Phoenix 1.10
123+ #
124+ # Nodes running Phoenix < 1.8.16 expect cluster-wide channel broadcasts to use
125+ # this module as dispatcher, otherwise their channels receive broadcasts
126+ # they cannot handle. Therefore we still broadcast with it, and it is also
127+ # invoked for broadcasts coming from older nodes. Subscriptions carry their
128+ # own sender, so we delegate to the default dispatching.
129+ @ doc false
132130 def dispatch ( entries , from , message ) do
133- for { pid , _ } <- entries , pid != from do
134- send ( pid , message )
135- end
136-
137- :ok
131+ PubSub . dispatch ( entries , from , message )
138132 end
139133
140134 @ doc """
@@ -440,8 +434,8 @@ defmodule Phoenix.Channel.Server do
440434 end
441435
442436 Process . monitor ( transport_pid )
443- fastlane = { :fastlane , transport_pid , serializer , channel . __intercepts__ ( ) }
444- PubSub . subscribe ( pubsub_server , topic , metadata: fastlane )
437+ sender = { __MODULE__ , { transport_pid , serializer , channel . __intercepts__ ( ) } }
438+ PubSub . subscribe ( pubsub_server , topic , sender: sender )
445439
446440 { :noreply , % { socket | joined: true } }
447441 end
0 commit comments