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

proxy: Parse units with duration configurations #909

Merged
merged 7 commits into from
May 8, 2018

Conversation

olix0r
Copy link
Member

@olix0r olix0r commented May 8, 2018

Configuration values that take durations are currently specified as
time values with no units. So 600 may mean 600ms in some contexts and
10 minutes in others.

In order to avoid this problem, this change now requires that
configurations provide explicit units for time values such as '600ms' or
'10 minutes'.

After this, users may set environment vars like CONDUIT_PROXY_METRICS_RETAIN_IDLE="1h".

olix0r added 2 commits May 8, 2018 06:38
It's easy to misconfigure default durations, since they're recorded as
integers and converted to Durations separately.

Now, all default constants that represent durations use const `Duration`
instances (enabled by a recent Rust release).

This fixes #905 which was caused by using the wrong time unit for the
metrics retain time.
Configuration values that take durations are currently specified as
time values with no units.  So `600` may mean 600ms in some contexts and
10 minutes in others.

In order to avoid this problem, this change now requires that
configurations provide explicit units for time values such as '600ms' or
10 minutes'.
@olix0r olix0r added this to the 0.5.0 milestone May 8, 2018
@olix0r olix0r self-assigned this May 8, 2018
@olix0r olix0r changed the base branch from ver/config-durations to master May 8, 2018 17:58
lazy_static! {
static ref RE: Regex = Regex::new(r"(?x)^
\s* (\d+) \s*
( ms | msecs? | millis? | milliseconds?
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we should only support the short form of each duration unit that we support: "ms", "s", "m", "h", "d", to make life easier and to make sure our testing is comprehensive.

Some('h') => 60 * 60,
Some('d') => 60 * 60 * 24,
_ => return Err(ParseError::NotADuration),
};
Copy link
Contributor

Choose a reason for hiding this comment

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

In particular, notice that this doesn't validate anything after the first character, which I'm sure will create problems later, if we change anything here later.

Instead, we should match unit as full strings. Then we can also merge the processing for "ms" into the match and use from_millis for everything.

use super::*;

fn test_units<F: Fn(u64) -> Duration>(units: &[&str], to_duration: F) {
for v in &[1, 23, 456_789] {
Copy link
Contributor

Choose a reason for hiding this comment

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

We should include 0 here too. We should consider whether we support the value 0 at all for any of these values, and, if so, whether we require a unit for 0.

#[test]
fn parse_invalid_unit() {
assert_eq!(parse_duration("12 moons"), Err(ParseError::NotADuration));
}
Copy link
Contributor

Choose a reason for hiding this comment

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

We should also have a test for the input string that would cause a overflow, as well as for the maximum value that won't cause an overflow. Also negative numbers.

@briansmith
Copy link
Contributor

Note that this fixes #27.

@briansmith
Copy link
Contributor

I imagine conduit inject and conduit install need to be modified to add the units to the config files they generate, and to accept the units in their command-line argument parsing.

@olix0r
Copy link
Member Author

olix0r commented May 8, 2018

@briansmith these values are not currently configurable in the CLI, so no change is necessary

@briansmith
Copy link
Contributor

OK, I thought #865 was merged already. #865 adds one.

Add tests for 0 and overflow values.
@olix0r
Copy link
Member Author

olix0r commented May 8, 2018

@briansmith i've removed support for all but the shortest names and i've added tests for "0" and an overflow number

@@ -340,6 +339,32 @@ fn parse_number<T>(s: &str) -> Result<T, ParseError> where T: FromStr {
s.parse().map_err(|_| ParseError::NotANumber)
}

fn parse_duration(s: &str) -> Result<Duration, ParseError> {
use regex::Regex;
lazy_static! {
Copy link
Contributor

Choose a reason for hiding this comment

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

TIOLI: this use of lazy_static is overkill.

use regex::Regex;
lazy_static! {
static ref RE: Regex = Regex::new(r"(?x)^
\s* (\d+) \s* ( ms | s | m | h | d ) \s*
Copy link
Contributor

Choose a reason for hiding this comment

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

TIOLI: I didn't notice this the first time. IMO it is better to NOT allow whitespace between the digits and the unit.

@@ -111,7 +111,7 @@ macro_rules! generate_tests {
let mut env = config::TestEnv::new();

// set the bind timeout to 100 ms.
env.put(config::ENV_BIND_TIMEOUT, "100".to_owned());
env.put(config::ENV_BIND_TIMEOUT, "100 ms".to_owned());
Copy link
Contributor

Choose a reason for hiding this comment

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

Regardless of whether we allow spaces, let's be consistent and avoid using spaces ourselves.

@olix0r olix0r merged commit 63fbbd6 into master May 8, 2018
@olix0r olix0r deleted the ver/config-parse-durations branch May 8, 2018 20:54
sfroment added a commit to sfroment/conduit that referenced this pull request May 9, 2018
sfroment added a commit to sfroment/conduit that referenced this pull request May 9, 2018
Signed-off-by: Sacha Froment <sfroment42@gmail.com>
sfroment added a commit to sfroment/conduit that referenced this pull request May 12, 2018
Signed-off-by: Sacha Froment <sfroment42@gmail.com>
sfroment added a commit to sfroment/conduit that referenced this pull request May 12, 2018
Signed-off-by: Sacha Froment <sfroment42@gmail.com>
sfroment added a commit to sfroment/conduit that referenced this pull request May 12, 2018
Signed-off-by: Sacha Froment <sfroment42@gmail.com>
sfroment added a commit to sfroment/conduit that referenced this pull request May 23, 2018
Signed-off-by: Sacha Froment <sfroment42@gmail.com>
klingerf pushed a commit that referenced this pull request May 29, 2018
* conduit inject: Add flag to set proxy bind timeout (#863)
* fix test
* fix flag to get it working with #909
* Add time parsing
* Use the variable to set the default value

Signed-off-by: Sacha Froment <sfroment42@gmail.com>
khappucino pushed a commit to Nordstrom/linkerd2 that referenced this pull request Mar 5, 2019
Configuration values that take durations are currently specified as
time values with no units.  So `600` may mean 600ms in some contexts and
10 minutes in others.

In order to avoid this problem, this change now requires that
configurations provide explicit units for time values such as '600ms' or
10 minutes'.

Fixes linkerd#27.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants