I have the following:
//In an init func
if logStashHost != "" {
lsconn, err = net.Dial("tcp", logStashHost)
}
...
ToLogStash(rec, lsconn)
Then Two functions:
func ReadLogStash(conn net.Conn) {
buffer := make([]byte, 256)
for {
_, err := conn.Read(buffer)
if err != nil {
fmt.Println(err)
} else {
fmt.Println(buffer)
}
}
}
func ToLogStash(r *logrow.Record, conn net.Conn) {
b, err := json.Marshal(r)
if err != nil {
fmt.Println(err)
return
}
_, err = fmt.Fprintln(conn, string(b))
if err != nil {
fmt.Println(err)
}
}
Where ReadLogStash is a running goroutine. If the other side closes, I get EOF. What would be a good implementation in ReadLogStash to have it attempt to reestablish the connection every X seconds when it gets an EOF?
JimB :
Go has channels for synchronization and communication, use them!\n\nMake your connection in a loop, and have it wait for some sort of message to come back on a channel.\n\n...\nerrCh := make(chan error)\nfor {\n lsconn, err = net.Dial(\"tcp\", logStashHost)\n // check error!\n go ReadLogStash(lsconn, errCh)\n err = <-errCh\n if err != nil {\n // bad error\n break\n }\n // sleep to backoff on retries?\n}\n...\n\nfunc ReadLogStash(conn net.Conn, errCh chan error) {\n _, err := io.Copy(os.Stderr, conn)\n if err != nil {\n fmt.Println(err)\n }\n // a nil error from io.Copy means you reached EOF.\n errCh <- err\n}\n\n\nUnless you have more functionality in ReadLogStash, you can probably just use io.Copy inline, and forget the entire function, but this pattern may come in useful for you anyway.",
2014-04-30T19:23:47