@@ -24,7 +24,8 @@ defmodule GenStage.PartitionDispatcher do
2424 and the partition as second. The partition must be one of the partitions
2525 specified in `:partitions` above. The default uses
2626 `fn event -> {event, :erlang.phash2(event, Enum.count(partitions))} end`
27- on the event to select the partition.
27+ on the event to select the partition. If it returns `:none`, the event
28+ is discarded.
2829
2930 ### Examples
3031
@@ -239,30 +240,7 @@ defmodule GenStage.PartitionDispatcher do
239240
240241 @ doc false
241242 def dispatch ( events , _length , { tag , hash , waiting , pending , partitions , references , infos } ) do
242- { deliver_now , deliver_later , waiting } = split_events ( events , waiting , [ ] )
243-
244- for event <- deliver_now do
245- { event , partition } =
246- case hash . ( event ) do
247- { event , partition } ->
248- { event , partition }
249-
250- other ->
251- raise "the :hash function should return {event, partition}, got: #{ inspect ( other ) } "
252- end
253-
254- case :erlang . get ( partition ) do
255- :undefined ->
256- Logger . error ( fn ->
257- "Unknown partition #{ inspect ( partition ) } computed for GenStage/Flow event " <>
258- "#{ inspect ( event ) } . The known partitions are #{ inspect ( Map . keys ( partitions ) ) } . " <>
259- "See the :partitions option to set your own. This event has been discarded."
260- end )
261-
262- current ->
263- Process . put ( partition , [ event | current ] )
264- end
265- end
243+ { deliver_later , waiting } = split_events ( events , waiting , hash , partitions )
266244
267245 partitions =
268246 partitions
@@ -273,11 +251,30 @@ defmodule GenStage.PartitionDispatcher do
273251 { :ok , deliver_later , { tag , hash , waiting , pending , partitions , references , infos } }
274252 end
275253
276- defp split_events ( events , 0 , acc ) , do: { :lists . reverse ( acc ) , events , 0 }
277- defp split_events ( [ ] , counter , acc ) , do: { :lists . reverse ( acc ) , [ ] , counter }
254+ defp split_events ( events , 0 , _hash , _partitions ) , do: { events , 0 }
255+ defp split_events ( [ ] , counter , _hash , _partitions ) , do: { [ ] , counter }
256+
257+ defp split_events ( [ event | events ] , counter , hash , partitions ) do
258+ case hash . ( event ) do
259+ { event , partition } ->
260+ case :erlang . get ( partition ) do
261+ :undefined ->
262+ raise "unknown partition #{ inspect ( partition ) } computed for GenStage event " <>
263+ "#{ inspect ( event ) } . The known partitions are #{ inspect ( Map . keys ( partitions ) ) } . " <>
264+ "See the :partitions option to set your own. This event has been discarded."
265+
266+ current ->
267+ Process . put ( partition , [ event | current ] )
268+ split_events ( events , counter - 1 , hash , partitions )
269+ end
270+
271+ :none ->
272+ split_events ( events , counter , hash , partitions )
278273
279- defp split_events ( [ event | events ] , counter , acc ) ,
280- do: split_events ( events , counter - 1 , [ event | acc ] )
274+ other ->
275+ raise "the :hash function should return {event, partition}, got: #{ inspect ( other ) } "
276+ end
277+ end
281278
282279 defp dispatch_per_partition ( [ { partition , { pid , ref , demand_or_queue } = value } | rest ] ) do
283280 case Process . put ( partition , [ ] ) do
0 commit comments