Skip to content

Commit 619d0fc

Browse files
committed
kafka: consolidate read-replica handling in get_leader_epoch_last_offset
`get_leader_epoch_last_offset_unbounded()` branched on `is_read_replica` five times. A read replica serves all reads from cloud storage and never consults the local log, so handle it in a single early-return block at the top and drop the `is_read_replica` qualifiers from the rest of the function. No behavior change.
1 parent f620e15 commit 619d0fc

1 file changed

Lines changed: 31 additions & 28 deletions

File tree

src/v/kafka/data/replicated_partition.cc

Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -487,54 +487,57 @@ replicated_partition::get_leader_epoch_last_offset_unbounded(
487487
last_local_term,
488488
is_read_replica);
489489

490-
if (!is_read_replica && term > last_local_term) {
490+
if (is_read_replica) {
491+
if (!_partition->cloud_data_available()) {
492+
// If we didn't sync the manifest yet the cloud_data_available will
493+
// return false. We can't call `get_cloud_term_last_offset` in this
494+
// case but we also can't use `first_local_offset` for read replica.
495+
co_return std::nullopt;
496+
}
497+
auto last_offset = co_await _partition->get_cloud_term_last_offset(
498+
term);
499+
if (last_offset) {
500+
co_return last_offset;
501+
}
502+
// The term was not found in cloud storage.
503+
const auto highest_cloud_term = _partition->highest_cloud_term();
504+
if (highest_cloud_term.has_value() && term > *highest_cloud_term) {
505+
// A read replica has no local log, so a term above the highest
506+
// cloud term is an unknown (future) epoch for it.
507+
co_return std::nullopt;
508+
}
509+
// The term is below the earliest cloud segment; the next-highest term
510+
// still lives in cloud, so return the cloud start offset.
511+
co_return _partition->start_cloud_offset();
512+
}
513+
514+
if (term > last_local_term) {
491515
// Request for term that is in the future
492516
co_return std::nullopt;
493517
}
494518
// Look for the highest offset in the requested term, or the first offset
495519
// in the next term. This mirrors behavior in Kafka, see
496520
// https://github.com/apache/kafka/blob/97105a8e5812135515f5a0fa4d5ff554d80df2fe/storage/src/main/java/org/apache/kafka/storage/internals/epoch/LeaderEpochFileCache.java#L255-L281
497-
if (!is_read_replica && term >= first_local_term) {
521+
if (term >= first_local_term) {
498522
auto last_offset = _partition->get_term_last_offset(term);
499523
if (last_offset) {
500524
co_return _translator->from_log_offset(*last_offset);
501525
}
502526
}
503-
// The requested term falls below our earliest local segment.
504-
505-
// Check cloud storage for a viable offset.
527+
// The requested term falls below our earliest local segment. Check cloud
528+
// storage for a viable offset.
506529
if (
507-
is_read_replica
508-
|| (_partition->is_remote_fetch_enabled() && _partition->cloud_data_available())) {
509-
if (is_read_replica && !_partition->cloud_data_available()) {
510-
// If we didn't sync the manifest yet the cloud_data_available will
511-
// return false. We can't call `get_cloud_term_last_offset` in this
512-
// case but we also can't use `first_local_offset` for read replica.
513-
co_return std::nullopt;
514-
}
530+
_partition->is_remote_fetch_enabled()
531+
&& _partition->cloud_data_available()) {
515532
auto last_offset = co_await _partition->get_cloud_term_last_offset(
516533
term);
517534
if (last_offset) {
518535
co_return last_offset;
519536
}
520-
521-
const auto highest_cloud_term = _partition->highest_cloud_term();
522-
if (is_read_replica) {
523-
// The term was not found in cloud storage. A read replica has no
524-
// local log, so a term above the highest cloud term is an unknown
525-
// (future) epoch for it: return no value (an undefined epoch on the
526-
// wire) rather than the cloud start offset, which would sit below
527-
// the consumer's position and spuriously signal truncation.
528-
if (highest_cloud_term.has_value() && term > *highest_cloud_term) {
529-
co_return std::nullopt;
530-
}
531-
// The term is below the earliest cloud segment; the next-highest
532-
// term still lives in cloud, so return the cloud start offset.
533-
co_return _partition->start_cloud_offset();
534-
}
535537
// The requested term is below the first local term (so its data is not
536538
// in the local log) and was not found in cloud storage. Here, we use
537539
// the highest cloud term to disambiguate two cases.
540+
const auto highest_cloud_term = _partition->highest_cloud_term();
538541
if (highest_cloud_term.has_value() && term <= *highest_cloud_term) {
539542
// The term must be lower than the lowest cloud term: the
540543
// next-highest term still lives in cloud, so the answer is the

0 commit comments

Comments
 (0)