-
Notifications
You must be signed in to change notification settings - Fork 278
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
Reorganize serve flags into flagsets #2023
Conversation
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.
See comments
func RegisterDatastoreFlags(cmd *cobra.Command, opts *Config) error { | ||
return RegisterDatastoreFlagsWithPrefix(cmd.Flags(), "", opts) | ||
func RegisterDatastoreFlags(cmd *cobra.Command, flagset *pflag.FlagSet, opts *Config) error { | ||
return RegisterDatastoreFlagsWithPrefix(flagset, "", opts) |
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.
Passing in the flagset so we can get them properly grouped.
ot := cobraotel.New(cmd.Use) | ||
ot.RegisterFlags(cmd.PersistentFlags()) | ||
if err := ot.RegisterFlagCompletion(cmd); err != nil { | ||
return fmt.Errorf("failed to register otel flag completion: %w", err) | ||
} | ||
|
||
releases.RegisterFlags(cmd.PersistentFlags()) | ||
termination.RegisterFlags(cmd.PersistentFlags()) | ||
runtime.RegisterFlags(cmd.PersistentFlags()) |
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.
This is cribbing from #2022 - these flags are really more serve-specific than root flags, so we move them up into serve so that we can group them accordingly.
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 think we still need these at least for migrate
commands - maybe serve-testing
too?
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.
Yeah... in #2022 they're moved into a function that registers them and then that function is reused. I can mimic that.
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 went ahead and added them to migrate
but I'm gonna push back on serve-testing
for the time being.
pkg/cmd/serve.go
Outdated
grpcFlagSet := nfs.FlagSet("gRPC") | ||
// Flags for logging | ||
cmd.Flags().BoolVar(&config.EnableRequestLogs, "grpc-log-requests-enabled", false, "logs API request payloads") | ||
cmd.Flags().BoolVar(&config.EnableResponseLogs, "grpc-log-responses-enabled", false, "logs API response payloads") | ||
grpcFlagSet.BoolVar(&config.EnableRequestLogs, "grpc-log-requests-enabled", false, "logs API request payloads") | ||
grpcFlagSet.BoolVar(&config.EnableResponseLogs, "grpc-log-responses-enabled", false, "logs API response payloads") |
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.
This is basically the pattern you'll see - create a flagset on the flagsets with a name (and they're declared in the order they're displayed) and then attach a bunch of flags to the named flagset rather than the command's flagset.
pkg/cmd/serve.go
Outdated
// TODO: this one should maybe not live in API? | ||
apiFlags.Uint64Var(&config.MaxDatastoreReadPageSize, "max-datastore-read-page-size", 1_000, "limit on the maximum page size that we will load into memory from the datastore at one time") |
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.
Wasn't sure whether this should be api or datastore
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 would call this datastore since it affects how data is loaded from the backend
pkg/cmd/serve.go
Outdated
// TODO: should this be under datastore or api? | ||
datastoreFlags.DurationVar(&config.SchemaWatchHeartbeat, "datastore-schema-watch-heartbeat", 1*time.Second, "heartbeat time on the schema watch in the datastore (if supported). 0 means to default to the datastore's minimum.") |
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.
Same here
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.
This is datastore - this controls how spicedb pro-actively fills its cache with the schema from the backend
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.
Actually this might fit better in the Namespace cache section, since it controls the automatic filling of that cache from Watch. But also that feature is still experimental 😓
// TODO: these two could reasonably be put in either the Dispatch group or the Experimental group. Is there a preference? | ||
experimentalFlags.StringToStringVar(&config.DispatchSecondaryUpstreamAddrs, "experimental-dispatch-secondary-upstream-addrs", nil, "secondary upstream addresses for dispatches, each with a name") | ||
experimentalFlags.StringToStringVar(&config.DispatchSecondaryUpstreamExprs, "experimental-dispatch-secondary-upstream-exprs", nil, "map from request type (currently supported: `check`) to its associated CEL expression, which returns the secondary upstream(s) to be used for the request") |
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.
Same here.
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.
Good question - I don't have a strong preference since once these are no longer experiments we'll put them in the right place anyway. I like what you've done here in grouping the experiments together.
@josephschorr or @jzelinskie sometimes have opinions about this kind of thing though.
pkg/cmd/serve.go
Outdated
observabilityFlags := nfs.FlagSet("Observability") | ||
// Flags for observability and profiling | ||
otel := cobraotel.New(cmd.Use) | ||
otel.RegisterFlags(observabilityFlags) | ||
runtime.RegisterFlags(observabilityFlags) |
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.
This is where the flags that used to live in the root command landed
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.
see my other comment - I think we at least need these on migrate
, and maybe others 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.
Looking good! Much easier to scan flags now.
I noticed that our examples use colors (when supported) - I don't know how hard this would be, but it might be nice to add some color to the flagset headers so that gRPC Flags
and HTTP Flags
etc are different colors. If there's a simple way to do that I think it would help delineate the blocks even more than now (if it's a whole big project do make that happen don't worry about it).
pkg/cmd/datastore/datastore.go
Outdated
@@ -159,8 +159,8 @@ type Config struct { | |||
} | |||
|
|||
// RegisterDatastoreFlags adds datastore flags to a cobra command. | |||
func RegisterDatastoreFlags(cmd *cobra.Command, opts *Config) error { | |||
return RegisterDatastoreFlagsWithPrefix(cmd.Flags(), "", opts) | |||
func RegisterDatastoreFlags(cmd *cobra.Command, flagset *pflag.FlagSet, opts *Config) error { |
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.
func RegisterDatastoreFlags(cmd *cobra.Command, flagset *pflag.FlagSet, opts *Config) error { | |
func RegisterDatastoreFlags(flagset *pflag.FlagSet, opts *Config) error { |
cmd is unused now, right?
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 it possible to nest flagsets? The datastore set is pretty big and I see some natural points we could break it up; i.e. connection pooling, bootstrapping, etc
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 don't think so - the hierarchy seems to be cobra.Command
-> nfs.NamedFlagSets
-> nfs.FlagSet
, and there isn't a recursive definition in there. I could add additional categories under datastore if you think that would help, though.
ot := cobraotel.New(cmd.Use) | ||
ot.RegisterFlags(cmd.PersistentFlags()) | ||
if err := ot.RegisterFlagCompletion(cmd); err != nil { | ||
return fmt.Errorf("failed to register otel flag completion: %w", err) | ||
} | ||
|
||
releases.RegisterFlags(cmd.PersistentFlags()) | ||
termination.RegisterFlags(cmd.PersistentFlags()) | ||
runtime.RegisterFlags(cmd.PersistentFlags()) |
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 think we still need these at least for migrate
commands - maybe serve-testing
too?
pkg/cmd/serve.go
Outdated
// TODO: this one should maybe not live in API? | ||
apiFlags.Uint64Var(&config.MaxDatastoreReadPageSize, "max-datastore-read-page-size", 1_000, "limit on the maximum page size that we will load into memory from the datastore at one time") |
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 would call this datastore since it affects how data is loaded from the backend
pkg/cmd/serve.go
Outdated
// TODO: should this be under datastore or api? | ||
datastoreFlags.DurationVar(&config.SchemaWatchHeartbeat, "datastore-schema-watch-heartbeat", 1*time.Second, "heartbeat time on the schema watch in the datastore (if supported). 0 means to default to the datastore's minimum.") |
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.
This is datastore - this controls how spicedb pro-actively fills its cache with the schema from the backend
// TODO: these two could reasonably be put in either the Dispatch group or the Experimental group. Is there a preference? | ||
experimentalFlags.StringToStringVar(&config.DispatchSecondaryUpstreamAddrs, "experimental-dispatch-secondary-upstream-addrs", nil, "secondary upstream addresses for dispatches, each with a name") | ||
experimentalFlags.StringToStringVar(&config.DispatchSecondaryUpstreamExprs, "experimental-dispatch-secondary-upstream-exprs", nil, "map from request type (currently supported: `check`) to its associated CEL expression, which returns the secondary upstream(s) to be used for the request") |
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.
Good question - I don't have a strong preference since once these are no longer experiments we'll put them in the right place anyway. I like what you've done here in grouping the experiments together.
@josephschorr or @jzelinskie sometimes have opinions about this kind of thing though.
apiFlags.Uint16Var(&config.MaximumPreconditionCount, "update-relationships-max-preconditions-per-call", 1000, "maximum number of preconditions allowed for WriteRelationships and DeleteRelationships calls") | ||
// TODO: this one should maybe not live in API? | ||
apiFlags.Uint64Var(&config.MaxDatastoreReadPageSize, "max-datastore-read-page-size", 1_000, "limit on the maximum page size that we will load into memory from the datastore at one time") | ||
apiFlags.BoolVar(&config.DisableV1SchemaAPI, "disable-v1-schema-api", false, "disables the V1 schema API") |
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 think we can hide this flag, I don't think there's much utility for most users.
pkg/cmd/serve.go
Outdated
// TODO: should this be under datastore or api? | ||
datastoreFlags.DurationVar(&config.SchemaWatchHeartbeat, "datastore-schema-watch-heartbeat", 1*time.Second, "heartbeat time on the schema watch in the datastore (if supported). 0 means to default to the datastore's minimum.") |
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.
Actually this might fit better in the Namespace cache section, since it controls the automatic filling of that cache from Watch. But also that feature is still experimental 😓
util.RegisterGRPCServerFlags(cmd.Flags(), &config.DispatchServer, "dispatch-cluster", "dispatch", ":50053", false) | ||
server.MustRegisterCacheFlags(cmd.Flags(), "dispatch-cache", &config.DispatchCacheConfig, dispatchCacheDefaults) | ||
server.MustRegisterCacheFlags(cmd.Flags(), "dispatch-cluster-cache", &config.ClusterDispatchCacheConfig, dispatchClusterCacheDefaults) | ||
util.RegisterGRPCServerFlags(dispatchFlags, &config.DispatchServer, "dispatch-cluster", "dispatch", ":50053", false) |
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.
this is good but I think we could further break down the dispatch flags if we wanted to: dispatch server, dispatch (client) cache, dispatch (server) cache, hashring config, etc.
@ecordell re: color: I think it's just on the far side of easy. I tried https://github.com/ivanpirog/coloredcobra and it isn't aware of flagsets, and I tried
I think it'd be possible to do it, but it'd require more manual intervention, so I'm gonna leave it for now and work on addressing your other comments. |
cmd.Flags().StringVar(&config.TelemetryEndpoint, "telemetry-endpoint", telemetry.DefaultEndpoint, "endpoint to which telemetry is reported, empty string to disable") | ||
cmd.Flags().StringVar(&config.TelemetryCAOverridePath, "telemetry-ca-override-path", "", "TODO") | ||
cmd.Flags().DurationVar(&config.TelemetryInterval, "telemetry-interval", telemetry.DefaultInterval, "approximate period between telemetry reports, minimum 1 minute") | ||
|
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.
You need to add this to the end in order for the flags to actually be registered with the command. This seems like an unintuitive DX for cobrautil
:
nfs.AddFlagSets(cmd)
Co-authored-by: Evan Cordell <[email protected]>
2880c7f
to
0e4105b
Compare
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 think the changes to the otel flags are doing weird things:
On serve:
--otel-service-name string service name for trace data (default "serve")
Vs the previous:
--otel-service-name string service name for trace data (default "spicedb")
Also look at migrate:
--otel-service-name string service name for trace data (default "migrate [revision]")
I also don't see --schema-prefixes-required
in the new flagsets:
$ go run ./cmd/spicedb/... serve -h | grep prefixes
It was kind of tricky to review that the flags hadn't changed - I wonder if we should have a test that with a list of flags to confirm are in the output?
Description
The flags on
spicedb serve --help
are numerous. It makes parsing through them to figure out which ones are relevant and which ones you need pretty difficult. This is the first step towards addressing that - we organize the flags into flagsets which provides a bit of logical and visual grouping.Changes
Gonna annotate.
Testing
Review.
./spicedb serve --help
and see that all of the expected flags are present and that they are organized more nicely.