DUE TO SPAM, SIGN-UP IS DISABLED. Goto Selfserve wiki signup and request an account.
Status
Current state: Under discussion
Discussion thread: TODO
JIRA: KAFKA-9474
Please keep the discussion on the mailing list rather than commenting on the wiki (wiki discussions get unwieldy fast).
Motivation
The Kafka RPC message format has no inherent support for handling Double values, however some interfaces may benefit from their addition. The particular motivating case is in implementing a quotas admin client API (KIP-546), which natively accepts Double values, but there's no direct way to define them in the RPC messages. Instead of attempting to work around this limitation, it'd be useful to extent the RPC format to support Double values.
Public Interfaces
Adds double as a possible RPC protocol field type.
This has no immediate impact to any existing public interfaces. It'll permit new and existing messages to add double fields to their structure in subsequent iterations.
Proposed Changes
Adds the following code block to clients/src/main/java/org/apache/kafka/common/protocol/types/Type.java and support code to Struct.java.
Note that, while the ByteBuffer natively supports serializing a Double, the format in which the value is serialized is not strongly specified, so the preference is to explicitly ensure a standard representation using Double.doubleToRawLongBits() and Double.longBitsToDouble().
/**
* Read a double-precision 64-bit format IEEE 754 value.
*
* @param buffer The buffer to read from
* @return The long value read
*/
public static double readDouble(ByteBuffer buffer) {
return Double.longBitsToDouble(buffer.getLong());
}
/**
* Write the given double following the double-precision 64-bit format IEEE 754 value into the buffer.
*
* @param value The value to write
* @param buffer The buffer to write to
*/
public static void writeDouble(double value, ByteBuffer buffer) {
buffer.putLong(Double.doubleToRawLongBits(value));
}
The protocol type definition:
public static final DocumentedType DOUBLE = new DocumentedType() {
@Override
public void write(ByteBuffer buffer, Object o) {
ByteUtils.writeDouble((Double) o, buffer);
}
@Override
public Object read(ByteBuffer buffer) {
return ByteUtils.readDouble(buffer);
}
@Override
public int sizeOf(Object o) {
return 8;
}
@Override
public String typeName() {
return "DOUBLE";
}
@Override
public Double validate(Object item) {
if (item instanceof Double)
return (Double) item;
else
throw new SchemaException(item + " is not a Double.");
}
@Override
public String documentation() {
return "Represents a double-precision 64-bit format IEEE 754 value. " +
"The values are encoded using eight bytes in network byte order (big-endian).";
}
};
In generator/src/main/java/org/apache/kafka/message/MessageGenerator.java, the following operations will be used (code omitted for brevity):
Hash code: Double.hashCode(value) Empty value: (double) 0 Parsing a default value string: Double.parseDouble(defaultValue)
Compatibility, Deprecation, and Migration Plan
- No deprecation or migration necessary.
- Compatibility
- Let's say existing message DescribeConfigsRequest added a
doublefield.- If the client is old but server is new, then it won't attempt to set the double field, so it won't be serialized in the request.
- If the client is new but server is old, then the server won't understand the request due to a version mismatch (this setup is generally not advised).
- If a new request with a
doublefield is added, both client and server must be aware of the message, and therefore will be aware of thedoublemessage type.
- Let's say existing message DescribeConfigsRequest added a
Rejected Alternatives
- Requiring the application to serialize into an existing RPC type (int64). This is prone to error and introduces additional complexity in areas where the application shouldn't have to worry about it.