Skip to content

Avoid using exceptions for control flow in GetBatch #2138

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 15, 2019

Conversation

stephentoub
Copy link
Member

@stephentoub stephentoub commented Jan 14, 2019

Fixes #2137
Contributes to #2099

This avoids using Take() in GetBatch, instead using TryTake with an infinite timeout, the only difference being whether it expects to eventually get data, and thus whether it throws or returns false when it finds the collection empty and marked for completion. This doesn't fix #2099, but it helps. These exceptions are largely a side-effect of tons of threads getting created, which is another huge contributor to #2099.

cc: @TomFinley

Copy link
Contributor

@TomFinley TomFinley left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great, thank you @stephentoub .

Contracts.AssertValue(inner);
throw Contracts.ExceptDecode(inner, "Stream reading encountered exception");
if (!_queue.TryTake(out LineBatch batch, millisecondsTimeout: -1))
return default;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not familiar with BlockingCollection, so please excuse my ignorance.

But is IsAddingCompleted the only reason TryTake will return false when given an Infinite timeout?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is IsAddingCompleted the only reason TryTake will return false when given an Infinite timeout?

Yeah... well, or a Dispose.

(Related, I think there may be some additional exceptional issues happening because of disposal in fact. I'm seeing a non-trivial number of OperationCanceledExceptions getting thrown and swallowed inside of BlockingCollection due to it being disposed of while there are still threads actively waiting to take. While it'd be great if BC could avoid using exceptions itself for control flow in that case, it's generally not something to optimize for given you're generally not supposed to dispose of things while they're still in use.)

Copy link
Member

@eerhardt eerhardt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. Just one simple question mostly for my education.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
4 participants