66 is_ready /1 ,
77 pick /2 ,
88 pick /3 ,
9+ add_endpoints /2 ,
10+ remove_endpoints /3 ,
911 stop /1 ,
1012 stop /2 ]).
1113-export ([init /1 ,
@@ -86,6 +88,12 @@ pick_worker(Name, undefined) ->
8688pick_worker (Name , Key ) ->
8789 gproc_pool :pick_worker (Name , Key ).
8890
91+ add_endpoints (Name , Endpoints ) ->
92+ gen_statem :call (? CHANNEL (Name ), {add_endpoints , Endpoints }).
93+
94+ remove_endpoints (Name , Endpoints , Reason ) ->
95+ gen_statem :call (? CHANNEL (Name ), {remove_endpoints , Endpoints , Reason }).
96+
8997-spec interceptor (name (), unary | stream ) -> grpcbox_client :interceptor () | undefined .
9098interceptor (Name , CallType ) ->
9199 case ets :lookup (? CHANNELS_TAB , {Name , CallType }) of
@@ -114,14 +122,13 @@ init([Name, Endpoints, Options]) ->
114122 pool = Name ,
115123 encoding = Encoding ,
116124 stats_handler = StatsHandler ,
117- endpoints = Endpoints
125+ endpoints = lists : usort ( Endpoints )
118126 },
119-
120127 case maps :get (sync_start , Options , false ) of
121128 false ->
122129 {ok , idle , Data , [{next_event , internal , connect }]};
123130 true ->
124- _ = start_workers (Name , StatsHandler , Encoding , Endpoints ),
131+ start_workers (Name , StatsHandler , Encoding , Endpoints ),
125132 {ok , connected , Data }
126133 end .
127134
@@ -130,14 +137,32 @@ callback_mode() ->
130137
131138connected ({call , From }, is_ready , _Data ) ->
132139 {keep_state_and_data , [{reply , From , true }]};
140+ connected ({call , From }, {add_endpoints , Endpoints },
141+ Data = # data {pool = Pool ,
142+ stats_handler = StatsHandler ,
143+ encoding = Encoding ,
144+ endpoints = TotalEndpoints }) ->
145+ NewEndpoints = lists :subtract (Endpoints , TotalEndpoints ),
146+ NewTotalEndpoints = lists :umerge (TotalEndpoints , Endpoints ),
147+ start_workers (Pool , StatsHandler , Encoding , NewEndpoints ),
148+ {keep_state , Data # data {endpoints = NewTotalEndpoints }, [{reply , From , ok }]};
149+ connected ({call , From }, {remove_endpoints , Endpoints , Reason },
150+ Data = # data {pool = Pool , endpoints = TotalEndpoints }) ->
151+
152+ NewEndpoints = sets :to_list (sets :intersection (sets :from_list (Endpoints ),
153+ sets :from_list (TotalEndpoints ))),
154+ NewTotalEndpoints = lists :subtract (TotalEndpoints , Endpoints ),
155+ stop_workers (Pool , NewEndpoints , Reason ),
156+ {keep_state , Data # data {endpoints = NewTotalEndpoints }, [{reply , From , ok }]};
133157connected (EventType , EventContent , Data ) ->
134158 handle_event (EventType , EventContent , Data ).
135159
136160idle (internal , connect , Data = # data {pool = Pool ,
137161 stats_handler = StatsHandler ,
138162 encoding = Encoding ,
139163 endpoints = Endpoints }) ->
140- _ = start_workers (Pool , StatsHandler , Encoding , Endpoints ),
164+
165+ start_workers (Pool , StatsHandler , Encoding , Endpoints ),
141166 {next_state , connected , Data };
142167idle ({call , From }, is_ready , _Data ) ->
143168 {keep_state_and_data , [{reply , From , false }]};
@@ -186,8 +211,16 @@ insert_stream_interceptor(Name, _Type, Interceptors) ->
186211
187212start_workers (Pool , StatsHandler , Encoding , Endpoints ) ->
188213 [begin
189- gproc_pool :add_worker (Pool , Endpoint ),
190- {ok , Pid } = grpcbox_subchannel :start_link (Endpoint , Pool , {Transport , Host , Port , EndpointOptions },
191- Encoding , StatsHandler ),
192- Pid
193- end || Endpoint = {Transport , Host , Port , EndpointOptions } <- Endpoints ].
214+ gproc_pool :add_worker (Pool , Endpoint ),
215+ {ok , Pid } = grpcbox_subchannel :start_link (Endpoint ,
216+ Pool , Endpoint , Encoding , StatsHandler ),
217+ Pid
218+ end || Endpoint <- Endpoints ].
219+
220+ stop_workers (Pool , Endpoints , Reason ) ->
221+ [begin
222+ case gproc_pool :whereis_worker (Pool , Endpoint ) of
223+ undefined -> ok ;
224+ Pid -> grpcbox_subchannel :stop (Pid , Reason )
225+ end
226+ end || Endpoint <- Endpoints ].
0 commit comments