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 ,
@@ -83,6 +85,12 @@ pick_worker(Name, undefined) ->
8385pick_worker (Name , Key ) ->
8486 gproc_pool :pick_worker (Name , Key ).
8587
88+ add_endpoints (Name , Endpoints ) ->
89+ gen_statem :call (? CHANNEL (Name ), {add_endpoints , Endpoints }).
90+
91+ remove_endpoints (Name , Endpoints , Reason ) ->
92+ gen_statem :call (? CHANNEL (Name ), {remove_endpoints , Endpoints , Reason }).
93+
8694-spec interceptor (name (), unary | stream ) -> grpcbox_client :interceptor () | undefined .
8795interceptor (Name , CallType ) ->
8896 case ets :lookup (? CHANNELS_TAB , {Name , CallType }) of
@@ -112,14 +120,13 @@ init([Name, Endpoints, Options]) ->
112120 pool = Name ,
113121 encoding = Encoding ,
114122 stats_handler = StatsHandler ,
115- endpoints = Endpoints
123+ endpoints = lists : usort ( Endpoints )
116124 },
117-
118125 case maps :get (sync_start , Options , false ) of
119126 false ->
120127 {ok , idle , Data , [{next_event , internal , connect }]};
121128 true ->
122- _ = start_workers (Name , StatsHandler , Encoding , Endpoints ),
129+ start_workers (Name , StatsHandler , Encoding , Endpoints ),
123130 {ok , connected , Data }
124131 end .
125132
@@ -128,14 +135,32 @@ callback_mode() ->
128135
129136connected ({call , From }, is_ready , _Data ) ->
130137 {keep_state_and_data , [{reply , From , true }]};
138+ connected ({call , From }, {add_endpoints , Endpoints },
139+ Data = # data {pool = Pool ,
140+ stats_handler = StatsHandler ,
141+ encoding = Encoding ,
142+ endpoints = TotalEndpoints }) ->
143+ NewEndpoints = lists :subtract (Endpoints , TotalEndpoints ),
144+ NewTotalEndpoints = lists :umerge (TotalEndpoints , Endpoints ),
145+ start_workers (Pool , StatsHandler , Encoding , NewEndpoints ),
146+ {keep_state , Data # data {endpoints = NewTotalEndpoints }, [{reply , From , ok }]};
147+ connected ({call , From }, {remove_endpoints , Endpoints , Reason },
148+ Data = # data {pool = Pool , endpoints = TotalEndpoints }) ->
149+
150+ NewEndpoints = sets :to_list (sets :intersection (sets :from_list (Endpoints ),
151+ sets :from_list (TotalEndpoints ))),
152+ NewTotalEndpoints = lists :subtract (TotalEndpoints , Endpoints ),
153+ stop_workers (Pool , NewEndpoints , Reason ),
154+ {keep_state , Data # data {endpoints = NewTotalEndpoints }, [{reply , From , ok }]};
131155connected (EventType , EventContent , Data ) ->
132156 handle_event (EventType , EventContent , Data ).
133157
134158idle (internal , connect , Data = # data {pool = Pool ,
135159 stats_handler = StatsHandler ,
136160 encoding = Encoding ,
137161 endpoints = Endpoints }) ->
138- _ = start_workers (Pool , StatsHandler , Encoding , Endpoints ),
162+
163+ start_workers (Pool , StatsHandler , Encoding , Endpoints ),
139164 {next_state , connected , Data };
140165idle ({call , From }, is_ready , _Data ) ->
141166 {keep_state_and_data , [{reply , From , false }]};
@@ -184,8 +209,16 @@ insert_stream_interceptor(Name, _Type, Interceptors) ->
184209
185210start_workers (Pool , StatsHandler , Encoding , Endpoints ) ->
186211 [begin
187- gproc_pool :add_worker (Pool , Endpoint ),
188- {ok , Pid } = grpcbox_subchannel :start_link (Endpoint , Pool , {Transport , Host , Port , SSLOptions },
189- Encoding , StatsHandler ),
190- Pid
191- end || Endpoint = {Transport , Host , Port , SSLOptions } <- Endpoints ].
212+ gproc_pool :add_worker (Pool , Endpoint ),
213+ {ok , Pid } = grpcbox_subchannel :start_link (Endpoint ,
214+ Pool , Endpoint , Encoding , StatsHandler ),
215+ Pid
216+ end || Endpoint <- Endpoints ].
217+
218+ stop_workers (Pool , Endpoints , Reason ) ->
219+ [begin
220+ case gproc_pool :whereis_worker (Pool , Endpoint ) of
221+ undefined -> ok ;
222+ Pid -> grpcbox_subchannel :stop (Pid , Reason )
223+ end
224+ end || Endpoint <- Endpoints ].
0 commit comments