Closed aovestdipaperino closed 4 weeks ago
Found the problem:
impl Encoder<Option<&ReadOnlyRecords>> for NullableRecords {
fn encode<B: Writable>(&self, buf: &mut B, value: Option<&ReadOnlyRecords>) -> io::Result<()> {
match value {
None => {
if self.0 {
VarInt.encode(buf, 0)?
} else {
Int16.encode(buf, -1)? // Is it correct to use INT16? Maybe old versions didn't support more than 64k records?
}
}
Some(r) => {
let len = r.size() as i16; // PROBLEM: this cast is problematic.
if self.0 {
VarInt.encode(buf, len as i32 + 1)?;
} else {
Int16.encode(buf, len)?; // See above
}
buf.write_records(r)?;
}
}
Ok(())
}
Because the CalculateSize was doing the right thing, the buffer was exactly 2 bytes shorter (encoded len was 0, which turns into a single byte) and the poll on the client side never completed.
You are correct. Fixed bytes definition use Int32 for length.
This is fixed in https://github.com/tisonkun/morax/commit/4ee1579a3a817534720b03a56b3bed27033aad12#diff-e4f0d66a90a44626c385ba5dcf17619d3233b619f2ee9d5141754eda16b082a8 so kafka-api 0.3.1.
The source is https://kafka.apache.org/protocol.html#protocol_types
BYTES: Represents a raw sequence of bytes. First the length N is given as an INT32. Then N bytes follow.
NULLABLE_BYTES: Represents a raw sequence of bytes or null. For non-null values, first the length N is given as an INT32. Then N bytes follow. A null value is encoded with length of -1 and there are no following bytes.
Closed as the development has been moved to Morax under api/kafka-api
.
Explained above.
This is the Java repro. There is also a discrepancy for such large messages between the length of the buffer and the value that comes out of calculateSize