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 {
@ -431,14 +436,15 @@ func handle(s *Server, c *conn) {
// conn represents a client connection // conn represents a client connection
type conn struct { type conn struct {
conn net.Conn conn net.Conn
wr *Writer wr *Writer
rd *Reader rd *Reader
addr string addr string
ctx interface{} ctx interface{}
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 {
@ -541,15 +547,16 @@ type Command struct {
// Server defines a server for clients for managing client connections. // Server defines a server for clients for managing client connections.
type Server struct { type Server struct {
mu sync.Mutex mu sync.Mutex
net string net string
laddr string laddr string
handler func(conn Conn, cmd Command) handler func(conn Conn, cmd Command)
accept func(conn Conn) bool accept func(conn Conn) bool
closed func(conn Conn, err error) closed func(conn Conn, err error)
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()
}