-
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
RFC: Vtctld Service #7058
Comments
|
I'm very excited for this. We've avoided some automation simply because the old "api" was so fickle to deal with. It has also held back innovation on the Vitess dashboard & UI. |
|
This is very detailed and thorough. |
|
Yeah, we definitely want to deprecate that. Correct me if I'm wrong, but I think to maintain compatibility guarantees the ordering would have to be:
|
|
VEP-3 specifically deals with components of a running vitess system. |
|
Design and implementation plan look great. I also really like the fact that this uses cobra: allows us to use bash completion, auto-suggest and sub-commands etc etc. I had tried to retrofit cobra but we decided it wasn't worth the effort at that time. Also a useful effect is that a lot of deprecated and obsolete commands will get dropped. |
Yeah, revisiting flags more holistically is uhhhh another thing I would be interested in doing at some point 😅 |
(I'm working on a sharable google doc form, for folks that would prefer to comment inline)
Abstract
This document presents a design to define a well-typed gRPC interface to the vtctld component of Vitess.
Background
The current vtctl API is a gRPC interface defining a single method:
Note: this is a modified example to fit in one snippet.
This interface gave us the flexibility to add, modify, and remove commands quickly, without needing to worry about adherence to a strict protobuf API definition.
It now poses several problems.
First, from the client perspective, this is effectively an untyped interface. Unlike other gRPC interfaces, the first element of
ExecuteVtctlCommandRequest.argsdetermines the underlying method call and the shape of the response data. We lose the benefit of protobufs defining the structure on both sides of the network boundary, and must parse arbitrary, sometimes-but-not-always JSON-formatted bytes into data structures before we can do anything with them. The list of available methods and their arguments, as well as the shape of their responses may change at any time, without any feedback or warning from the Go compiler. Further, some of the current vtctl methods use customMarshalJSONimplementations, without providing the inverseUnmarshalJSON, forcing the client to define nearly-identical types to provide this behavior. These types must be kept in sync by the client, causing additional maintenance burden.Second, on 07/24/2020, VEP3: Vitess Upgrade Order removed the upgrading ordering requirements, beginning with version 8.0. VEP3 specified a new requirement to facilitate this change: “a new version of a server must work with an old version as well as the current version.” Due to other problems mentioned in the above paragraph, this is difficult, if not impossible, to guarantee at compile time for the vtctl API.
Goals
Non-Goals
Proposal
We propose to add a new service to the existing
vtctldservice.protofile, calledVtctldthat will live alongside theVtctlservice.Design
The service will provide one RPC definition for each supported vtctl command (
GetKeyspaces,GetVSchema,Backup,VReplicationExecetc). Any additional message definitions will be defined invtctldata.proto, unless a more appropriate proto file is identified.When adding an RPC to
VtctldServer, the corresponding legacy implementation should be updated to invoke the new implementation under the hood, and then invoke the usualprintJSON(wr.Logger(), resp). For a proof-of-concept of this, see brancham_vtctld_proto.A few things to point out in that example:
VtctldServerimplementation does not take aWrangler, instead it has its ownTopoServerandTabletManagerClientfields. We discuss this further in Other Considerations.Wranglerwill eventually include a*VtctldServerto reduce allocations.package
vtctlclientPackage
vtctlclientuses a factory pattern to return an implementation ofVtctlClient. Clearly, this does not work with the new interface defined by theVtctldprotobuf.Instead, we introduce a new interface defined as:
From there, we add a new factory and constructor:
Identical with the current layout,
fakevtctlclientandgrpcvtctlclientwill provide implementations and register factories for those implementations.vtctlclienttestwill adapt the current test suite to the new interface.Compatibility Considerations
vtworker(legacy), “automation”, andvttest.We will need to update vtworker, automation, and vttest to use the new
vtctldclient. An outstanding question for me is if we can ignore vtworker, or if that needs to be updated as well.Timeline and Rollout
A codebase with two competing ways of accomplishing a task can be frustrating to work in at best, and risky to work in at worst. We want to minimize the amount of time in this state. To accomplish this, we will declare the
VtctldServerinterface to be unstable until it has met parity with theVtctlServer. We can consider the two at parity when all legacy vtctl commands defer their logic to the correspondingVtctldServermethods.What “unstable” means in this context may be unorthodox, so:
VtctldServerdo so at their own risk; we reserve the ability to change the shape of the API at any point during the unstable period.VtctldServerAPI, we will perform the necessary changes to ensure indirect clients do not break.The distinction here is that an engineer writing an arbitrary external program against the
VtctldServershould not trust the stability of the interface during the transition, but when changing any particularVtctldServermethod, we will update any vtctl commands that call that method to ensure correct behavior from a blackbox perspective.We aim for this period to take less than two months.
After reaching parity, the
VtctldServerAPI will be declared stable and become subject to all the standard release cadence and compatibility standards of the Vitess project. At the same time, we will declare theVtctlServerAPI to be deprecated.Other Considerations
We choose to make
VtctldServertake its ownTopoServerandTabletManagerClientfor interacting with the topo, and to haveWranglertake aVtctldServerto have calls flow in that direction. Alternatively, we could forceVtctldServeruse aWranglerto access the topo. This would look like:I have no strong opinion. At first glance, giving
VtctldServerdirect access to the topo server feels simpler than forcing everything through the wrangler, but this is a very minor point with respect to the overall proposal. If going through wrangler is indeed better, then we will switch to that.We chose to create an entire second interface rather than progressively add typed methods to the existing interface. We spent an afternoon exploring this alternative and found that the number of types and mocks that would need updating each time a method was added wasn’t worth the trouble of keeping the
vtctlname. The upside here is getting to move faster; the downside here is that we have to pick a new name, hencevtctld.The text was updated successfully, but these errors were encountered: