This is a quick attempt to improve connection startup time by caching
the properties that are loaded when a connection is ready in the pool,
so that further connections don't incur this cost.
I'm not entirely convinced by the interface here, perhaps these 3 items
could live in their own type and that be passed around for clearer code,
but the idea works well.
If no connections are available, and the pool is reset, there will
be no connections at all in the pool. So the pool needs to be able
to create a connection after waiting for a connection to be released.
- Use unlisten * when releasing connection with listeners to pool
- Only unlisten on releasing connection to pool when necessary
- Remove Unlisten("") as was to release all listeners
ErrDeadConn is returned when calling an already dead connection. But the initial failure returns the real error. So we check for IsAlive instead of ErrDeadConn.
Added test for ConnPool.Begin retry logic.
Benchmarks revealed that it is no longer performant enough to pull
its own wait. Using go_db_bench to copy JSON results to HTTP responses
it was ~20% *slower* for ~4BK responses and less than 10% faster for
+1MB responses.
The the performance problem was in io.CopyN / io.Copy. io.Copy
allocates a 32KB buffer if it doesn't have io.WriterTo or io.ReaderFrom
available. This extra alloc on every request was more expensive than
just reading the result into a string and writing it out to the response
body.
Tests indicated that if MsgReader implemented a custom Copy that used a
shared buffer it might have a few percent performance advantage. But the
additional complexity is not worth the performance gain.