jersey
jersey copied to clipboard
JdkConnector does not properly cleanup ERROR state connections
I am using Dropwizard 4 (Jersey 3.0.5) on Java 17. This problem exists in 3.0.12 as well.
When an HttpConnection transitions to ERROR from IDLE state, the connection gets closed but not removed from DestinationConnectionPool. This results in the next request failing regardless of whether the server has been restarted.
My guess is that cleanClosedConnection should be called at: https://github.com/eclipse-ee4j/jersey/blob/fc78757d0b2ece3f03e2c35f709fe070c350fc96/connectors/jdk-connector/src/main/java/org/glassfish/jersey/jdk/connector/internal/DestinationConnectionPool.java#L287
@dude-abides which is the request or how do you receive the ERROR state after which a connection is not removed?
Step to recreate
- Run a server and client on the same machine
- Make one request to server successfully
- Shutdown the server (forced)
- Make another request to the server
So, I've retried the described behavior.
The main difference I've got is:
When the server is being shut down between requests, the request that goes to nowhere results in the ERROR state but in the DestinationConnectionPool it hits the
case CONNECTING: {
removeAllPendingWithError(connection.getError());
return;
}
case because the oldState is CONNECTING thus the removeAllPendingWithError(connection.getError()); properly cleans all connections and the next request which runs to the already started server passes OK. Furthermore, the line in the DestinationConnectionPool you are referring to handles unexpected behavior by throwing the IllegalStateException("Illegal state transition, old state: " + oldState + " new state: " + newState); exception which terminates all connections in the flow instantly. I'm not sure, how it's possible to bypass the CONNECTING state from the IDLE. All my investigations resulted in the flow that defines the IDLE state as the primary and then in case of sending the request the flow goes to the CONNECTING state. If you have some special use case that somehow manages to violate this sequence please share it I'll try to make it impossible :)