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…
Make resilient Go servers using timeouts, deadlines and context cancellation
21–30 of 42 posts
Re: Make resilient Go servers using timeouts, deadlines and context cancellation
#22when doing DB work with these, I'm a little shakier -- once I start a multistep DB write, I probably want it to finish. Yes I can use a transaction to roll back the whole thing, but I think there are cases where rollback is wrong and I'd rather keep the write.
so while cancellation is cool, it's also a little fraught and hard to test.
Re: Make resilient Go servers using timeouts, deadlines and context cancellation
#23Earlier quoted context omitted.
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…
It's hard to see why synchronous multi-threaded code would find these things any more difficult than async or actor models.
All three models are equally able to access shared data structures to keep track of resource usage statistics, per-connection statistics, and timers.
OS kernels do this routinely, and are essentially multi-threaded on SMP architectures or with kernel pre-emption.
Re: Make resilient Go servers using timeouts, deadlines and context cancellation
#24Earlier quoted context omitted.
> 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…
> 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. It's hard to see why synchronous multi-threaded code would find these things any more difficult than async or actor models. All three models are equally able to access shared data structures to keep track of reso…
Re: Make resilient Go servers using timeouts, deadlines and context cancellation
#25That's fine but I feel like it might not be the best introduction for a novice as a lot of concepts are mixed together and they might miss the bigger picture. Context is not just for web servers. You don't have to know how net/http works.
You could simply demonstrate the usefulness of the context package with showing how to properly clean up your program on a sigterm. Or even gracefully stop a long running operation so you are not afraid to stop/start your program at the "wrong" time.
Re: Make resilient Go servers using timeouts, deadlines and context cancellation
#26Earlier quoted context omitted.
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
#27Ok, 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
#28Earlier quoted context omitted.
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
All you have to do is make sure is to pass to the library the context that carries your timeout or cancellation signal. The "rule" that everyone seems to follow is to always take as first argument a context.Context if your library handles cancellation.
Re: Make resilient Go servers using timeouts, deadlines and context cancellation
#29I 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…
Re: Make resilient Go servers using timeouts, deadlines and context cancellation
#30absolutely agree with the risk of slow clients saturating your connection limit when doing DB work with these, I'm a little shakier -- once I start a multistep DB write, I probably want it to finish. Yes I can use a transaction to roll back the whole thing, but I think there are cases where rollback is wrong and I'd rather keep the write. so while cancellation is cool, it's also a little fraught and hard to test.