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

Allow human-readable byte sizes in config #8891

Merged
merged 2 commits into from
Nov 2, 2017

Conversation

andrewhare
Copy link
Contributor

@andrewhare andrewhare commented Sep 27, 2017

Update support in the toml package for parsing human-readble byte sizes.
Supported size suffixes are "k" or "K" for kibibytes, "m" or "M" for
mebibytes, and "g" or "G" for gibibytes. If a size suffix isn't specified
then bytes are assumed.

In the config, cache-max-memory-size and cache-snapshot-memory-size are
now typed as toml.Size and support the new syntax.

Required for all non-trivial PRs
  • Rebased/mergable
  • Tests pass
  • CHANGELOG.md updated
Required only if applicable
  • Provide example syntax
  • Config changes: update sample config (etc/config.sample.toml), server NewDemoConfig method, and Diagnostics methods reporting config settings, if necessary

@ghost ghost assigned andrewhare Sep 27, 2017
@ghost ghost added the review label Sep 27, 2017
toml/toml.go Outdated
default:
return fmt.Errorf("unknown size suffix: %c", suffix)
if maxInt/mult < size {
return fmt.Errorf("size would overflow the max size (%d) of an int: %s", maxInt, string(text))
Copy link
Contributor

Choose a reason for hiding this comment

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

This should say a uint because now it's an unsigned integer. I don't think we need to specify it is a uint64. Can you also use math.MaxUint64 for the size check? It would make it so maxInt isn't needed anymore.

Copy link
Contributor

Choose a reason for hiding this comment

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

maxInt is actually based on the largest value of int, and Size was previously defined as the type int. If the goal is for Size to be a uint64, then use MaxUint64. If it's meant to be int, then keep the current constant and change the underlying type of Size.

toml/toml.go Outdated
// Check for overflow.
if size > maxInt {
return fmt.Errorf("size %d cannot be represented by an int", size)
return fmt.Errorf("size %d is too large", size)
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think this check is possible. I don't think the previous code worked and I don't see any tests that verified this if statement ever worked.

Copy link
Contributor

Choose a reason for hiding this comment

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

I agree, the previous check should cover it since we're just dealing with known powers of two (shifting).

@@ -71,10 +71,12 @@

# CacheMaxMemorySize is the maximum size a shard's cache can
# reach before it starts rejecting writes.
# Values without a size suffix (e.g. 30k, 20m, 10g) are in bytes.
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you update this to say: Valid size suffixes are k, m, or g (case insensitive). Values without a size suffix are in bytes.

toml/toml.go Outdated
// Parse numeric portion of value.
length := len(string(text))
size, err := strconv.ParseInt(string(text[:length-1]), 10, 64)
size, err := strconv.ParseInt(string(sizeText), 10, 64)
Copy link
Contributor

Choose a reason for hiding this comment

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

This should be probably be ParseUint, so we don't end up with negative sizes

toml/toml.go Outdated
default:
return fmt.Errorf("unknown size suffix: %c", suffix)
if maxInt/mult < size {
return fmt.Errorf("size would overflow the max size (%d) of an int: %s", maxInt, string(text))
Copy link
Contributor

Choose a reason for hiding this comment

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

maxInt is actually based on the largest value of int, and Size was previously defined as the type int. If the goal is for Size to be a uint64, then use MaxUint64. If it's meant to be int, then keep the current constant and change the underlying type of Size.

toml/toml.go Outdated
// Check for overflow.
if size > maxInt {
return fmt.Errorf("size %d cannot be represented by an int", size)
return fmt.Errorf("size %d is too large", size)
Copy link
Contributor

Choose a reason for hiding this comment

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

I agree, the previous check should cover it since we're just dealing with known powers of two (shifting).

Update support in the `toml` package for parsing human-readble byte sizes.
Supported size suffixes are "k" or "K" for kibibytes, "m" or "M" for
mebibytes, and "g" or "G" for gibibytes. If a size suffix isn't specified
then bytes are assumed.

In the config, `cache-max-memory-size` and `cache-snapshot-memory-size` are
now typed as `toml.Size` and support the new syntax.
@jsternberg jsternberg force-pushed the amh-human-readable-sizes branch from d69a1a6 to 978094f Compare November 1, 2017 16:09
@ghost ghost assigned jsternberg Nov 1, 2017
@jsternberg
Copy link
Contributor

jsternberg commented Nov 1, 2017

@andrewhare @joelegasse I implemented the feedback to this so we can get it in for 1.4. Can you two check to make sure that there isn't anything I missed?

Copy link
Contributor

@mark-rushakoff mark-rushakoff left a comment

Choose a reason for hiding this comment

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

A couple copy changes and one new test requested, then LGTM.

@@ -71,10 +71,14 @@

# CacheMaxMemorySize is the maximum size a shard's cache can
# reach before it starts rejecting writes.
# Valid size suffixes are k, m, or g (case insensitive).
# Values without a size suffix (e.g. 30k, 20m, 10g) are in bytes.
Copy link
Contributor

Choose a reason for hiding this comment

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

"without a size suffix" - should it be 30, 20, 10 in that case? Or maybe just say that all values represent bytes.

To reduce any other confusion, it would help if this comment clarified k means 1000 and not 1024.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure that's the case. Since the sizes are byte shifts, then 1 << 10 is 1024. I'll see if I can clarify this comment though since what it's trying to say is that 30k, 20m, and 10g have size suffixes.

Copy link
Contributor

Choose a reason for hiding this comment

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

You're right, it's 1024 and not 1000. Should still be clarified for users.

Copy link
Contributor

Choose a reason for hiding this comment

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

I updated the configuration file to include a note that 1024 = 1k. That should be good enough for someone to extrapolate that these are 1024 and not 1000.

toml/toml.go Outdated
case 'g', 'G':
mult = 1 << 30 // GiB
default:
return fmt.Errorf("unknown size suffix: %c", suffix)
Copy link
Contributor

Choose a reason for hiding this comment

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

It would be helpful if this error mentioned that "valid suffixes are k, m, g".

Copy link
Contributor

Choose a reason for hiding this comment

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

Done.

@@ -71,8 +71,8 @@ type Config struct {
QueryLogEnabled bool `toml:"query-log-enabled"`

// Compaction options for tsm1 (descriptions above with defaults)
CacheMaxMemorySize uint64 `toml:"cache-max-memory-size"`
CacheSnapshotMemorySize uint64 `toml:"cache-snapshot-memory-size"`
CacheMaxMemorySize toml.Size `toml:"cache-max-memory-size"`
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd like to see an addition to tsdb/config_test.go that sets one of these new toml.Size values to something with a suffix.

Copy link
Contributor

Choose a reason for hiding this comment

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

Done.

@jsternberg jsternberg force-pushed the amh-human-readable-sizes branch from 978094f to 9f59680 Compare November 1, 2017 17:51
# cache-max-memory-size = 1048576000
# Valid size suffixes are k, m, or g (case insensitive).
# Vaues without a size suffix are in bytes.
# cache-max-memory-size = "1g"
Copy link
Contributor

Choose a reason for hiding this comment

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

Just a note for those who might check this, the sample configuration file has the wrong value. The code has 1 GB as the default and 1 GB in bytes is 1073741824 bytes, not 1048576000.

Copy link
Contributor

Choose a reason for hiding this comment

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

I see, the old sample config value was 1000m but the const DefaultCacheMaxMemorySize is actually 1g (i.e. 1024m). Fixing the sample config to 1g makes sense here.

@jsternberg jsternberg force-pushed the amh-human-readable-sizes branch from 9f59680 to 87ed89e Compare November 1, 2017 18:08
# cache-max-memory-size = 1048576000
# Valid size suffixes are k, m, or g (case insensitive).
# Vaues without a size suffix are in bytes.
# cache-max-memory-size = "1g"
Copy link
Contributor

Choose a reason for hiding this comment

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

I see, the old sample config value was 1000m but the const DefaultCacheMaxMemorySize is actually 1g (i.e. 1024m). Fixing the sample config to 1g makes sense here.

@jsternberg
Copy link
Contributor

The circle tests continue to fail for some reason, but the appveyor ones succeeded and the ones that failed, the race tests, seem to work on my computer and have little to nothing to do with this PR. I'm going to merge this since I don't think the unit tests are actual failures.

@jsternberg jsternberg merged commit a8a36d1 into master Nov 2, 2017
@ghost ghost removed the review label Nov 2, 2017
@jsternberg jsternberg deleted the amh-human-readable-sizes branch November 2, 2017 18:34
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.

4 participants