@ -271,6 +271,12 @@ func (bc *BrokerClient) ReadRecordsFromOffset(ctx context.Context, session *Brok
if requestedOffset >= cacheStartOffset && requestedOffset <= cacheEndOffset {
if requestedOffset >= cacheStartOffset && requestedOffset <= cacheEndOffset {
// Found in cache
// Found in cache
startIdx := int ( requestedOffset - cacheStartOffset )
startIdx := int ( requestedOffset - cacheStartOffset )
// CRITICAL: Bounds check to prevent race condition where cache is modified between checks
if startIdx < 0 || startIdx >= len ( session . consumedRecords ) {
glog . V ( 2 ) . Infof ( "[FETCH] Cache index out of bounds (race condition): startIdx=%d, cache size=%d, falling through to normal read" ,
startIdx , len ( session . consumedRecords ) )
// Cache was modified, fall through to normal read path
} else {
endIdx := startIdx + maxRecords
endIdx := startIdx + maxRecords
if endIdx > len ( session . consumedRecords ) {
if endIdx > len ( session . consumedRecords ) {
endIdx = len ( session . consumedRecords )
endIdx = len ( session . consumedRecords )
@ -280,6 +286,7 @@ func (bc *BrokerClient) ReadRecordsFromOffset(ctx context.Context, session *Brok
return session . consumedRecords [ startIdx : endIdx ] , nil
return session . consumedRecords [ startIdx : endIdx ] , nil
}
}
}
}
}
// CRITICAL FIX for Schema Registry: Keep subscriber alive across multiple fetch requests
// CRITICAL FIX for Schema Registry: Keep subscriber alive across multiple fetch requests
// Schema Registry expects to make multiple poll() calls on the same consumer connection
// Schema Registry expects to make multiple poll() calls on the same consumer connection