From 0205c889f6fc6e5db4a441ef00dc0810b0cc6c11 Mon Sep 17 00:00:00 2001 From: tidwall Date: Thu, 5 Nov 2020 16:54:41 -0700 Subject: [PATCH] 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 --- redcon.go | 49 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/redcon.go b/redcon.go index 74b5464..63d497f 100644 --- a/redcon.go +++ b/redcon.go @@ -10,6 +10,7 @@ import ( "net" "strings" "sync" + "time" "github.com/tidwall/btree" "github.com/tidwall/match" @@ -356,6 +357,7 @@ func serve(s *Server) error { rd: NewReader(lnconn), } s.mu.Lock() + c.idleClose = s.idleClose s.conns[c] = true s.mu.Unlock() 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 for { // read pipeline commands + if c.idleClose != 0 { + c.conn.SetReadDeadline(time.Now().Add(c.idleClose)) + } cmds, err := c.rd.readCommands(nil) if err != nil { if err, ok := err.(*errProtocol); ok { @@ -431,14 +436,15 @@ func handle(s *Server, c *conn) { // conn represents a client connection type conn struct { - conn net.Conn - wr *Writer - rd *Reader - addr string - ctx interface{} - detached bool - closed bool - cmds []Command + conn net.Conn + wr *Writer + rd *Reader + addr string + ctx interface{} + detached bool + closed bool + cmds []Command + idleClose time.Duration } func (c *conn) Close() error { @@ -541,15 +547,16 @@ type Command struct { // Server defines a server for clients for managing client connections. type Server struct { - mu sync.Mutex - net string - laddr string - handler func(conn Conn, cmd Command) - accept func(conn Conn) bool - closed func(conn Conn, err error) - conns map[*conn]bool - ln net.Listener - done bool + mu sync.Mutex + net string + laddr string + handler func(conn Conn, cmd Command) + accept func(conn Conn) bool + closed func(conn Conn, err error) + conns map[*conn]bool + ln net.Listener + done bool + idleClose time.Duration // AcceptError is an optional function used to handle Accept errors. AcceptError func(err error) @@ -1346,3 +1353,11 @@ func (ps *PubSub) unsubscribe(conn Conn, pattern, all bool, channel string) { } 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() +}