-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
Initial implementation of vtctld service #7128
Conversation
I've only added some simple keyspace-related getters for now. No documentation or tests or anything yet, this is just a proof-of-concept / example implementation. Signed-off-by: Andrew Mason <amason@slack-corp.com>
Signed-off-by: Andrew Mason <amason@slack-corp.com>
I very quickly ran into circular imports trying to keep things colocated. Signed-off-by: Andrew Mason <amason@slack-corp.com>
…typo 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>
We bring in cobra to manage the CLI for us; it's the most structured one Vitess has had yet. This also forces us to do _something_ about the various project-global flags, but it's a compromise - essentially we just blindly apply all of them to the root of our command tree. Signed-off-by: Andrew Mason <amason@slack-corp.com>
Signed-off-by: Andrew Mason <amason@slack-corp.com>
It turns out that some vitess packages make calls to `flag.Lookup` to find flag values, and if we swap out the original flagset, these all fail, and in some cases, panic. I encountered this while attempting to move vttablet to cobra in a separate branch, and the panic came from `logutil.PurgeLogs()` needing a `log_dir` flag ([ref][logutil_ref]). [logutil_ref]: https://github.com/vitessio/vitess/blob/20a545533bc94d6f85e1682a6539e93c32a82486/go/vt/logutil/purge.go#L106-L109 While this appears to actually not matter for the vtctldclient, since the code with the potential bug is able to run without issue, I don't want to commit a potentially-risky flag shim into the codebase that may be copied by others. Signed-off-by: Andrew Mason <amason@slack-corp.com>
proto/vtctlservice.proto
Outdated
// GetKeyspaces returns the names of all keyspaces in the topo. | ||
rpc GetKeyspaces(vtctldata.GetKeyspacesRequest) returns (vtctldata.GetKeyspacesResponse) {}; |
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 GetKeyspaces not returning the actual object because that's not how the existing rpc works? I would vote for this call to return the list of keyspace objects that you've currently created a new RPC for. If we want to be able to restrict the data that is returned, I would prefer to use a view or a fieldmask. https://google.aip.dev/157
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 that was originally my reason. What do you think about removing the "just the names" rpc entirely, and having clients do for _, ks := range kss { ks.Name }
if they want?
I think the downside to using a fieldmask in this specific case is the "subset" of fields we want is actually a list of scalars, so our return types should either be []string
or []*pb.Keyspace
, which I'm not sure how to represent nicely in protos.
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.
Agreed, my vote is to return the whole object as []*pb.Keyspace
and eliminate the ShowAllKeyspaces
rpc
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.
Semi-related, it's weird that the underlying topodata.Keyspace
proto doesn't have the name easily accessible, making you wrap that message 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.
Yeah I agree. I wonder how controversial of a change it would be to put a name
field in the Keyspace
and Shard
protos or if that would require a more careful migration. If the latter I'd rather stick with this thin wrapper for now and revisit later.
@deepthi do you have any thoughts 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.
To the first point, all rpcs take a Request
proto and return a Response
proto. This allows us to change the contents of the proto between versions without breaking compatibility.
Regarding adding name
to the proto objects: AFAICT the logic seems to have been that the name
of the object is the filename and the object is a representation of the file contents. This makes perfect sense from the POV of the topo - why duplicate information and why not keep the data small.
As we expand the usage of these proto objects beyond topo calls and start passing them around, it will be nice to not have to wrap them with another object that has the name, so I'm not opposed to this change. We can rely on protobuf compatibility guarantees.
@sougou @enisoc please chime in if you disagree.
proto/vtctlservice.proto
Outdated
// ShowAllKeyspaces returns the keyspace struct of each keyspace in the topo. | ||
rpc ShowAllKeyspaces(vtctldata.ShowAllKeyspacesRequest) returns (stream vtctldata.Keyspace) {}; |
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 there a compelling reason to return a stream vs just a standard reply/response? Streams are much more difficult to consume and reason about. There's a pretty good discussion about the drawbacks here.
twitchtv/twirp#70 (comment)
There are obviously cases for them, especially inside of Vitess, but if we can avoid them in this server definition, I think we'll be better off.
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 was a super good thread, thank you for sharing that! I think it hit the nail right on the head w.r.t. "is there a compelling reason" with
people could easily reach for it too early in order to future-proof their APIs, "just in case we need streams later," and walk themselves into an architectural hole which is very difficult to get out of.
I'll switch it to a unary RPC!
In a separate branch, I was exploring making the streaming collect the keyspaces from the topo and send them to the stream in separate goroutines, and the complexity exploded pretty quickly.
Co-authored-by: Derek Perkins <derek@derekperkins.com> Signed-off-by: Andrew Mason <amason@slack-corp.com>
Signed-off-by: Andrew Mason <amason@slack-corp.com>
0b418ef
to
9064b14
Compare
Signed-off-by: Andrew Mason <amason@slack-corp.com>
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.
lgtm.
I pulled the branch and it works fine. If you fix the go.sum conflict I can merge.
proto/vtctlservice.proto
Outdated
// Service Vtctld exposes gRPC endpoints for each vt command. | ||
service Vtctld { | ||
// GetKeyspace reads the given keyspace from the topo and returns it. | ||
rpc GetKeyspace(vtctldata.GetKeyspaceRequest) returns (vtctldata.Keyspace) {}; |
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 fix this before we merge? Return type should be GetKeyspaceResponse
.
The rest looks good 👍
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.
Done! Looking at that conflict now
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.
FWIW, we wrap everything in a response internally like you are suggesting, but I was surprised to see that the current Google recommendations are to return the object itself on a Get
https://google.aip.dev/131
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.
oh! that's interesting..
maybe we should adopt that in that case for the new RPCs (they are new after all).
@ajm188 we can merge this PR as-is but revisit the return types.
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 I was kind of wondering about that ... I don't think the Response
wrappers actually get you any additional compatibility guarantees. If I have a response like Response: {MyObject: {Field1, Field2}}
vs MyObject: {Field1, Field2}
, if I need to remove Field2, either way it's going to break the client, and if I want to add a field, either way it's optional to the client and goes unnoticed.
Anyway, happy to revisit this. Right now trying to figure out why after merging master and running go mod tidy
I'm seeing:
❯ golangci-lint run
WARN [runner] Can't run linter goanalysis_metalinter: bodyclose: failed prerequisites: [buildssa@vitess.io/vitess/go/test/endtoend/onlineddl [vitess.io/vitess/go/test/endtoend/onlineddl.test]: analysis skipped: errors in package: [/Users/amason/work/vitess/go/test/endtoend/onlineddl/onlineddl_test.go:209:9: undeclared name: testAlterTable]]
ERRO Running error: bodyclose: failed prerequisites: [buildssa@vitess.io/vitess/go/test/endtoend/onlineddl [vitess.io/vitess/go/test/endtoend/onlineddl.test]: analysis skipped: errors in package: [/Users/amason/work/vitess/go/test/endtoend/onlineddl/onlineddl_test.go:209:9: undeclared name: testAlterTable]]
ERRO Timeout exceeded: try increasing it by passing --timeout option
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.
Ah, it looks like this PR missed one rename
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.
Fixed in #7148
…sites and tests 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>
323f345
to
30dfa30
Compare
Signed-off-by: Andrew Mason <amason@slack-corp.com>
Signed-off-by: Andrew Mason <amason@slack-corp.com>
Initial implementation of vtctld service
Initial implementation of vtctld service
Backport
NO
Status
READY
Description
This PR introduces the initial implementation of the vtctld API server, providing the foundation for the rest of the server implementation, and defining the CLI structure for the client binary.
Of note, this is also the first usage of cobra in vitess, which requires some extra care around vitess's flags, which is documented in a comment. Some additional refactoring globally (which I think is complex and large enough to be its own project) would make this way nicer to use (and would also let us solve issues like #4921 with viper easily).
The other thing that I want to explicitly call out is that in addition to migratingInstead, I changedGetKeyspaces
andGetKeyspace
, I introduced a new command,ShowAllKeyspaces
, which is the equivalent of runningfor ks in $(vtctl GetKeyspaces); vtctl GetKeyspace $ks; done
.GetKeyspaces
to provide the full keyspace struct for each keyspace in the topo instead of just the keyspace names.Related Issue(s)
#7058.
This resolves #7133.
Deployment Notes
To deploy these changes:
grpc-vtctld
to the CSV-service_map
argumentvtctldclient --server localhost:15999 --help
)Impacted Areas in Vitess
List general components of the application that this PR will affect:
Testing
After spinning up
./examples/local/101_initial_cluster.sh
: