Current section

113 Versions

Jump to

Compare versions

5 files changed
+25 additions
-16 deletions
  @@ -1,7 +1,7 @@
1 1 KAFKA_VERSION ?= 1.1
2 2 PROJECT = brod
3 3 PROJECT_DESCRIPTION = Kafka client library in Erlang
4 - PROJECT_VERSION = 3.7.9
4 + PROJECT_VERSION = 3.7.10
5 5
6 6 DEPS = supervisor3 kafka_protocol
  @@ -1,5 +1,5 @@
1 1 {<<"name">>,<<"brod">>}.
2 - {<<"version">>,<<"3.7.9">>}.
2 + {<<"version">>,<<"3.7.10">>}.
3 3 {<<"requirements">>,
4 4 #{<<"kafka_protocol">> =>
5 5 #{<<"app">> => <<"kafka_protocol">>,<<"optional">> => false,
  @@ -1,6 +1,6 @@
1 1 {application,brod,
2 2 [{description,"Apache Kafka Erlang client library"},
3 - {vsn,"3.7.9"},
3 + {vsn,"3.7.10"},
4 4 {registered,[]},
5 5 {applications,[kernel,stdlib,kafka_protocol,supervisor3]},
6 6 {env,[]},
  @@ -376,18 +376,19 @@ handle_batches(_Header, ?incomplete_batch(Size),
376 376 State = maybe_send_fetch_request(State1),
377 377 {noreply, State};
378 378 handle_batches(Header, [], #state{begin_offset = BeginOffset} = State0) ->
379 - HighWmOffset = kpro:find(high_watermark, Header),
379 + StableOffset = brod_utils:get_stable_offset(Header),
380 380 State =
381 - case BeginOffset < HighWmOffset of
381 + case BeginOffset < StableOffset of
382 382 true ->
383 383 %% There are chances that kafka may return empty message set
384 - %% when messages are delete from a compacted topic.
384 + %% when messages are deleted from a compacted topic.
385 385 %% Since there is no way to know how big the 'hole' is
386 386 %% we can only bump begin_offset with +1 and try again.
387 387 State1 = State0#state{begin_offset = BeginOffset + 1},
388 388 maybe_send_fetch_request(State1);
389 389 false ->
390 - %% we have reached the end of partition
390 + %% we have either reached the end of a partition
391 + %% or trying to read uncommitted messages
391 392 %% try to poll again (maybe after a delay)
392 393 maybe_delay_fetch_request(State0)
393 394 end,
  @@ -399,20 +400,19 @@ handle_batches(Header, Batches,
399 400 , topic = Topic
400 401 , partition = Partition
401 402 } = State0) ->
402 - HighWmOffset = kpro:find(high_watermark, Header),
403 - %% for API version 4 or higher, use last_stable_offset
404 - LatestOffset = kpro:find(last_stable_offset, Header, HighWmOffset),
403 + StableOffset = brod_utils:get_stable_offset(Header),
405 404 {NewBeginOffset, Messages} =
406 405 brod_utils:flatten_batches(BeginOffset, Header, Batches),
407 406 State1 = State0#state{begin_offset = NewBeginOffset},
408 407 State =
409 408 case Messages =:= [] of
410 409 true ->
410 + %% All messages are before requested offset, hence dropped
411 411 State1;
412 412 false ->
413 413 MsgSet = #kafka_message_set{ topic = Topic
414 414 , partition = Partition
415 - , high_wm_offset = LatestOffset
415 + , high_wm_offset = StableOffset
416 416 , messages = Messages
417 417 },
418 418 ok = cast_to_subscriber(Subscriber, MsgSet),
  @@ -31,6 +31,7 @@
31 31 , get_metadata/1
32 32 , get_metadata/2
33 33 , get_metadata/3
34 + , get_stable_offset/1
34 35 , group_per_key/1
35 36 , group_per_key/2
36 37 , init_sasl_opt/1
  @@ -322,18 +323,16 @@ fetch(Conn, ReqFun, Offset, MaxBytes) ->
322 323 {ok, #{batches := ?incomplete_batch(Size)}} ->
323 324 fetch(Conn, ReqFun, Offset, Size);
324 325 {ok, #{header := Header, batches := Batches}} ->
325 - HighWm = kpro:find(high_watermark, Header),
326 - %% for API version 4 or higher, use last_stable_offset
327 - LatestOffset = kpro:find(last_stable_offset, Header, HighWm),
326 + StableOffset = get_stable_offset(Header),
328 327 {NewBeginOffset, Msgs} = flatten_batches(Offset, Header, Batches),
329 - case Offset < LatestOffset andalso Msgs =:= [] of
328 + case Offset < StableOffset andalso Msgs =:= [] of
330 329 true ->
331 330 %% Not reached the latest stable offset yet,
332 331 %% but received an empty batch-set (all messages are dropped).
333 332 %% try again with new begin-offset
334 333 fetch(Conn, ReqFun, NewBeginOffset, MaxBytes);
335 334 false ->
336 - {ok, {LatestOffset, Msgs}}
335 + {ok, {StableOffset, Msgs}}
337 336 end;
338 337 {error, Reason} ->
339 338 {error, Reason}
  @@ -467,6 +466,16 @@ make_batch_input(Key, Value) ->
467 466 false -> [unify_msg(make_msg_input(Key, Value))]
468 467 end.
469 468
469 + %% @doc last_stable_offset is added in fetch response version 4
470 + %% This function takes high watermark offset as last_stable_offset
471 + %% in case it's missing.
472 + %% Offsets are considered 'unstable' if they belong to open transactions
473 + get_stable_offset(Header) ->
474 + HighWmOffset = kpro:find(high_watermark, Header),
475 + StableOffset = kpro:find(last_stable_offset, Header, HighWmOffset),
476 + StableOffset > HighWmOffset andalso error(unexpected_last_stable_offset),
477 + StableOffset.
478 +
470 479 %%%_* Internal functions =======================================================
471 480
472 481 drop_aborted(#{aborted_transactions := AbortedL}, Batches) ->