Added SetIdleClose

It's now possible to automatically close idle connections by
calling the SetIdleClose method.

    s := redcon.NewServer(...)
    s.SetIdleClose(time.Minute*5)
    s.ListenAndServe()

closed #34
This commit is contained in:
tidwall 2020-11-05 16:54:41 -07:00
parent 2d74bb5825
commit 0205c889f6
1 changed files with 32 additions and 17 deletions

View File

@ -10,6 +10,7 @@ import (
"net" "net"
"strings" "strings"
"sync" "sync"
"time"
"github.com/tidwall/btree" "github.com/tidwall/btree"
"github.com/tidwall/match" "github.com/tidwall/match"
@ -356,6 +357,7 @@ func serve(s *Server) error {
rd: NewReader(lnconn), rd: NewReader(lnconn),
} }
s.mu.Lock() s.mu.Lock()
c.idleClose = s.idleClose
s.conns[c] = true s.conns[c] = true
s.mu.Unlock() s.mu.Unlock()
if s.accept != nil && !s.accept(c) { if s.accept != nil && !s.accept(c) {
@ -395,6 +397,9 @@ func handle(s *Server, c *conn) {
// read commands and feed back to the client // read commands and feed back to the client
for { for {
// read pipeline commands // read pipeline commands
if c.idleClose != 0 {
c.conn.SetReadDeadline(time.Now().Add(c.idleClose))
}
cmds, err := c.rd.readCommands(nil) cmds, err := c.rd.readCommands(nil)
if err != nil { if err != nil {
if err, ok := err.(*errProtocol); ok { if err, ok := err.(*errProtocol); ok {
@ -439,6 +444,7 @@ type conn struct {
detached bool detached bool
closed bool closed bool
cmds []Command cmds []Command
idleClose time.Duration
} }
func (c *conn) Close() error { func (c *conn) Close() error {
@ -550,6 +556,7 @@ type Server struct {
conns map[*conn]bool conns map[*conn]bool
ln net.Listener ln net.Listener
done bool done bool
idleClose time.Duration
// AcceptError is an optional function used to handle Accept errors. // AcceptError is an optional function used to handle Accept errors.
AcceptError func(err error) AcceptError func(err error)
@ -1346,3 +1353,11 @@ func (ps *PubSub) unsubscribe(conn Conn, pattern, all bool, channel string) {
} }
sconn.dconn.Flush() sconn.dconn.Flush()
} }
// SetIdleClose will automatically close idle connections after the specified
// duration. Use zero to disable this feature.
func (s *Server) SetIdleClose(dur time.Duration) {
s.mu.Lock()
s.idleClose = dur
s.mu.Unlock()
}