News for hackers. Stuff that matters.
Re:Golang is evil on shitty networks by ialad on Thursday December 29, 2022 @07:48PM (#34180205)
I'm using Go's default HTTP client to make a few requests per second. I set a context timeout of a few seconds for each request. There are random 16 minute intervals where I only get the error `context deadline exceeded`.

From what I found, Go's default client uses HTTP/2 by default. When a TCP connection stops working, it relies on the OS to decide when to time out the connection. Over HTTP/1.1, it closes the connection itself [1] on timeout and makes a new connection.

In Linux, I guess the timeout for a TCP connection depends on `tcp_retries2` which defaults to 15 and corresponds to a time of ~15m40s [2].

This can be simulated by making a client and some requests and then blocking traffic with an `iptables` rule [3]. My solution for now is to use a client that only uses HTTP/1.1.

[1] https://github.com/golang/go/issues/36026#issuecomment-56902...

[2] https://blog.cloudflare.com/when-tcp-sockets-refuse-to-die/

[3] https://github.com/golang/go/issues/30702

Re:Golang is evil on shitty networks by rattray on Thursday December 29, 2022 @08:08PM (#34180361)
Wow. Can you easily change the tcp connection timeout?
Re:Golang is evil on shitty networks by iampims on Thursday December 29, 2022 @09:11PM (#34180942)
You can. It’s trivial once you know it’s possible. Not sure why it’s not set by default. https://go.googlesource.com/net/+/master/http2/transport.go
Re:Golang is evil on shitty networks by klabb3 on Thursday December 29, 2022 @11:40PM (#34181850)
To be clear, this is for http/2, not tcp. You can very easily set read and write deadlines on tcp conns, but you can’t detect if a peer has disappeared without data. You can set keepalive but it’s not reliable and varies wildly between OSs.

You need a heartbeat or ping message together with an advancing deadline to detect dead peers reliably.

Re:Golang is evil on shitty networks by benmmurphy on Friday December 30, 2022 @09:36AM (#34185375)
HTTP/2 supports a heartbeat in the protocol using PING frames. But I guess a lot of clients probably don’t support it or use it by default.
Re:Golang is evil on shitty networks by benmmurphy on Thursday December 29, 2022 @09:00PM (#34180847)
that sounds like there is pooling going on and not invalidating the pooled connection when a timeout happens. I've actually seen a lot of libraries in other languages do a similar thing (my experience is some of the elixir libraries don't have good pool invalidation for http connections). having a default invalidation policy that handles all situations is a bit difficult but I think a default policy that invalidates on any timeout is much better than a default policy that never invalidates on a timeout. as long as invalidation means just evicting it from the pool and not tearing down other channels on the HTTP/2 connection. for example you could have a timeout on a HTTP/2 connection that is just on an individual channel but there is still data flowing through the other channels.
Re:Golang is evil on shitty networks by iampims on Thursday December 29, 2022 @09:10PM (#34180938)
You can configure the HTTP/2 client to use a timeout + heartbeat.

https://go.googlesource.com/net/+/master/http2/transport.go

Re:Golang is evil on shitty networks by francislavoie on Friday December 30, 2022 @12:01AM (#34181979)
That's a big file. Mind pointing to a specific line number?
Re:Golang is evil on shitty networks by iampims on Friday December 30, 2022 @02:05AM (#34182650)
https://go.googlesource.com/net/+/master/http2/transport.go#...

Looks like it got cut off when I originally pasted it.