Skip to content

Comments

WIP KTOR-6503: Add connection pooling for CIO client#4407

Closed
e5l wants to merge 1 commit intomainfrom
e5l/cio-connection-pool
Closed

WIP KTOR-6503: Add connection pooling for CIO client#4407
e5l wants to merge 1 commit intomainfrom
e5l/cio-connection-pool

Conversation

@e5l
Copy link
Member

@e5l e5l commented Oct 17, 2024

KTOR-6503 CIO client engine creates new TCP connection for each HTTP requests

@e5l e5l self-assigned this Oct 17, 2024
@e5l e5l requested a review from osipxd October 17, 2024 09:48
Copy link
Member

@osipxd osipxd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea! I have some questions and I see a lot of failing tests. I think the reason might be the inconsistency of socket.isClosed with JVM sockets isOpen flag.

}

private fun releaseConnection() {
val address = connectionAddress ?: return
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we remove the field connectionAddress?

) {
private val connectionsLimit: Int,
private val addressConnectionsLimit: Int,
private val keepAliveTime: Long = 30_000, // Default keep-alive time in milliseconds
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shall we use Duration here?

private fun getPooledConnection(address: InetSocketAddress): PooledConnection? {
LOG.trace { "Checking for pooled connection for address: $address" }
val connections = connectionPool[address] ?: return null
val currentTime = GMTDate().timestamp
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just wondering why we don't use kotlinx.datetime? Are we waiting for a stable version?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found the issue: KTOR-2721 Migrate from GMTDate to kotlinx.datetime.Instant

LOG.trace { "Releasing connection for address: ${socket.remoteAddress}" }

if (socket.isClosed) {
LOG.warn("Attempted to release a closed connection for address: ${socket.remoteAddress}")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On JVM sun.nio.ch.SocketChannelImpl.getRemoteAddress calls ensureOpen under the hood, so here will be a crash

fun release(socket: Socket) {
LOG.trace { "Releasing connection for address: ${socket.remoteAddress}" }

if (socket.isClosed) {
Copy link
Member

@osipxd osipxd Oct 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This flag seems out of sync with SocketChannel.isOpen on JVM. As a result, we put closed connections to the pool and get a lot of test failures with java.nio.channels.ClosedChannelException

it.close()
return@removeAll true
}
false
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we also remove closed connections here? Is it possible to have a closed connection in the pool?

@osipxd osipxd changed the title WIP Add connection pooling for CIO client WIP KTOR-6503: Add connection pooling for CIO client Mar 6, 2025
@e5l e5l closed this Mar 26, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants