Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> gracefully stop a long running operation so you are not afraid to stop/start your program at the "wrong" time.

This is one of my major pain points with Go's contexts. Where I work we do have an "application wrapper" that gets cancelled on various signals, and it's very handy for some things. But one thing it's not good at is shutting things down safely!

Something we do pretty commonly is start multiple servers (e.g. a public and a private HTTP server, or an HTTP server and DB background task, etc.) When we get SIGINT, we want to cancel both's context (easy), then wait for both to stop before continuing with our exit process (hard). Yes, this is the canonical case for sync.WaitGroup, but those are hard to use correctly when you need to transition into and out of "acceptable" states rather than just count down (well, hard to use correctly period, to be honest - probably half the time I see a junior dev using them they increment within the goroutine). And hard to timeout waiting for the waitgroup when you want to continue despite unclean shutdown - WaitGroup.Done doesn't itself take a context.

This is further complicated by the fact that for servers you often don't really want to use the "application context" as the parent of the request contexts. Rather you want the server to shut down cleanly when that context is cancelled, processing all pending requests to completion but without immediately cancelling them. So the base request context is ideally something like "cancelling X seconds after the application context" which is not part of the standard context toolbox.

And of course different libraries are not really consistent in how they shut down - http.Server lets you close it with a timeout and so returns an error but also you need to check the error return of the Serve method (and you can't distinguish a graceful stop from a hard stop from try to restart a stopped server), grpc.Server offers only hard and graceful stops with no timeout and only the Serve method returns an error, and sarama.Client provides only a synchronous close that returns an error.

I've not used them but I'm told C#'s cancellation tokens akin to Go context but are closely integrated with their async task state machine, such that it's easy to hand out cancellation tokens and wait for the tasks waiting for those tokens to finish.



Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: