Go version 1.8.3

In DB.QueryContext(), Go will close long live connection which exceeded the 
duration setted by  DB.SetConnMaxLifetime(), the code is below
database/sql/sql.go
 895 func (db *DB) conn(ctx context.Context, strategy connReuseStrategy) 
(*driverConn, error) {
 896     db.mu.Lock()
 897     if db.closed {
 898         db.mu.Unlock()
 899         return nil, errDBClosed
 900     }
 901     // Check if the context is expired.
 902     select {
 903     default:
 904     case <-ctx.Done():
 905         db.mu.Unlock()
 906         return nil, ctx.Err()
 907     }
 908     lifetime := db.maxLifetime
 909 
 910     // Prefer a free connection, if possible.
 911     numFree := len(db.freeConn)
 912     if strategy == cachedOrNewConn && numFree > 0 {
 913         conn := db.freeConn[0]
 914         copy(db.freeConn, db.freeConn[1:])
 915         db.freeConn = db.freeConn[:numFree-1]
 916         conn.inUse = true
 917         db.mu.Unlock()
* 918         if conn.expired(lifetime) {*
* 919             conn.Close()*
 920             return nil, driver.ErrBadConn
 921         }                                                             
                                                                            
              
 922         return conn, nil
 923     }


The problem is if driver.Close() has some handshake to tear down the 
connection, this may introduce unexpected latency. But the driver.Conn 
interface not mention this.
database/sql/driver/driver.go
 143 type Conn interface {
 144     // Prepare returns a prepared statement, bound to this connection.
 145     Prepare(query string) (Stmt, error)
 146 
 147     // Close invalidates and potentially stops any current
 148     // prepared statements and transactions, marking this
 149     // connection as no longer in use.
 150     //
 151     // Because the sql package maintains a free pool of
 152     // connections and only calls Close when there's a surplus of
 153     // idle connections, it shouldn't be necessary for drivers to
 154     // do their own connection caching.                               
                                                                            
              
 155     Close() error
 156 
 157     // Begin starts and returns a new transaction.
 158     //
 159     // Deprecated: Drivers should implement ConnBeginTx instead (or 
additionally).
 160     Begin() (Tx, error)
 161 }

There is already a goroutine to clean the connections, why still need a 
synchronous check? 
database/sql/sql.go
 750 func (db *DB) connectionCleaner(d time.Duration) {                     
                                                                            
             
 751     const minInterval = time.Second
 752 
 753     if d < minInterval {
 754         d = minInterval
 755     }
 756     t := time.NewTimer(d)
 757 
 758     for {
 759         select {
 760         case <-t.C:
 761         case <-db.cleanerCh: // maxLifetime was changed or db was 
closed.
 762         }
 763 
 764         db.mu.Lock()
 765         d = db.maxLifetime
 766         if db.closed || db.numOpen == 0 || d <= 0 {
 767             db.cleanerCh = nil
 768             db.mu.Unlock()
 769             return
 770         }
 771 
 772         expiredSince := nowFunc().Add(-d)
 773         var closing []*driverConn
 774         for i := 0; i < len(db.freeConn); i++ {
 775             c := db.freeConn[i]
 776             if c.createdAt.Before(expiredSince) {
 777                 closing = append(closing, c)
 778                 last := len(db.freeConn) - 1
 779                 db.freeConn[i] = db.freeConn[last]
 780                 db.freeConn[last] = nil
 781                 db.freeConn = db.freeConn[:last]
 782                 i--
 783             }
 784         }



Is this by design or need to be fixed? 

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to