-
Notifications
You must be signed in to change notification settings - Fork 162
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Attempt of better connection error handling / reconnect #347
Changes from all commits
a746114
34d2b7f
60ac0a2
ec9299b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -192,15 +192,30 @@ defmodule KafkaEx.ConsumerGroup.Manager do | |
{:noreply, state} | ||
end | ||
|
||
# If the heartbeat gets an unrecoverable error. | ||
def handle_info( | ||
{:EXIT, _heartbeat_timer, {:shutdown, {:error, reason}}}, | ||
%State{} = state | ||
) do | ||
{:stop, {:shutdown, {:error, reason}}, state} | ||
end | ||
|
||
# When terminating, inform the group coordinator that this member is leaving | ||
# the group so that the group can rebalance without waiting for a session | ||
# timeout. | ||
def terminate(_reason, %State{generation_id: nil, member_id: nil}), do: :ok | ||
def terminate(_reason, %State{generation_id: nil, member_id: nil} = state) do | ||
Process.unlink(state.worker_name) | ||
KafkaEx.stop_worker(state.worker_name) | ||
end | ||
|
||
def terminate(_reason, %State{} = state) do | ||
{:ok, _state} = leave(state) | ||
Process.unlink(state.worker_name) | ||
KafkaEx.stop_worker(state.worker_name) | ||
|
||
# should be at end because of race condition (stop heartbeat while it is shutting down) | ||
# if race condition happens, worker will be abandoned | ||
stop_heartbeat_timer(state) | ||
end | ||
|
||
### Helpers | ||
|
@@ -244,9 +259,14 @@ defmodule KafkaEx.ConsumerGroup.Manager do | |
|
||
# crash the worker if we recieve an error, but do it with a meaningful | ||
# error message | ||
if join_response.error_code != :no_error do | ||
raise "Error joining consumer group #{group_name}: " <> | ||
"#{inspect(join_response.error_code)}" | ||
case join_response do | ||
%{error_code: :no_error} -> :ok | ||
%{error_code: error_code} -> | ||
raise "Error joining consumer group #{group_name}: " <> | ||
"#{inspect(error_code)}" | ||
{:error, reason} -> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here - dialyzer says that join_response can never be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also checked on live application - exception can be raised from line 268 |
||
raise "Error joining consumer group #{group_name}: " <> | ||
"#{inspect(reason)}" | ||
end | ||
|
||
Logger.debug(fn -> "Joined consumer group #{group_name}" end) | ||
|
@@ -331,7 +351,6 @@ defmodule KafkaEx.ConsumerGroup.Manager do | |
member_id: member_id | ||
} = state | ||
) do | ||
stop_heartbeat_timer(state) | ||
|
||
leave_request = %LeaveGroupRequest{ | ||
group_name: group_name, | ||
|
@@ -341,13 +360,19 @@ defmodule KafkaEx.ConsumerGroup.Manager do | |
leave_group_response = | ||
KafkaEx.leave_group(leave_request, worker_name: worker_name) | ||
|
||
if leave_group_response.error_code == :no_error do | ||
Logger.debug(fn -> "Left consumer group #{group_name}" end) | ||
else | ||
Logger.warn(fn -> | ||
"Received error #{inspect(leave_group_response.error_code)}, " <> | ||
"consumer group manager will exit regardless." | ||
end) | ||
case leave_group_response do | ||
%{error_code: :no_error} -> | ||
Logger.debug(fn -> "Left consumer group #{group_name}" end) | ||
%{error_code: error_code} -> | ||
Logger.warn(fn -> | ||
"Received error #{inspect(error_code)}, " <> | ||
"consumer group manager will exit regardless." | ||
end) | ||
{:error, reason} -> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also here, Dialyzer catches this as not possible |
||
Logger.warn(fn -> | ||
"Received error #{inspect(reason)}, " <> | ||
"consumer group manager will exit regardless." | ||
end) | ||
end | ||
|
||
{:ok, state} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not possible for this value to be returned from
KafkaEx.heartbeat/2
according to dialyzer.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm sure it's possible, I've checked this on live application.
KafkaEx.heartbeat is called here -
kafka_ex/lib/kafka_ex/consumer_group/heartbeat.ex
Line 69 in a746114
->
KafkaEx.heartbeat
kafka_ex/lib/kafka_ex.ex
Line 146 in a746114
->
KafkaEx.Server.handle_call({:heartbeat... -
kafka_ex/lib/kafka_ex/server.ex
Line 336 in a746114
->
KafkaEx.Server0P9P0.kafka_server_heartbeat -
kafka_ex/lib/kafka_ex/server_0_p_9_p_0.ex
Line 186 in a746114
->
KafkaEx.Server0P9P0.consumer_group_sync_request -
kafka_ex/lib/kafka_ex/server_0_p_9_p_0.ex
Line 228 in a746114
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
heh, that's unfortunate. I suspect we need to fix the
@spec
for KafkaEx.heartbeat then, so that dialyzer will pass.