I've run into a problem where I create a new connection each request and it is terribly inefficient.
I would like to allow a set maximum number of TLS connections to stay open/cached on my client at once. When data is ready to be transmitted it first checks if there is an idle connection, then it checks if it can create a new connection (i.e. number of open connections < maximum allowed). If both are false then it has to wait until either a connection becomes idle or the number of open connections decreases. Connections should also be killed after they have been idle for a set amount of time.
Here is some (bad) pseudocode of what I have in mind. Could I have some suggestions?
func newTLSConnection(netDialer, host, tlsConfig) (tls.Con) {
// Set up the certs
// ...
// Make A TLS Connection
con, _ := tls.DialWithDialer(netDialer, "tcp", host, tlsConfig)
return con
}
func (con tls.Con) Do (someData []byte) {
// If con
// Send some date to the server
_, _ := con.Write(someData)
// Get response from server
response := make([]byte, 100)
_, _ := io.ReadFull(con, response)
return
}
main(){
var cons []tls.Con
maxConSize := 3
while {
if allConsInSliceAreBusy() && len(cons) < maxConSize{
newCon = NewTLSConnection(...)
cons = append(cons, newCon)
conToUse := newCon
conToUse.Do([]byte("stuff"))
} else if !allConsInSliceAreBusy() {
conToUse := firstOpenConInCons()
conToUse.Do([]byte("stuff"))
} else{
// NOP. Max cons created and they are all busy.
// Wait for one to become idle or close.
}
}
}
Thank you!
What you ask about is called connection pooling. Have a look at Fasthttp package source code: https://github.com/valyala/fasthttp/blob/master/client.go. You can even use this library or another one for your purpose.
You can find the acquireConn
func which does exactly what you need: