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

VEP4: flags, pflag, optional viper #8

Merged
merged 7 commits into from Feb 18, 2022
Merged

Conversation

ajm188
Copy link
Contributor

@ajm188 ajm188 commented Apr 8, 2021

This VEP introduces a series of projects to improve the global flag "situation" in various Vitess binaries to make the user experience and documentation for each of those binaries better.

veps/vep-4.md Outdated
Comment on lines 158 to 159
(NB: I'm not convinced this is a good idea at this point, but I wanted to put
it out there for criticism).
Copy link
Member

Choose a reason for hiding this comment

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

Not sure how much complexity this adds, but this seems like a very solid goal to me, given that in vitessio/vitess#7471 we're looking at having a server and a client binary.

@derekperkins
Copy link
Member

I know your proposal is in favor of hiding flag implementations, but given that we all seem to be in favor of moving to cobra, regardless of how the binary consolidation RFC turns out, I wonder if we shouldn't be more prescriptive about using https://github.com/spf13/pflag

@ajm188
Copy link
Contributor Author

ajm188 commented Apr 8, 2021

That makes sense to me; we can prescribe by outlining that all the AddFlags(...) functions take a pflag.FlagSet rather than a flag.FlagSet (and, vtadmin actually already does this for parsing discovery options: https://github.com/vitessio/vitess/blob/master/go/vt/vtadmin/cluster/discovery/discovery.go#L81)

@systay
Copy link
Contributor

systay commented May 19, 2021

👋 I'm about to open a new PR here, and I was wondering if the new VEP I write should be VEP4 or VEP5

In other words - is this PR still en route to be merged?

@ajm188
Copy link
Contributor Author

ajm188 commented May 28, 2021

Sorry Andres! You should take VEP4, I will rename

Signed-off-by: Andrew Mason <amason@slack-corp.com>
Signed-off-by: Andrew Mason <amason@slack-corp.com>
Signed-off-by: Andrew Mason <amason@slack-corp.com>
@ajm188
Copy link
Contributor Author

ajm188 commented Nov 3, 2021

@derekperkins (and others!) i am baaaaack (sorry for letting this sit on a backburner for so long) with a new version that does the restructure/encapsulation + pflag + viper-if-you-want-to all in one VEP. let me know what you think!

@ajm188 ajm188 changed the title Very rough initial thoughts on flags VEP4: flags, pflag, optional viper Nov 3, 2021
@ajm188 ajm188 marked this pull request as ready for review November 3, 2021 19:11
@derekperkins
Copy link
Member

I like it a lot. While I'm all for landing it in v13, and I don't think we've ever advertised -- for flags, we might need at least one version where it's deprecated.

I know that there's already some support for setting parameters via yaml, though I've never tried it and don't know much about it, so maybe this question isn't valid. Would native viper yaml/json support replace what we have today?

@ajm188
Copy link
Contributor Author

ajm188 commented Nov 3, 2021

I don't think we've ever advertised -- for flags

This is true, but I don't think the next part necessarily follows:

we might need at least one version where it's deprecated.

maybe! It's unclear to me how strictly our compatibility guarantees define "breaking change". It doesn't cross RPC boundaries, and you can make preparations now (or in v11, or v10, ..., or v1) to not be broken when we make this change. so, with a looser interpretation, we can drop it now and communicate over the monthly calls or other non—"code-prints-a-warning" channels the migration path. i can also see the argument for the stricter interpretation where it's "yeah, technically you can get away with it, but you shouldn't / that's not how we do things". so, i think it's at the very least an interesting gap in the specificity of the compatibility VEP (which focuses primarily on cross-component RPCs - i.e. vttablet{N} can talk to vtgate{N-1, N, N+1} and not as much on other pieces of the codebase)

I know that there's already some support for setting parameters via yaml, though I've never tried it and don't know much about it, so maybe this question isn't valid.

Just vttablet and vtadmin:

$ git grep -E "yaml2?\.Unmarshal"
go/cmd/vttablet/vttablet.go:            if err := yaml2.Unmarshal(bytes, config); err != nil {
go/vt/dbconfigs/dbconfigs_test.go:      err = yaml2.Unmarshal(inBytes, &gotdb)
go/vt/vtadmin/cluster/config.go:// UnmarshalYAML implements the yaml.Unmarshaler interface.
go/vt/vtadmin/cluster/config_test.go:                   err := yaml.Unmarshal([]byte(tt.yaml), &cfg)
go/vt/vtadmin/cluster/file_config.go:// UnmarshalYAML is part of the yaml.Unmarshaler interface.
go/vt/vtadmin/cluster/file_config.go:   return yaml.Unmarshal(data, fc)
go/vt/vtadmin/cluster/file_config_test.go:                      err := yaml.Unmarshal([]byte(tt.yaml), &cfg)
go/vt/vttablet/tabletserver/tabletenv/config_test.go:   err = yaml2.Unmarshal(inBytes, &gotCfg)
go/vt/vttablet/tabletserver/tabletenv/seconds_test.go:  err = yaml2.Unmarshal([]byte(wantBytes), &gotts)
go/yaml2/yaml.go:       Unmarshal = yaml.Unmarshal

I haven't used the tablet ones ever before, but I have used the vtadmin ones (heh). VTAdmin could easily switch to viper (in fact, its rbac config is viper-backed), it just hasn't been a top priority for me. A quick skim of the vttablet yaml config looks to me like it would also be easy to switch.

Would native viper yaml/json support replace what we have today?

To me, yes; it's better to have one way that all file configs get loaded, so you learn/debug viper once and now you're good to go for any component vs vttablets use thing1, vtadmin uses thing2, and so on.

@derekperkins
Copy link
Member

yes; it's better to have one way that all file configs get loaded

That's what I assumed, and I think that should be stated in the VEP. Other than that and pending a decision on the deprecation cycle, I think this is great.

Signed-off-by: Andrew Mason <amason@slack-corp.com>
Copy link
Member

@deepthi deepthi left a comment

Choose a reason for hiding this comment

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

Great proposal!
I have some comments/questions inline.


Users can actually already update the way they pass flags and subcommands in a way that won't break, without any code changes needed in Vitess.

The question: **Do we need to do a formal deprecation cycle?**
Copy link
Member

Choose a reason for hiding this comment

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

I think we do need a formal deprecation cycle. More comments below.


Unfortunately, we cannot simply drop-in `pflag` as a replacement for `flag`, despite its advertisement to support exactly that.

Since the very beginning, Vitess documentation has encouraged the use of the single-dash form of flags (e.g. `-my_flag`).
Copy link
Member

Choose a reason for hiding this comment

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

This is the reason we need a deprecation notice. Quite likely everyone is using the single-dash form of flags and changing all of your scripts is non-trivial.
Luckily vitess-operator uses the double-dash form so at least we won't need to update that.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

My understanding of a deprecation cycle (for example, changing a flag name) is:

  1. version 1: old version exists
  2. version 2: old and new versions exist, old "marked" (for some definition of marked) as deprecated. this allows people to switch from the old to the new before going to a version where the old won't work
  3. version 3: old is removed, only new version exists

For flags, we're already in step 2(...ish) because people can migrate their scripts in their current vitess version. The only thing we're missing is the "marking". If we think it's important that happens in the code (vs in release notes / announcements / monthly call), then I totally get it and we'll do the deprecation notice.

flag.Visit(func(f *flag.Flag) {
for _, arg := range argv {
if strings.HasPrefix(arg, "-"+f.Name) {
log.Warningf("Use of single-dash long flags is deprecated and will be removed in 14.0. Please use --%s instead", f.Name)
Copy link
Member

Choose a reason for hiding this comment

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

👍

veps/vep-4.md Outdated
Comment on lines 133 to 135
Now, other packages which declare flags can begin moving to `pflag`.
Once all packages are adding their flags directly to the `pflag.CommandLine` flagset, we can remove the "TODO" interop line.
Now, other packages can gradually move over to `pflag`, and once everything is adding their flags directly to the `pflag` flagset, we can remove the interop line.
Copy link
Member

Choose a reason for hiding this comment

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

Is there some duplicated text here that should be cleaned up?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeeeeeeep 😅

veps/vep-4.md Outdated

Note that there are other places that call `flag.Parse` directly (most in `go/test`, some in `go/cmd`) that will need the same treatment.
In addition, places with subcommands will need to update callsites to take a `pflag.FlagSet`, but the changes there should be fairly minimal.
For example, modulo running `goimports`, [this][mysqlctl_pflag_diff] is the full diff required to compile `mysqlctl`.
Copy link
Member

Choose a reason for hiding this comment

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

Should that link be to a gist or something like that? Also I couldn't really parse this sentence.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It does (easier to see in the Rich Diff view); the gist it links to is defined allll the way down here with the rest of the links.

I can remove the "modulo running goimports" bit (I'm guessing that's where this gets wordy/confusing?); the only reason I added it is it's technically not the actual diff because if you run goimports it (correctly) moves the pflag import down to the 3rd-party section which makes the diff slightly larger/less clear to read. (To be clear: not suggesting we ship a diff that breaks goimports for this work, only that doctoring the diff a bit makes the clarity of the change easier to see for the purpose of the RFC proposal)


For binaries that have many options (like `vttablet`), specifying all of those on the command-line is cumbersome.
In addition, we currently don't support live-reloading of configuration variables.
Live-reload is a huge usability win; consider for example being able to adjust an operation timeout without having to restart the component ... :chefs-kiss:
Copy link
Member

Choose a reason for hiding this comment

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

Agreed. We will still need to cautious about which flags can actually take effect on a running instance. What if someone wants to change a connection pool size, can we actually support that?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right, I think that's a separate design/rfc/project (i.e. one for "tablet connpool live reload" and another for "vreplication timeouts live reload" and so on). Viper only makes this possible/easy to implement, but we still have to add the watch call and reload logic (which is necessarily app-specific and therefore not provided by viper) ourselves explicitly. I will add some language to clarify that here!

Signed-off-by: Andrew Mason <amason@slack-corp.com>
Signed-off-by: Andrew Mason <amason@slack-corp.com>
Copy link
Member

@deepthi deepthi left a comment

Choose a reason for hiding this comment

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

Assuming all feedback has been addressed 👍

Copy link
Member

@deepthi deepthi left a comment

Choose a reason for hiding this comment

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

Can you change this section before merge?

Status: In Review
 Created: 2021-04-07 (second major revision 2021-11-03)

veps/vep-4.md Outdated
Comment on lines 8 to 9
Status: In Review
Created: 2021-04-07 (second major revision 2021-11-03)
Copy link
Member

@deepthi deepthi Feb 18, 2022

Choose a reason for hiding this comment

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

Suggested change
Status: In Review
Created: 2021-04-07 (second major revision 2021-11-03)
Status: Approved
Created: 2021-04-07 (second major revision 2021-11-03)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yep!

Signed-off-by: Andrew Mason <amason@hey.com>
@deepthi deepthi merged commit 637919b into vitessio:main Feb 18, 2022
@ajm188 ajm188 deleted the am_flags_vep branch February 18, 2022 18:20
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.

None yet

4 participants