Skip to content

Commit f873ced

Browse files
committed
Add SocketExpireTime to avoid long live sockets
1 parent 1cd2673 commit f873ced

File tree

2 files changed

+37
-22
lines changed

2 files changed

+37
-22
lines changed

session.go

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,9 @@ type DialInfo struct {
593593
// before being removed and closed.
594594
MaxIdleTimeMS int
595595

596+
// Socket expire time to avoid long live connections
597+
SocketExpireTime time.Duration
598+
596599
// DialServer optionally specifies the dial function for establishing
597600
// connections with the MongoDB servers.
598601
DialServer func(addr *ServerAddr) (net.Conn, error)
@@ -613,28 +616,29 @@ func (i *DialInfo) Copy() *DialInfo {
613616
}
614617

615618
info := &DialInfo{
616-
Timeout: i.Timeout,
617-
Database: i.Database,
618-
ReplicaSetName: i.ReplicaSetName,
619-
Source: i.Source,
620-
Service: i.Service,
621-
ServiceHost: i.ServiceHost,
622-
Mechanism: i.Mechanism,
623-
Credentials: i.Credentials,
624-
Username: i.Username,
625-
Password: i.Password,
626-
PoolLimit: i.PoolLimit,
627-
PoolTimeout: i.PoolTimeout,
628-
ReadTimeout: i.ReadTimeout,
629-
WriteTimeout: i.WriteTimeout,
630-
AppName: i.AppName,
631-
ReadPreference: readPreference,
632-
FailFast: i.FailFast,
633-
Direct: i.Direct,
634-
MinPoolSize: i.MinPoolSize,
635-
MaxIdleTimeMS: i.MaxIdleTimeMS,
636-
DialServer: i.DialServer,
637-
Dial: i.Dial,
619+
Timeout: i.Timeout,
620+
Database: i.Database,
621+
ReplicaSetName: i.ReplicaSetName,
622+
Source: i.Source,
623+
Service: i.Service,
624+
ServiceHost: i.ServiceHost,
625+
Mechanism: i.Mechanism,
626+
Credentials: i.Credentials,
627+
Username: i.Username,
628+
Password: i.Password,
629+
PoolLimit: i.PoolLimit,
630+
PoolTimeout: i.PoolTimeout,
631+
ReadTimeout: i.ReadTimeout,
632+
WriteTimeout: i.WriteTimeout,
633+
AppName: i.AppName,
634+
ReadPreference: readPreference,
635+
FailFast: i.FailFast,
636+
Direct: i.Direct,
637+
MinPoolSize: i.MinPoolSize,
638+
MaxIdleTimeMS: i.MaxIdleTimeMS,
639+
SocketExpireTime: i.SocketExpireTime,
640+
DialServer: i.DialServer,
641+
Dial: i.Dial,
638642
}
639643

640644
info.Addrs = make([]string, len(i.Addrs))

socket.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ package mgo
2929
import (
3030
"errors"
3131
"fmt"
32+
"math/rand"
3233
"net"
3334
"strings"
3435
"sync"
@@ -59,6 +60,7 @@ type mongoSocket struct {
5960
serverInfo *mongoServerInfo
6061
closeAfterIdle bool
6162
lastTimeUsed time.Time // for time based idle socket release
63+
expireTime time.Time // for avoid long lived sockets
6264
sendMeta sync.Once
6365

6466
dialInfo *DialInfo
@@ -197,6 +199,12 @@ func newSocket(server *mongoServer, conn net.Conn, info *DialInfo) *mongoSocket
197199
replyFuncs: make(map[uint32]replyFunc),
198200
dialInfo: info,
199201
}
202+
if info.SocketExpireTime > 0 {
203+
expireTime := info.SocketExpireTime
204+
expireTime += time.Duration(rand.Uint64() % (uint64(expireTime) / 4))
205+
socket.expireTime = coarseTime.Now().Add(expireTime)
206+
}
207+
200208
socket.gotNonce.L = &socket.Mutex
201209
if err := socket.InitialAcquire(server.Info(), info); err != nil {
202210
panic("newSocket: InitialAcquire returned error: " + err.Error())
@@ -286,6 +294,9 @@ func (socket *mongoSocket) Release() {
286294
stats.socketsInUse(-1)
287295
server := socket.server
288296
closeAfterIdle := socket.closeAfterIdle
297+
if !closeAfterIdle && !socket.expireTime.IsZero() && coarseTime.Now().After(socket.expireTime) {
298+
closeAfterIdle = true
299+
}
289300
socket.Unlock()
290301
socket.LogoutAll()
291302
if closeAfterIdle {

0 commit comments

Comments
 (0)