-
Notifications
You must be signed in to change notification settings - Fork 615
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
Generate data store code #2039
Generate data store code #2039
Conversation
Codecov Report
@@ Coverage Diff @@
## master #2039 +/- ##
==========================================
+ Coverage 53.37% 53.85% +0.47%
==========================================
Files 111 111
Lines 19703 19211 -492
==========================================
- Hits 10517 10346 -171
+ Misses 7917 7605 -312
+ Partials 1269 1260 -9 Continue to review full report at Codecov.
|
Updated to also generate code for |
d040c4d
to
6c72dfd
Compare
Rebased. Let's try to get this in. I think it's a big improvement. We can continue to make improvements as we go. |
Can you add a test for code generation to validate the generated code is expected? |
@dongluochen: What kind of test do you have in mind? There are unit tests in |
If they have covered the generated functions, that would be enough. |
Understood. Let me give it a try. |
|
||
d.P("func (indexer ", ccTypeName, "IndexerByName) FromObject(obj interface{}) (bool, []byte, error) {") | ||
d.In() | ||
d.P("m := obj.(*", ccTypeName, ")") |
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.
In the code that the auto-generation replaces, we check if the cast succeeds, else we panic saying that the object passed to FromObject
is invalid. Do we also need to do that here (and also in the CustomIndexer
and IndexByID
in the auto-generated code?
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 catch but I left it out because this would only happen if the code setting up the indices was wrong, and if it was, this will panic anyway the first time one of those objects is added to the store. Having a fancier custom panic for this use case didn't seem worth generating the extra code.
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 ok, then do we want to remove the panic check in the other indexers then? (e.g. the other Task
ones)
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.
Removing them should be fine, but I don't think it matters either way.
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.
Sounds good - I have no strong feelings, was just wondering if we should be consistent.
api/objects.proto
Outdated
@@ -25,6 +26,8 @@ message Meta { | |||
|
|||
// Node provides the internal node state as seen by the cluster. | |||
message Node { | |||
option (docker.protobuf.plugin.store_object) = { table: "node" }; |
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.
Non-blocking dumb question: I am probably just not seeing it, but where is this option used in the code generation?
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.
It is not used yet. I anticipated automatically generating the index schema, but it's not there yet. On further consideration, if/when this happens it should just be generated from a lowercased version of the object name. I'll remove this.
Note that #2034 extends this protobuf option with further fields.
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 cool, ok, thanks!
@dongluochen: @cyli generously generated cross-package coverage info, and found that the unit tests are covering most of the generated code. Not every single generated function is covered (for example, particular events that are not used by the unit tests), but since a lot of these generated functions are essentially duplicates of each other, it looks like the existing tests are giving us a very good cross section that covers essentially everything that the code generation is doing. I can give you the coverage profile if you're interested. |
6c72dfd
to
284e647
Compare
Rebased, and removed |
LGTM |
1 similar comment
LGTM |
} | ||
|
||
// UpdateCluster updates an existing cluster in the store. | ||
// Returns ErrNotExist if the cluster doesn't exist. | ||
func UpdateCluster(tx Tx, c *api.Cluster) error { | ||
// Ensure the name is either not in use or already used by this same Cluster. | ||
if existing := tx.lookup(tableCluster, indexName, strings.ToLower(c.Spec.Annotations.Name)); existing != nil { | ||
if existing.ID() != c.ID { | ||
if existing.GetID() != c.ID { |
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.
nit: Why the change? Typically in Go getters are not prefixed by Get
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.
ID()
would conflict with the ID
field.
LGTM Couple of questions:
|
I would like this but I don't know of a way to do it. The code generation that's part of protobuf seems to just add stuff to the
Seems tricky. Anyway, it would definitely be something for a followup. |
Generate interface methods on top-level objects so they can be used directly by the store instead of needing a wrapper. Generate some basic indexers. Signed-off-by: Aaron Lehmann <[email protected]>
Signed-off-by: Aaron Lehmann <[email protected]>
Signed-off-by: Aaron Lehmann <[email protected]>
284e647
to
48b7518
Compare
It has become difficult to add top-level object types. Doing so involves copying/pasting a lot of code in the store, and potentially making mistakes. We had considered changing the object model to work around this, but decided that we already have the right object model - we just have a code problem. Code generation can solve the code duplication and tedium of adding top-level objects.
This PR is a start at doing that. First, it simplifies the object-specific code in the store by generating interface methods on each top-level type, so the store doesn't have to use a wrapper type to provide methods like
ID()
,Meta()
, etc.As part of this, the event types had to be moved into the
api
package to avoid a circular dependency. While we're at it, we code generate those event types, which were another annoying bit of boilerplate.Finally, this can generate a few basic indexers. More will come, perhaps by marking the fields of interest in the
.proto
file with an extension option.cc @docker/core-swarmkit-maintainers