Skip to content

Commit cd64eff

Browse files
authored
Merge pull request #6 from emqx/fix/stale-grpc-channel-recovery-emqx
fix: recover stale grpc channels
2 parents 5a7b90f + 54d630b commit cd64eff

2 files changed

Lines changed: 48 additions & 2 deletions

File tree

src/greptimedb_worker.erl

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ init(Args) ->
7171
lists:map(fun({Scheme, Host, Port}) -> {Scheme, Host, Port, ssl_options(Scheme, SslOptions)}
7272
end, Endpoints),
7373
Channel = iolist_to_binary([PoolName, ":", integer_to_binary(WorkerId)]),
74-
{ok, _} = grpcbox_channel_sup:start_child(Channel, Channels, Options),
74+
{ok, _} = start_channel(Channel, Channels, Options),
7575
logger:debug("[GreptimeDB] genserver has started (~s)~n", [Channel]),
7676
{ok, #state{channel = Channel, hints = Hints, requests = #{ pending => queue:new(), pending_count => 0}}}.
7777

@@ -134,6 +134,28 @@ terminate(Reason, #state{channel = Channel} = State) ->
134134
%%%===================================================================
135135
%%% Helper functions
136136
%%%===================================================================
137+
start_channel(Channel, Channels, Options) ->
138+
case grpcbox_channel_sup:start_child(Channel, Channels, Options) of
139+
{error, {already_started, StaleChannel}} ->
140+
%% ecpool may force-kill a worker without invoking terminate/2, leaving its
141+
%% grpcbox channel alive under the global supervisor. Remove that orphan
142+
%% before reusing the deterministic channel name.
143+
logger:warning(
144+
"[GreptimeDB] removing stale grpc channel ~s (~p)",
145+
[Channel, StaleChannel]),
146+
ok = stop_stale_channel(Channel),
147+
grpcbox_channel_sup:start_child(Channel, Channels, Options);
148+
Result ->
149+
Result
150+
end.
151+
152+
stop_stale_channel(Channel) ->
153+
try grpcbox_channel:stop(Channel)
154+
catch
155+
exit:noproc -> ok;
156+
exit:{noproc, _} -> ok
157+
end.
158+
137159
ssl_options(https, []) ->
138160
%% https://www.erlang.org/doc/man/ssl#type-client_option
139161
[

test/greptimedb_SUITE.erl

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
-define(WRONG_PASSWORD, <<"wrong_pwd">>).
1414

1515
all() ->
16-
[t_write,
16+
[t_recover_stale_channel,
17+
t_write,
1718
t_write_stream,
1819
t_write_failure,
1920
t_write_batch,
@@ -41,6 +42,29 @@ all() ->
4142
t_write_custom_ts_column,
4243
t_write_decimal128].
4344

45+
t_recover_stale_channel(_) ->
46+
Pool = greptimedb_stale_channel_pool,
47+
Channel = <<"greptimedb_stale_channel_pool:1">>,
48+
Endpoint = {http, greptime_host(), 5001},
49+
GrpcOptions = #{connect_timeout => 5_000},
50+
Options =
51+
[{endpoints, [Endpoint]},
52+
{pool, Pool},
53+
{pool_size, 1},
54+
{grpc_opts, GrpcOptions}],
55+
try
56+
{Scheme, Host, Port} = Endpoint,
57+
{ok, StaleChannel} =
58+
grpcbox_channel_sup:start_child(
59+
Channel, [{Scheme, Host, Port, []}], GrpcOptions),
60+
{ok, Client} = greptimedb:start_client(Options),
61+
?assertNot(is_process_alive(StaleChannel)),
62+
ok = greptimedb:stop_client(Client)
63+
after
64+
_ = catch ecpool:stop_sup_pool(Pool),
65+
_ = catch grpcbox_channel:stop(Channel)
66+
end.
67+
4468
%%[t_bench_perf].
4569
%%[t_insert_requests, t_bench_perf].
4670

0 commit comments

Comments
 (0)