twitter/finagle — pull request #57 by jluxenberg (2012-01-04 22:51:16+00:00)
Title: FATAL error in logs: "more-than-once release for channel!" when using connection pooling

When using the following ClientBuilder:

val clientBuilder = ClientBuilder()
.codec(Http())
.cluster(new AWSElbCluster(config.url))
.connectionTimeout(20.seconds)
.hostConnectionLimit(config.maxConnections)
.hostConnectionMaxIdleTime(30.seconds)
.hostConnectionMaxLifeTime(2.minute)
.retries(1)
.reportTo(new OstrichStatsReceiver)
.name(config.url.toString)

we get benign FATAL errors in the logs (see https://gist.github.com/1557984). I found that this was the result of an interaction between the ExpiringService wrapper and the WatermarkPool. The time-based timeout in ExpiringService would cause 'release' to be called on the underlying service, then later on the WatermarkPool would attempt to use the connection, find out that it is unusable, and then also attempt to call 'release' on it.

This commit fixes this problem in ExpiringService by ensuring "release" is only called once on the underlying service.