Live data from Hacker News

Make resilient Go servers using timeouts, deadlines and context cancellation

ieftimov.com

11–20 of 42 posts

Re: Make resilient Go servers using timeouts, deadlines and context cancellation

#11
post #8

I tried running Go HTTP servers bare to the internet (after Cloudflare promoted doing so in a blog post), but went back to using a reverse proxy the next time. The main benefit seems to be convenience. I can upgrade and graceful-restart nginx instead of having to rebuild and redeploy the Go server (involving a full app restart). Not having to worry about goroutine leaks because some jerk decided to send the request l…

You have to worry about the jerk sending requests at 1 byte per second no matter which webserver you use. It's always a problem to let an unlimited number of people ask for an unlimited amount of resources; it's just that things like goroutines are heavier than a file descriptor or a few bytes of RAM, so you'll notice wasted goroutines more quickly than wasted fds or memory.

Typically, you need to consider the total amount of memory you want your web server to use, how much of that memory one request can use, and how long a request can use that memory. (File descriptors must also be considered.)

Envoy has a section in their documentation about this here: https://www.envoyproxy.io/docs/envoy/latest/configuration/be...

nginx similarly has a number of knobs to turn: https://www.nginx.com/blog/tuning-nginx/

I use Envoy as my web proxy and nginx to serve static content. My envoy configuration is complicated and my nginx configuration is simple, as a result. I imagine that if you are hosting a serious amount of traffic with Nginx as the edge proxy, more tuning is required. I've never tried, so I don't really know.

Re: Make resilient Go servers using timeouts, deadlines and context cancellation

#12
Ok, good, contexts are now making sure you can handle upcoming timeouts decided by an upper layer (caller function). But how about the time.After function? It'll still be running in the background? So you can still have a memory or 'processing power' leak?

Re: Make resilient Go servers using timeouts, deadlines and context cancellation

#13

Ok, good, contexts are now making sure you can handle upcoming timeouts decided by an upper layer (caller function). But how about the time.After function? It'll still be running in the background? So you can still have a memory or 'processing power' leak?

The function you write after time.After should use the same context, and check its Done channel before continuing execution

Re: Make resilient Go servers using timeouts, deadlines and context cancellation

#14
post #13

Ok, good, contexts are now making sure you can handle upcoming timeouts decided by an upper layer (caller function). But how about the time.After function? It'll still be running in the background? So you can still have a memory or 'processing power' leak?

The function you write after time.After should use the same context, and check its Done channel before continuing execution

So you have to propagate the Context, hm. IIRC, go test will panic the test case when it times out. Not exactly sure tho. It would be nice if there was a kind of 'abort' feature to clean up subroutines spun off this thread

Re: Make resilient Go servers using timeouts, deadlines and context cancellation

#18
post #3

Earlier quoted context omitted.

I did not get such an ad on my end? And this browser has no blockers of any kind. I scrolled through it in its entirety.

Appears after a while. Not based on scrolling, as far as I can tell.

That makes sense. Using a timeout is much more appropriate for this specific article.

Re: Make resilient Go servers using timeouts, deadlines and context cancellation

#19
post #8

I tried running Go HTTP servers bare to the internet (after Cloudflare promoted doing so in a blog post), but went back to using a reverse proxy the next time. The main benefit seems to be convenience. I can upgrade and graceful-restart nginx instead of having to rebuild and redeploy the Go server (involving a full app restart). Not having to worry about goroutine leaks because some jerk decided to send the request l…

You have to worry about the jerk sending requests at 1 byte per second no matter which webserver you use. It's always a problem to let an unlimited number of people ask for an unlimited amount of resources; it's just that things like goroutines are heavier than a file descriptor or a few bytes of RAM, so you'll notice wasted goroutines more quickly than wasted fds or memory. Typically, you need to consider the total…

> You have to worry about the jerk sending requests at 1 byte per second no matter which webserver you use.

Not necessarily. It's just free webservers don't bother dealing with it, but there are plenty of simple approaches. Like just dropping connections that are sending requests slower than some threshold or dropping the slowest connection when some total number of connections is reached. Or more complicated, which also works to protect from all kinds of attacks, dropping the highest malicious score or the lowest reputation score client when some resource usage threshold is reached.

None of these are easy to implement with synchronous multithreaded networking code though, like in Go. Realistically it's only viable with asynchronous single threaded programming models or an actor model.

Post reply on HN