/** * Return the metadata for the next full fetch request. */ public static FetchMetadata newIncremental(int sessionId) { return new FetchMetadata(sessionId, nextEpoch(INITIAL_EPOCH)); }
/** * Handle an error sending the prepared request. * * When a network error occurs, we close any existing fetch session on our next request, * and try to create a new session. * * @param t The exception. */ public void handleError(Throwable t) { log.info("Error sending fetch request {} to node {}: {}.", nextMetadata, node, t.toString()); nextMetadata = nextMetadata.nextCloseExisting(); } }
new ReqEntry("bar", 0, 20, 120, 220)), data.toSend(), data.sessionPartitions()); assertTrue(data.metadata().isFull()); new FetchRequest.PartitionData(10, 110, 210, Optional.empty())); FetchSessionHandler.FetchRequestData data2 = builder2.build(); assertFalse(data2.metadata().isFull()); assertEquals(123, data2.metadata().sessionId()); assertEquals(1, data2.metadata().epoch()); assertMapEquals(reqMap(new ReqEntry("foo", 1, 10, 110, 210)), data2.sessionPartitions()); new FetchRequest.PartitionData(0, 100, 200, Optional.empty())); FetchSessionHandler.FetchRequestData data3 = builder3.build(); assertTrue(data3.metadata().isFull()); assertEquals(INVALID_SESSION_ID, data3.metadata().sessionId()); assertEquals(INITIAL_EPOCH, data3.metadata().epoch()); assertMapsEqual(reqMap(new ReqEntry("foo", 0, 0, 100, 200)), data3.sessionPartitions(), data3.toSend());
nextMetadata = FetchMetadata.INITIAL; } else { nextMetadata = nextMetadata.nextCloseExisting(); } else if (nextMetadata.isFull()) { String problem = verifyFullFetchResponsePartitions(response); if (problem != null) { nextMetadata = FetchMetadata.newIncremental(response.sessionId()); return true; if (problem != null) { log.info("Node {} sent an invalid incremental fetch response with {}", node, problem); nextMetadata = nextMetadata.nextCloseExisting(); return false; } else if (response.sessionId() == INVALID_SESSION_ID) { node, nextMetadata.sessionId(), responseDataToLogString(response)); nextMetadata = FetchMetadata.INITIAL; return true; nextMetadata = nextMetadata.nextIncremental(); return true;
/** * Return the metadata for the next error response. */ public FetchMetadata nextCloseExisting() { return new FetchMetadata(sessionId, INITIAL_EPOCH); }
@Override public String toString() { if (metadata.isFull()) { StringBuilder bld = new StringBuilder("FullFetchRequest("); String prefix = "";
@Override public AbstractResponse getErrorResponse(int throttleTimeMs, Throwable e) { // The error is indicated in two ways: by setting the same error code in all partitions, and by // setting the top-level error code. The form where we set the same error code in all partitions // is needed in order to maintain backwards compatibility with older versions of the protocol // in which there was no top-level error code. Note that for incremental fetch responses, there // may not be any partitions at all in the response. For this reason, the top-level error code // is essential for them. Errors error = Errors.forException(e); LinkedHashMap<TopicPartition, FetchResponse.PartitionData<MemoryRecords>> responseData = new LinkedHashMap<>(); for (Map.Entry<TopicPartition, PartitionData> entry : fetchData.entrySet()) { FetchResponse.PartitionData<MemoryRecords> partitionResponse = new FetchResponse.PartitionData<>(error, FetchResponse.INVALID_HIGHWATERMARK, FetchResponse.INVALID_LAST_STABLE_OFFSET, FetchResponse.INVALID_LOG_START_OFFSET, null, MemoryRecords.EMPTY); responseData.put(entry.getKey(), partitionResponse); } return new FetchResponse<>(error, responseData, throttleTimeMs, metadata.sessionId()); }
new ReqEntry("foo", 1, 10, 110, 210)), data.toSend(), data.sessionPartitions()); assertEquals(INVALID_SESSION_ID, data.metadata().sessionId()); assertEquals(INITIAL_EPOCH, data.metadata().epoch()); new FetchRequest.PartitionData(20, 200, 200, Optional.empty())); FetchSessionHandler.FetchRequestData data2 = builder2.build(); assertFalse(data2.metadata().isFull()); assertMapEquals(reqMap(new ReqEntry("foo", 0, 0, 100, 200), new ReqEntry("foo", 1, 10, 120, 210), new FetchRequest.PartitionData(20, 200, 200, Optional.empty())); FetchSessionHandler.FetchRequestData data4 = builder4.build(); assertTrue(data4.metadata().isFull()); assertEquals(data2.metadata().sessionId(), data4.metadata().sessionId()); assertEquals(INITIAL_EPOCH, data4.metadata().epoch()); assertMapsEqual(reqMap(new ReqEntry("foo", 0, 0, 100, 200), new ReqEntry("foo", 1, 10, 120, 210),
new ReqEntry("foo", 1, 10, 110, 210)), data.toSend(), data.sessionPartitions()); assertEquals(INVALID_SESSION_ID, data.metadata().sessionId()); assertEquals(INITIAL_EPOCH, data.metadata().epoch()); new FetchRequest.PartitionData(0, 100, 200, Optional.empty())); FetchSessionHandler.FetchRequestData data2 = builder2.build(); assertEquals(INVALID_SESSION_ID, data2.metadata().sessionId()); assertEquals(INITIAL_EPOCH, data2.metadata().epoch()); assertMapsEqual(reqMap(new ReqEntry("foo", 0, 0, 100, 200)), data.toSend(), data.sessionPartitions());
metadata = new FetchMetadata(struct.getOrElse(SESSION_ID, INVALID_SESSION_ID), struct.getOrElse(SESSION_EPOCH, FINAL_EPOCH));
public FetchRequestData build() { if (nextMetadata.isFull()) { log.debug("Built full fetch {} for node {} with {}.", nextMetadata, node, partitionsToLogString(next.keySet()));
/** * Return the metadata for the next incremental response. */ public FetchMetadata nextIncremental() { return new FetchMetadata(sessionId, nextEpoch(epoch)); }
toForgetTopics.add(new TopicPartition("foo", 2)); toForgetTopics.add(new TopicPartition("bar", 0)); checkRequest(createFetchRequest(7, new FetchMetadata(123, 456), toForgetTopics)); checkResponse(createFetchResponse(123), 7); checkResponse(createFetchResponse(Errors.FETCH_SESSION_ID_NOT_FOUND, 123), 7);