-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
fix(router): replace the occurrences of gen_range
with a safer alternative
#1908
Conversation
@@ -15,8 +15,11 @@ use crate::{configs::settings, routes::AppState}; | |||
|
|||
pub async fn tokio_mock_sleep(delay: u64, tolerance: u64) { | |||
let mut rng = rand::thread_rng(); | |||
let effective_delay = rng.gen_range((delay - tolerance)..(delay + tolerance)); | |||
tokio::sleep(tokio::Duration::from_millis(effective_delay)).await | |||
let effective_delay = Uniform::from((delay - tolerance)..(delay + tolerance)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we use Uniform::try_from
?.
(although that also does not seem to help)
https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=4a99d8a5b9a9604292cf7065e83e2866
Maybe it'll be fixed in future, we can use the safer API on our side in the meanwhile
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lsampras I started with try_from
:
let timeout = Uniform::try_from(0..=settings.loop_interval)?;
But the compiler complains that:
the trait `std::convert::From<Infallible>` is not implemented for `error_stack::Report<ProcessTrackerError>`
We can't just implement From<Infallible>
for error_stack::Report<ProcessTrackerError>
because of Rusts orphan rule. If we want to get around this then we may have to add significant amount of workaround in the errors.rs
file potentially changing the API contract.
Plus as you can see above it says to implement something that is Infallible that is unlikely to fail so we are not gaining much here. And another reason is that the from
method just does type conversion here which is infallible; the actual random number work is done by the sample
method which replaces the gen_range
functionality and again doesn't return a Result
.
Does that reasoning make sense?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lsampras @SanchithHegde any thoughts on the comment above?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let timeout = Uniform::try_from(0..=settings.loop_interval).into_report().change_context(ProcessTrackerError::InvalidInput)?;
I believe this should fix it^
yeah the result is currently infallible but in the future it's not gonna be,
we won't have much benefit from adding it rn but we'll be benefitting from this when a new version of rand is released
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lsampras cool, thanks. That is good to know. I'll resubmit the PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this still needs to be changed to Uniform::try_from()
?
let timeout = rand::thread_rng().gen_range(0..=settings.loop_interval); | ||
tokio::time::sleep(Duration::from_millis(timeout)).await; | ||
let mut rng = rand::thread_rng(); | ||
let timeout = Uniform::from(0..=settings.loop_interval); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Uniform::try_from
gen_range
with a safer alternative
@SanchithHegde I've updated the PR, let me know if there are any other changes required here. Thanks. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Other than that, looks good to me!
Thanks for the PR, @anupj!
let mut rng = rand::thread_rng(); | ||
let timeout = Uniform::try_from(0..=scheduler_settings.loop_interval) | ||
.into_report() | ||
.change_context(errors::ProcessTrackerError::InvalidInput)?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer this being named as , I'd prefer raising InvalidConfiguration
insteadConfigurationError
instead, since loop_interval
is a scheduler configuration variable, and this would provide us better error messages. We can remove the InvalidInput
error variant as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this PR blocked because of this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@anupj Not exactly blocked by the error propagation, there's still one remaining usage of Uniform::from()
that would have to be replaced.
Let us know if you need any help.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I'll fix this today/tomorrow and update PR for review. Thanks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@SanchithHegde I remember now why I didn't change this to try_from() because it will mean that we'll have to change the function signature for tokio_mock_sleep() to return a Result which could turn out to be a bigger change than is required for this PR as we haave to then change the fn signature where tokioo_mock_sleep() is called. Is that desirable? ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you then add a TODO here & if possible create a new issue for this that can be picked up later?
@@ -15,8 +15,11 @@ use crate::{configs::settings, routes::AppState}; | |||
|
|||
pub async fn tokio_mock_sleep(delay: u64, tolerance: u64) { | |||
let mut rng = rand::thread_rng(); | |||
let effective_delay = rng.gen_range((delay - tolerance)..(delay + tolerance)); | |||
tokio::sleep(tokio::Duration::from_millis(effective_delay)).await | |||
let effective_delay = Uniform::from((delay - tolerance)..(delay + tolerance)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this still needs to be changed to Uniform::try_from()
?
@anupj Could you please address the merge conflicts? |
Oh dear, looks like I might have accidentally closed the PR. Is it better to open a new PR to address the merge issues? |
Either is fine. |
Type of Change
Description
This is a bugfix for issue 1754.
I have replaced the instances of
gen_range()
withUniform.sample
.This should reduce the risk of
gen_range()
throwing apanic!
.Additional Changes
Motivation and Context
This is a bugfix for issue 1754
Closes #1754.
How did you test it?
I did not write any new tests but I ran
cargo test -p router --lib
and all tests passed.NOTE: I was not able to run all integration tests because my laptop is not setup for running integration tests.
Checklist
cargo +nightly fmt --all
cargo clippy