Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Poll{Records,Fetches}: inject an error for canceled context
It's debatable that this is necessary, but it's also not that useful not to do this. In the original implementation of PollFetches, no error was ever injected. You only received an error if a partition error occurred. Eventually, I realized this made quitting a poll loop on client close quite difficult. I added ErrClientClosed, injected it in Poll, and added a dedicated IsClientClosed API for this. --- Polling originally returned every fetch result, even without records. Fetches always returned updated log start offsets & high watermarks even if no records were returned. Polling returned these empty fetches. This was largely useless, so empty poll results were eventually removed. Poll functions switched from returning periodically to returning only if records were buffered, or the client closed, or the context was canceled. --- The intent of the context was to be a more powerful way to quit a poll loop, in contrast to Java's or librdkafka's poll millisecond timeout. The original implementation of the code largely mirrored Java and librdkafka's polling, modulo timeouts for a context. When you poll with a timeout, once the timeout is hit, you get no results. You also get no error. You just hit a timeout, it is fine. This was the original thought behind the context as well. It doesn't matter if the context is canceled: you just quit fetching. This isn't an error. If you wanted to quit polling when you canceled your context, you'd need to check the context yourself after the fact. This is a small ask, really: ``` for ctx.Err() == nil { fs := cl.PollFetches(ctx) {work} } return ctx.Err() ``` --- I've seen code *once* that has a select block after fetching to check if the context was canceled. I thought this was unfortunate, but it was easy. It's usual that functions that take a context return ctx.Err(), but this isn't always the case. If a singleflight cache takes a context and a value is loaded successfully, *even if* the next get for the same key uses an expired context, the cache can return the successfully cached key. You essentially find ctx.Err missing in functions where state is already loaded. This was the exact case as the polling functions here: we first did a check if anything was avaialable and if so, returned without waiting. It's valid to not return this context error. Most code does, because most code using a context transits application boundaries and a cancelation can only be an error, but there are cases where a cancelation is not an error. We're just done waiting. Regardless, odds are that if a person cancels a context, they want to return anyway, so we can inject the ctx.Err and just return that. We will avoid checking buffered fetches until we check ctx.Done. This is a behavior change. Closes #160.
- Loading branch information