mirror of https://github.com/jackc/pgx.git
Cache connection properties in the pool
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.pull/141/head
parent
d9fb1351fb
commit
a282d9df90
19
conn.go
19
conn.go
|
@ -63,8 +63,8 @@ type Conn struct {
|
||||||
logLevel int
|
logLevel int
|
||||||
mr msgReader
|
mr msgReader
|
||||||
fp *fastpath
|
fp *fastpath
|
||||||
pgsql_af_inet byte
|
pgsql_af_inet *byte
|
||||||
pgsql_af_inet6 byte
|
pgsql_af_inet6 *byte
|
||||||
busy bool
|
busy bool
|
||||||
poolResetCount int
|
poolResetCount int
|
||||||
preallocatedRows []Rows
|
preallocatedRows []Rows
|
||||||
|
@ -137,9 +137,16 @@ func (e ProtocolError) Error() string {
|
||||||
// config.Host must be specified. config.User will default to the OS user name.
|
// config.Host must be specified. config.User will default to the OS user name.
|
||||||
// Other config fields are optional.
|
// Other config fields are optional.
|
||||||
func Connect(config ConnConfig) (c *Conn, err error) {
|
func Connect(config ConnConfig) (c *Conn, err error) {
|
||||||
|
return connect(config, nil, nil, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func connect(config ConnConfig, pgTypes map[Oid]PgType, pgsql_af_inet *byte, pgsql_af_inet6 *byte) (c *Conn, err error) {
|
||||||
c = new(Conn)
|
c = new(Conn)
|
||||||
|
|
||||||
c.config = config
|
c.config = config
|
||||||
|
c.PgTypes = pgTypes
|
||||||
|
c.pgsql_af_inet = pgsql_af_inet
|
||||||
|
c.pgsql_af_inet6 = pgsql_af_inet6
|
||||||
|
|
||||||
if c.config.LogLevel != 0 {
|
if c.config.LogLevel != 0 {
|
||||||
c.logLevel = c.config.LogLevel
|
c.logLevel = c.config.LogLevel
|
||||||
|
@ -283,15 +290,19 @@ func (c *Conn) connect(config ConnConfig, network, address string, tlsConfig *tl
|
||||||
c.log(LogLevelInfo, "Connection established")
|
c.log(LogLevelInfo, "Connection established")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if c.PgTypes == nil {
|
||||||
err = c.loadPgTypes()
|
err = c.loadPgTypes()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.pgsql_af_inet == nil || c.pgsql_af_inet6 == nil {
|
||||||
err = c.loadInetConstants()
|
err = c.loadInetConstants()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
default:
|
default:
|
||||||
|
@ -336,8 +347,8 @@ func (c *Conn) loadInetConstants() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
c.pgsql_af_inet = ipv4[0]
|
c.pgsql_af_inet = &ipv4[0]
|
||||||
c.pgsql_af_inet6 = ipv6[0]
|
c.pgsql_af_inet6 = &ipv6[0]
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,9 @@ type ConnPool struct {
|
||||||
closed bool
|
closed bool
|
||||||
preparedStatements map[string]*PreparedStatement
|
preparedStatements map[string]*PreparedStatement
|
||||||
acquireTimeout time.Duration
|
acquireTimeout time.Duration
|
||||||
|
pgTypes map[Oid]PgType
|
||||||
|
pgsql_af_inet *byte
|
||||||
|
pgsql_af_inet6 *byte
|
||||||
}
|
}
|
||||||
|
|
||||||
type ConnPoolStat struct {
|
type ConnPoolStat struct {
|
||||||
|
@ -244,11 +247,15 @@ func (p *ConnPool) Stat() (s ConnPoolStat) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *ConnPool) createConnection() (*Conn, error) {
|
func (p *ConnPool) createConnection() (*Conn, error) {
|
||||||
c, err := Connect(p.config)
|
c, err := connect(p.config, p.pgTypes, p.pgsql_af_inet, p.pgsql_af_inet6)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p.pgTypes = c.PgTypes
|
||||||
|
p.pgsql_af_inet = c.pgsql_af_inet
|
||||||
|
p.pgsql_af_inet6 = c.pgsql_af_inet6
|
||||||
|
|
||||||
if p.afterConnect != nil {
|
if p.afterConnect != nil {
|
||||||
err = p.afterConnect(c)
|
err = p.afterConnect(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -1576,10 +1576,10 @@ func encodeIPNet(w *WriteBuf, oid Oid, value net.IPNet) error {
|
||||||
switch len(value.IP) {
|
switch len(value.IP) {
|
||||||
case net.IPv4len:
|
case net.IPv4len:
|
||||||
size = 8
|
size = 8
|
||||||
family = w.conn.pgsql_af_inet
|
family = *w.conn.pgsql_af_inet
|
||||||
case net.IPv6len:
|
case net.IPv6len:
|
||||||
size = 20
|
size = 20
|
||||||
family = w.conn.pgsql_af_inet6
|
family = *w.conn.pgsql_af_inet6
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("Unexpected IP length: %v", len(value.IP))
|
return fmt.Errorf("Unexpected IP length: %v", len(value.IP))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue