Skip to content
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

checked constructor for potential error conditions #4

Merged
merged 4 commits into from
Oct 29, 2020

Conversation

mroth
Copy link
Owner

@mroth mroth commented Oct 12, 2020

This commit introduces a variant of the NewChooser constructor that will pre-check for and error on conditions that could later cause a runtime issue during Pick.

The conditions handled are a lack of valid choices (fairly preventable by consumers) and a potential integer overflow in the running total (far more subtle, but an edge case). In general, it is highly preferable for us to expose these predictable scenarios rather than potentially allowing a runtime error that could panic or produce invalid results. I was thinking of this Cloudflare blog post as a similar scenario when proposing these changes.

The initial version of this is API backwards compatible by introducing a new NewChooserChecked function and changing the behavior of the NewChooser to panic at construction time in invalid states. However I'd like to iterate towards a more simple API before making this change. Some options:

  1. Expose both NewChooser and NewChooserChecked (as in the current proof of concept commit). I am not generally in favor of this as it introduces more user-complexity than needed and the distinction here is not significantly subtle to require the cognitive overhead of both options.

  2. Privatize newChooserChecked and keep the panic on error behavior on NewChooser. Pros: API backwards compatibility (though pre-release, so not as important), simpler caller semantics, the error conditions are currently fairly edge and unlikely to be encountered in typical usage. Cons: doesn't force error handling, and the overflow error scenario in particular, being an edge case, is unlikely to be pre-checked by consumers of the API, and panic recovery is a pain.

  3. Make NewChooserChecked the new NewChooser (renaming/replacing it), which introduces an API change in the return value of the constructor to (*Chooser, error). This would require a semantic version bump, but we're still in pre-release versioning so it makes sense to iterate towards the most ideal API now while we have the flexibility. Pros: Forces dealing with the potential error condition. Cons: Forces slightly more complex initialization code everywhere (e.g. checking err), current error conditions are not incredibly likely to emerge in typical usage.

Currently my current leaning is towards option number 3 (especially since the potentially use cases of this library include problem domains with highly reliable characteristics are desirable, such as load-balancing) but I would love to hear from actual users of this library. (To best have an informed opinion, I suggest reviewing the actual source code changes so you can see how likely you are to encounter the potential error conditions in your own usage.)

Some additional API considerations:

  • If going with option 1 or 3, whether to additionally export the sentinel error types (e.g. ErrWeightOverflow) or not (currently exported in initial commit). My initial inclination is that exporting them complicates the external surface of the API with minimal benefit, and I cannot currently conceive of a situation where a caller fo the constructor would act upon different error conditions significantly differently. (please let me know if you can think of a need here!).
  • There are some additional minor unrelated API changes I will want to consider making for ergonomics, so if this ends up going that route, I'll open additional issues to discuss those and they can potentially be rolled into a single breaking version bump.

This commit introduces a variant of the NewChooser constructor that will error
on conditions that could later cause a runtime issue during Pick().

The conditions handled are a lack of valid choices and a potential integer
overflow in the running total.

This is a proof of concept, but the final API may likely be different to avoid
introducing extra complexity into the library. This commit merely serves as the
intial code to aide a discussion in the PR.
@mroth
Copy link
Owner Author

mroth commented Oct 12, 2020

Pinging @0xERR0R since from a quick GitHub search, your Blocky project appears to be the current largest public project utilizing this library.

Pinging @mccutchen since I noticed you starred this repo recently and we've worked together in the past. 😁

@0xERR0R
Copy link

0xERR0R commented Oct 12, 2020

I would prefer the option 3. It is always better to check all errors earlier and fail fast and cheap (and not at runtime).

I don't see a current use case scenario where being able to act upon
these as sentinel errors would be significant, so better to avoid the
API complexity and keep them private for now. Always easier to export
them later if needed than taking them away once out in the wild.
@codecov
Copy link

codecov bot commented Oct 18, 2020

Codecov Report

Merging #4 into master will not change coverage.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff            @@
##            master        #4   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files            1         1           
  Lines           22        27    +5     
=========================================
+ Hits            22        27    +5     
Impacted Files Coverage Δ
weightedrand.go 100.00% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 3b00289...5da14cc. Read the comment docs.

@mroth
Copy link
Owner Author

mroth commented Oct 18, 2020

@0xERR0R potentially up for a quick code review on this before merge?

I'm thinking this could be targeted for a shortly upcoming v0.4 release after examining any other desirable API changes.

Copy link

@0xERR0R 0xERR0R 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, nice work!

@mroth mroth merged commit 953da99 into master Oct 29, 2020
@mroth mroth deleted the checked-constructor branch October 29, 2020 23:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants