private String formatNodeIds(Node[] nodes) { StringBuilder b = new StringBuilder("["); if (nodes != null) { for (int i = 0; i < nodes.length; i++) { b.append(nodes[i].idString()); if (i < nodes.length - 1) b.append(','); } } b.append("]"); return b.toString(); }
/** * Return the poll delay in milliseconds based on both connection and throttle delay. * @param node the connection to check * @param now the current time in ms */ @Override public long pollDelayMs(Node node, long now) { return connectionStates.pollDelayMs(node.idString(), now); }
/** * Check if authentication to this node has failed, based on the connection state. Authentication failures are * propagated without any retries. * * @param node the node to check * @return an AuthenticationException iff authentication has failed, null otherwise */ @Override public AuthenticationException authenticationException(Node node) { return connectionStates.authenticationException(node.idString()); }
/** * Check if the connection of the node has failed, based on the connection state. Such connection failure are * usually transient and can be resumed in the next {@link #ready(org.apache.kafka.common.Node, long)} } * call, but there are cases where transient failures needs to be caught and re-acted upon. * * @param node the node to check * @return true iff the connection has failed and the node is disconnected */ @Override public boolean connectionFailed(Node node) { return connectionStates.isDisconnected(node.idString()); }
private void handlePendingDisconnects() { lock.lock(); try { while (true) { Node node = pendingDisconnects.poll(); if (node == null) break; failUnsentRequests(node, DisconnectException.INSTANCE); client.disconnect(node.idString()); } } finally { lock.unlock(); } }
/** * Return true if there's at least one connection establishment is currently underway */ private boolean isAnyNodeConnecting() { for (Node node : fetchNodes()) { if (connectionStates.isConnecting(node.idString())) { return true; } } return false; }
@Override public String toString() { return String.format("Partition(topic = %s, partition = %d, leader = %s, replicas = %s, isr = %s, offlineReplicas = %s)", topic, partition, leader == null ? "none" : leader.idString(), formatNodeIds(replicas), formatNodeIds(inSyncReplicas), formatNodeIds(offlineReplicas)); }
private ClientResponse sendAndAwaitInitProducerIdRequest(Node node) throws IOException { String nodeId = node.idString(); InitProducerIdRequest.Builder builder = new InitProducerIdRequest.Builder(null); ClientRequest request = client.newClientRequest(nodeId, builder, time.milliseconds(), true, requestTimeoutMs, null); return NetworkClientUtils.sendAndReceive(client, request, time); }
public void authenticationFailed(Node node, long blackoutMs) { pendingAuthenticationErrors.remove(node); authenticationErrors.put(node, (AuthenticationException) Errors.SASL_AUTHENTICATION_FAILED.exception()); disconnect(node.idString()); blackout(node, blackoutMs); }
public void setUnreachable(Node node, long durationMs) { disconnect(node.idString()); unreachable.add(node, durationMs); }
@Override public boolean ready(Node node, long now) { if (blackedOut.contains(node, now)) return false; if (unreachable.contains(node, now)) { blackout(node, 100); return false; } if (delayedReady.contains(node, now)) return false; ready.add(node.idString()); return true; }
@Override public boolean conditionMet() { client.poll(0, time.milliseconds()); return client.hasInFlightRequests(node.idString()); } }, 1000, "");
@Test public void testServerDisconnectAfterInternalApiVersionRequest() throws Exception { awaitInFlightApiVersionRequest(); selector.serverDisconnect(node.idString()); // The failed ApiVersion request should not be forwarded to upper layers List<ClientResponse> responses = client.poll(0, time.milliseconds()); assertFalse(client.hasInFlightRequests(node.idString())); assertTrue(responses.isEmpty()); }
private void setExpectedApiVersionsResponse(ApiVersionsResponse response) { short apiVersionsResponseVersion = response.apiVersion(ApiKeys.API_VERSIONS.id).maxVersion; ByteBuffer buffer = response.serialize(apiVersionsResponseVersion, new ResponseHeader(0)); selector.delayedReceive(new DelayedReceive(node.idString(), new NetworkReceive(node.idString(), buffer))); }
@Test public void testClientDisconnectAfterInternalApiVersionRequest() throws Exception { awaitInFlightApiVersionRequest(); client.disconnect(node.idString()); assertFalse(client.hasInFlightRequests(node.idString())); // The failed ApiVersion request should not be forwarded to upper layers List<ClientResponse> responses = client.poll(0, time.milliseconds()); assertTrue(responses.isEmpty()); }
@Test public void testDefaultRequestTimeout() { awaitReady(client, node); // has to be before creating any request, as it may send ApiVersionsRequest and its response is mocked with correlation id 0 ProduceRequest.Builder builder = ProduceRequest.Builder.forCurrentMagic((short) 1, 1000, Collections.emptyMap()); ClientRequest request = client.newClientRequest(node.idString(), builder, time.milliseconds(), true); assertEquals(defaultRequestTimeoutMs, request.requestTimeoutMs()); testRequestTimeout(request); }
private void testRequestTimeout(ClientRequest request) { client.send(request, time.milliseconds()); time.sleep(request.requestTimeoutMs() + 1); List<ClientResponse> responses = client.poll(0, time.milliseconds()); assertEquals(1, responses.size()); ClientResponse clientResponse = responses.get(0); assertEquals(node.idString(), clientResponse.destination()); assertTrue("Expected response to fail due to disconnection", clientResponse.wasDisconnected()); }
@Test public void testRequestTimeout() { awaitReady(client, node); // has to be before creating any request, as it may send ApiVersionsRequest and its response is mocked with correlation id 0 ProduceRequest.Builder builder = ProduceRequest.Builder.forCurrentMagic((short) 1, 1000, Collections.emptyMap()); TestCallbackHandler handler = new TestCallbackHandler(); int requestTimeoutMs = defaultRequestTimeoutMs + 5000; ClientRequest request = client.newClientRequest(node.idString(), builder, time.milliseconds(), true, requestTimeoutMs, handler); assertEquals(requestTimeoutMs, request.requestTimeoutMs()); testRequestTimeout(request); }
@Test public void testDisconnectWithUnsentRequests() { RequestFuture<ClientResponse> future = consumerClient.send(node, heartbeat()); assertTrue(consumerClient.hasPendingRequests(node)); assertFalse(client.hasInFlightRequests(node.idString())); consumerClient.disconnectAsync(node); consumerClient.pollNoWakeup(); assertTrue(future.failed()); assertTrue(future.exception() instanceof DisconnectException); }
@Test public void testDisconnectWithInFlightRequests() { RequestFuture<ClientResponse> future = consumerClient.send(node, heartbeat()); consumerClient.pollNoWakeup(); assertTrue(consumerClient.hasPendingRequests(node)); assertTrue(client.hasInFlightRequests(node.idString())); consumerClient.disconnectAsync(node); consumerClient.pollNoWakeup(); assertTrue(future.failed()); assertTrue(future.exception() instanceof DisconnectException); }