Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(126)

Delta Between Two Patch Sets: src/pkg/database/sql/sql.go

Issue 6855102: database/sql: expose DB.MaxIdleConns and add DB.SetMaxIdleConns (Closed)
Left Patch Set: Created 12 years, 4 months ago
Right Patch Set: diff -r 616adac0bb59 https://code.google.com/p/go/ Created 12 years, 4 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Right: Side by side diff | Download
« no previous file with change/comment | « no previous file | src/pkg/database/sql/sql_test.go » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
(no file at all)
1 // Copyright 2011 The Go Authors. All rights reserved. 1 // Copyright 2011 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style 2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file. 3 // license that can be found in the LICENSE file.
4 4
5 // Package sql provides a generic interface around SQL (or SQL-like) 5 // Package sql provides a generic interface around SQL (or SQL-like)
6 // databases. 6 // databases.
7 package sql 7 package sql
8 8
9 import ( 9 import (
10 "database/sql/driver" 10 "database/sql/driver"
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 // pool of idle connections. If observing session state is required, 182 // pool of idle connections. If observing session state is required,
183 // either do not share a *DB between multiple concurrent goroutines or 183 // either do not share a *DB between multiple concurrent goroutines or
184 // create and observe all state only within a transaction. Once 184 // create and observe all state only within a transaction. Once
185 // DB.Open is called, the returned Tx is bound to a single isolated 185 // DB.Open is called, the returned Tx is bound to a single isolated
186 // connection. Once Tx.Commit or Tx.Rollback is called, that 186 // connection. Once Tx.Commit or Tx.Rollback is called, that
187 // connection is returned to DB's idle connection pool. 187 // connection is returned to DB's idle connection pool.
188 type DB struct { 188 type DB struct {
189 driver driver.Driver 189 driver driver.Driver
190 dsn string 190 dsn string
191 191
192 » mu sync.Mutex // protects freeConn and closed 192 » mu sync.Mutex // protects freeConn, closed and maxIdleConns
193 » freeConn []driver.Conn 193 » freeConn []driver.Conn
194 » closed bool 194 » closed bool
195 » maxIdleConns int
195 } 196 }
196 197
197 // Open opens a database specified by its database driver name and a 198 // Open opens a database specified by its database driver name and a
198 // driver-specific data source name, usually consisting of at least a 199 // driver-specific data source name, usually consisting of at least a
199 // database name and connection information. 200 // database name and connection information.
200 // 201 //
201 // Most users will open a database via a driver-specific connection 202 // Most users will open a database via a driver-specific connection
202 // helper function that returns a *DB. 203 // helper function that returns a *DB.
203 func Open(driverName, dataSourceName string) (*DB, error) { 204 func Open(driverName, dataSourceName string) (*DB, error) {
204 driver, ok := drivers[driverName] 205 driver, ok := drivers[driverName]
205 if !ok { 206 if !ok {
206 return nil, fmt.Errorf("sql: unknown driver %q (forgotten import ?)", driverName) 207 return nil, fmt.Errorf("sql: unknown driver %q (forgotten import ?)", driverName)
207 } 208 }
208 » return &DB{driver: driver, dsn: dataSourceName}, nil 209 » return &DB{driver: driver, dsn: dataSourceName, maxIdleConns: 2}, nil
209 } 210 }
210 211
211 // Close closes the database, releasing any open resources. 212 // Close closes the database, releasing any open resources.
212 func (db *DB) Close() error { 213 func (db *DB) Close() error {
213 db.mu.Lock() 214 db.mu.Lock()
214 defer db.mu.Unlock() 215 defer db.mu.Unlock()
215 var err error 216 var err error
216 for _, c := range db.freeConn { 217 for _, c := range db.freeConn {
217 err1 := c.Close() 218 err1 := c.Close()
218 if err1 != nil { 219 if err1 != nil {
219 err = err1 220 err = err1
220 } 221 }
221 } 222 }
222 db.freeConn = nil 223 db.freeConn = nil
223 db.closed = true 224 db.closed = true
224 return err 225 return err
225 } 226 }
226 227
227 func (db *DB) maxIdleConns() int { 228 // Adjust the maximum number of permanently retained database connections. This
bradfitz 2013/03/08 22:40:08 See next comment. // SetMaxIdleConns sets ...
228 » const defaultMaxIdleConns = 2 229 // defaults to 2 for historical reasons. N.B. This is not the maximum number of
bradfitz 2013/03/08 22:40:08 I think we should instead make an exported constan
230 // connections that can be open, or the minimum. It is the maximum number that
231 // are retained between uses.
232 func (db *DB) SetMaxIdleConns(v int) int {
233 » db.mu.Lock()
234 » defer db.mu.Unlock()
235 » db.maxIdleConns = v
236 » return v
237 }
238
239 // The current maximum number of idle database connections allowed. See
bradfitz 2013/03/08 22:40:08 Go comment style is to start sentences with the na
240 // SetMaxIdleConns for more information.
241 func (db *DB) MaxIdleConns() int {
229 // TODO(bradfitz): ask driver, if supported, for its default preference 242 // TODO(bradfitz): ask driver, if supported, for its default preference
bradfitz 2013/03/08 22:40:08 probably not here anymore. Probably only once the
julienschmidt 2013/03/09 02:10:03 I like the idea of a config struct ( like I did he
230 » // TODO(bradfitz): let users override? 243 » db.mu.Lock()
231 » return defaultMaxIdleConns 244 » defer db.mu.Unlock()
245 » return db.maxIdleConns
232 } 246 }
233 247
234 // conn returns a newly-opened or cached driver.Conn 248 // conn returns a newly-opened or cached driver.Conn
235 func (db *DB) conn() (driver.Conn, error) { 249 func (db *DB) conn() (driver.Conn, error) {
236 db.mu.Lock() 250 db.mu.Lock()
237 if db.closed { 251 if db.closed {
238 db.mu.Unlock() 252 db.mu.Unlock()
239 return nil, errors.New("sql: database is closed") 253 return nil, errors.New("sql: database is closed")
240 } 254 }
241 if n := len(db.freeConn); n > 0 { 255 if n := len(db.freeConn); n > 0 {
(...skipping 23 matching lines...) Expand all
265 // putConnHook is a hook for testing. 279 // putConnHook is a hook for testing.
266 var putConnHook func(*DB, driver.Conn) 280 var putConnHook func(*DB, driver.Conn)
267 281
268 // putConn adds a connection to the db's free pool. 282 // putConn adds a connection to the db's free pool.
269 // err is optionally the last error that occured on this connection. 283 // err is optionally the last error that occured on this connection.
270 func (db *DB) putConn(c driver.Conn, err error) { 284 func (db *DB) putConn(c driver.Conn, err error) {
271 if err == driver.ErrBadConn { 285 if err == driver.ErrBadConn {
272 // Don't reuse bad connections. 286 // Don't reuse bad connections.
273 return 287 return
274 } 288 }
289 // maxIdle is fetched before we open the lock. Ideally move to an RWLock
290 // instead, and retain it, which may reduce the time over which inconsis tent
291 // numbers of connections may be retained. The value also could just be
292 // modified using atomic.
293 maxIdle := db.MaxIdleConns()
bradfitz 2013/03/08 22:40:08 this is grabbing a lock and unlocking it, even tho
275 db.mu.Lock() 294 db.mu.Lock()
276 if putConnHook != nil { 295 if putConnHook != nil {
277 putConnHook(db, c) 296 putConnHook(db, c)
278 } 297 }
279 » if n := len(db.freeConn); !db.closed && n < db.maxIdleConns() { 298 » if n := len(db.freeConn); !db.closed && n < maxIdle {
280 db.freeConn = append(db.freeConn, c) 299 db.freeConn = append(db.freeConn, c)
281 db.mu.Unlock() 300 db.mu.Unlock()
282 return 301 return
283 } 302 }
284 // TODO: check to see if we need this Conn for any prepared 303 // TODO: check to see if we need this Conn for any prepared
285 // statements which are still active? 304 // statements which are still active?
286 db.mu.Unlock() 305 db.mu.Unlock()
287 c.Close() 306 c.Close()
288 } 307 }
289 308
(...skipping 745 matching lines...) Expand 10 before | Expand all | Expand 10 after
1035 1054
1036 // A Result summarizes an executed SQL command. 1055 // A Result summarizes an executed SQL command.
1037 type Result interface { 1056 type Result interface {
1038 LastInsertId() (int64, error) 1057 LastInsertId() (int64, error)
1039 RowsAffected() (int64, error) 1058 RowsAffected() (int64, error)
1040 } 1059 }
1041 1060
1042 type result struct { 1061 type result struct {
1043 driver.Result 1062 driver.Result
1044 } 1063 }
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b