@@ -14,33 +14,60 @@ defmodule GenStage.Streamer do
1414 x , { acc , counter } -> { :cont , { [ x | acc ] , counter - 1 } }
1515 end )
1616
17- { :producer , { stack , continuation } , Keyword . take ( opts , [ :dispatcher , :demand ] ) }
17+ on_cancel =
18+ case Keyword . get ( opts , :on_cancel , :continue ) do
19+ :continue -> nil
20+ :stop -> % { }
21+ end
22+
23+ { :producer , { stack , continuation , on_cancel } , Keyword . take ( opts , [ :dispatcher , :demand ] ) }
24+ end
25+
26+ def handle_subscribe ( :consumer , _opts , { pid , ref } , { stack , continuation , on_cancel } ) do
27+ if on_cancel do
28+ { :automatic , { stack , continuation , Map . put ( on_cancel , ref , pid ) } }
29+ else
30+ { :automatic , { stack , continuation , on_cancel } }
31+ end
32+ end
33+
34+ def handle_cancel ( _reason , { _ , ref } , { stack , continuation , on_cancel } ) do
35+ case on_cancel do
36+ % { ^ ref => _ } when map_size ( on_cancel ) == 1 ->
37+ { :stop , :normal , { stack , continuation , Map . delete ( on_cancel , ref ) } }
38+
39+ % { ^ ref => _ } ->
40+ { :noreply , [ ] , { stack , continuation , Map . delete ( on_cancel , ref ) } }
41+
42+ _ ->
43+ { :noreply , [ ] , { stack , continuation , on_cancel } }
44+ end
1845 end
1946
20- def handle_demand ( _demand , { stack , continuation } ) when is_atom ( continuation ) do
21- { :noreply , [ ] , { stack , continuation } }
47+ def handle_demand ( _demand , { stack , continuation , on_cancel } ) when is_atom ( continuation ) do
48+ { :noreply , [ ] , { stack , continuation , on_cancel } }
2249 end
2350
24- def handle_demand ( demand , { stack , continuation } ) when demand > 0 do
51+ def handle_demand ( demand , { stack , continuation , on_cancel } ) when demand > 0 do
2552 case continuation . ( { :cont , { [ ] , demand } } ) do
2653 { :suspended , { list , 0 } , continuation } ->
27- { :noreply , :lists . reverse ( list ) , { stack , continuation } }
54+ { :noreply , :lists . reverse ( list ) , { stack , continuation , on_cancel } }
2855
2956 { status , { list , _ } } ->
3057 GenStage . async_info ( self ( ) , :stop )
31- { :noreply , :lists . reverse ( list ) , { stack , status } }
58+ { :noreply , :lists . reverse ( list ) , { stack , status , on_cancel } }
3259 end
3360 end
3461
3562 def handle_info ( :stop , state ) do
3663 { :stop , :normal , state }
3764 end
3865
39- def handle_info ( msg , { stack , continuation } ) do
66+ def handle_info ( msg , { stack , continuation , on_cancel } ) do
4067 log =
4168 ~c" ** Undefined handle_info in ~tp~n** Unhandled message: ~tp~n** Stream started at:~n~ts"
4269
4370 :error_logger . warning_msg ( log , [ inspect ( __MODULE__ ) , msg , Exception . format_stacktrace ( stack ) ] )
44- { :noreply , [ ] , { stack , continuation } }
71+ { :noreply , [ ] , { stack , continuation , on_cancel } }
4572 end
4673end
0 commit comments