Skip to content

Commit

Permalink
TCP server connection idle timeout
Browse files Browse the repository at this point in the history
Implement a idle TCP connection timeout for plain and pickle inputs.

Issue: #250
  • Loading branch information
guillaumeautran committed Jan 17, 2018
1 parent cf65529 commit 2e8abd2
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 10 deletions.
1 change: 1 addition & 0 deletions cfg/cfg.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
type Config struct {
Listen_addr string
Pickle_addr string
Server_socket_timeout int64
Admin_addr string
Http_addr string
Spool_dir string
Expand Down
3 changes: 3 additions & 0 deletions examples/carbon-relay-ng.ini
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ listen_addr = "0.0.0.0:2003"
### Pickle Carbon ###
pickle_addr = "0.0.0.0:2013"

### Server socket idle timeout in seconds ###
server_socket_timeout = 3600

### AMQP ###
[amqp]
amqp_enabled = false
Expand Down
12 changes: 10 additions & 2 deletions input/pickle.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"io"
"math/big"
"net"
"time"

"github.com/graphite-ng/carbon-relay-ng/badmetrics"
"github.com/graphite-ng/carbon-relay-ng/cfg"
Expand All @@ -33,11 +34,16 @@ func NewPickle(config cfg.Config, addr string, tbl *table.Table, bad *badmetrics

func (p *Pickle) Handle(c net.Conn) {
defer c.Close()
// TODO c.SetTimeout(60e9)
idle_timeout := time.Duration(p.config.Server_socket_timeout) * time.Second
r := bufio.NewReaderSize(c, 4096)
log.Debug("pickle.go: entering ReadLoop...")
ReadLoop:
for {
if idle_timeout > 0 && c.RemoteAddr() != nil {
if err := c.SetReadDeadline(time.Now().Add(idle_timeout)); err != nil {
log.Error(err.Error())
}
}

// Note that everything in this loop should proceed as fast as it can
// so we're not blocked and can keep processing
Expand All @@ -48,7 +54,9 @@ ReadLoop:
var length uint32
err := binary.Read(r, binary.BigEndian, &length)
if err != nil {
if io.EOF != err {
if err, ok := err.(net.Error); ok && err.Timeout() {
log.Warning("Connection from %s is idle, closing.\n", c.RemoteAddr())
} else if io.EOF != err {
log.Error("couldn't read payload length: " + err.Error())
}
log.Debug("pickle.go: detected EOF while detecting payload length with binary.Read, nothing more to read, breaking")
Expand Down
12 changes: 10 additions & 2 deletions input/plain.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bufio"
"io"
"net"
"time"

"github.com/graphite-ng/carbon-relay-ng/badmetrics"
"github.com/graphite-ng/carbon-relay-ng/cfg"
Expand All @@ -30,9 +31,14 @@ func NewPlain(config cfg.Config, addr string, tbl *table.Table, badMetrics *badm

func (p *Plain) Handle(c net.Conn) {
defer c.Close()
// TODO c.SetTimeout(60e9)
r := bufio.NewReaderSize(c, 4096)
idle_timeout := time.Duration(p.config.Server_socket_timeout) * time.Second
for {
if idle_timeout > 0 && c.RemoteAddr() != nil {
if err := c.SetReadDeadline(time.Now().Add(idle_timeout)); err != nil {
log.Error(err.Error())
}
}

// Note that everything in this loop should proceed as fast as it can
// so we're not blocked and can keep processing
Expand All @@ -43,7 +49,9 @@ func (p *Plain) Handle(c net.Conn) {
buf, _, err := r.ReadLine()

if err != nil {
if io.EOF != err {
if err, ok := err.(net.Error); ok && err.Timeout() {
log.Warning("Connection from %v is idle, closing.\n", c.RemoteAddr())
} else if io.EOF != err {
log.Error(err.Error())
}
break
Expand Down
Loading

0 comments on commit 2e8abd2

Please sign in to comment.