-
Notifications
You must be signed in to change notification settings - Fork 43
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
Add pkg/querier package #4849
Add pkg/querier package #4849
Conversation
Pull Request Test Coverage Report for Build 11631537336Details
💛 - Coveralls |
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.
How are you feeling about this approach having started it?
I'm a bit nervous about the interaction with transactions; I think I'd rather expose methods to manage a sql.Tx
outside the interface than try to bundle it into the interface if you need transaction support. (Or you could include the transaction in the context, which might be a nice API)
proto/minder/v1/minder.proto
Outdated
|
||
// BundleSubscription represents a subscription to a bundle. | ||
message BundleSubscription { | ||
string id = 1; | ||
string project_id = 2; | ||
string bundle_id = 3; | ||
string current_version = 4; | ||
} |
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 feels like this should be someplace different from the external API, since it's not referenced by any clients.
We have an internal/proto
, but maybe it makes sense to have a pkg/proto (and exclude that from coverage)?
pkg/querier/querier.go
Outdated
ProfileHandlers | ||
BundleHandlers | ||
Close() | ||
Commit() 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.
Do you need a way to start a transaction, given that you have a Commit
method?
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, it looks like you need to throw away the object (and the connection pool) after each transaction?
44b522d
to
eb9837a
Compare
pkg/querier/querier.go
Outdated
RuleTypeHandlers | ||
ProfileHandlers | ||
BundleHandlers | ||
CommitTx() 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.
I'd probably call this Commit
and Cancel
, and document that the object can't be used after calling these.
pkg/querier/querier.go
Outdated
return fmt.Errorf("no transaction to cancel") | ||
} | ||
|
||
// initDb function initializes the database connection and transaction details, if needed |
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 doesn't do anything with transactions, does it?
pkg/querier/querier.go
Outdated
var _ Querier = (*Type)(nil) | ||
|
||
// New creates a new instance of the querier | ||
func New(ctx context.Context, config *server.Config) (Store, func(), 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.
You may want to define a type for the second return argument (it's not clear what you do with a func()
on its own).
pkg/querier/querier.go
Outdated
} | ||
|
||
// Type represents the querier type | ||
type Type struct { |
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.
Why is this type exported?
proto/minder/v1/minder.proto
Outdated
@@ -1023,6 +1023,8 @@ message Project { | |||
// display_names are short *non-unique* strings to provide | |||
// a user-friendly name for presentation in lists, etc. | |||
string display_name = 5; | |||
bool is_organization = 8; |
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.
Discussed offline, but I don't think we want to change our public API in this PR.
Signed-off-by: Radoslav Dimitrov <[email protected]>
Signed-off-by: Radoslav Dimitrov <[email protected]>
Signed-off-by: Radoslav Dimitrov <[email protected]>
Signed-off-by: Radoslav Dimitrov <[email protected]>
Signed-off-by: Radoslav Dimitrov <[email protected]>
return nil, nil, fmt.Errorf("unable to setup eventer: %w", err) | ||
} | ||
// Return the new Type | ||
return &querierType{ |
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, this is cute -- you're using querierType as both Store
and Querier
. I think that won't hurt you; anyone who goes to cast one to the other gets what's coming to them.
} | ||
// Return the new Type | ||
return &querierType{ | ||
store: store, |
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 probably don't need both querier
and store
with the new implementation, but I'm not going to begrudge you 8 bytes.
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 know this unlocks my embedded programming side if you do that 😁
pkg/querier/querier.go
Outdated
if q.tx != nil { | ||
err := q.store.Commit(q.tx) | ||
// Clear the transaction and the querier | ||
q.tx = nil | ||
q.querier = nil | ||
return err | ||
} | ||
return fmt.Errorf("no transaction to commit") |
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.
No need to fix here, but I'd tend to use the "early exit" model for these sorts of checks:
if q.tx != nil { | |
err := q.store.Commit(q.tx) | |
// Clear the transaction and the querier | |
q.tx = nil | |
q.querier = nil | |
return err | |
} | |
return fmt.Errorf("no transaction to commit") | |
if q.tx == nil { | |
return fmt.Errorf("no transaction to commit") | |
} | |
err := q.store.Commit(q.tx) | |
// Clear the transaction and the querier | |
q.tx = nil | |
q.querier = nil | |
return err |
When reading code, I find that I need to keep a mental stack open whenever I'm in a conditional to recall what the code path is with and without the conditional. Having conditionals that close quickly with early returns lets me retire that call stack in my head, and leaves the "most common" code path running to the end of the function.
pkg/querier/querier.go
Outdated
zerolog.Ctx(ctx).Debug(). | ||
Str("name", cfg.Database.Name). | ||
Str("host", cfg.Database.Host). | ||
Str("user", cfg.Database.User). | ||
Str("ssl_mode", cfg.Database.SSLMode). | ||
Int("port", cfg.Database.Port). | ||
Msg("connecting to minder database") |
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.
We log these inside GetDBConnection
too, don't we?
To be clear, the above are nits, and I'm fine with the code going in as-is. |
Signed-off-by: Radoslav Dimitrov <[email protected]>
Summary
The following PR adds a querier package to pkg. Its purpose is to expose a set of tools to interact with the Minder database.
The wrappers for managing the ruletypes and profiles are wrapped around their service alternatives as making changes to these entries without validating them can cause conflicts in the profile references and evaluations.
Change Type
Mark the type of change your PR introduces:
Testing
Outline how the changes were tested, including steps to reproduce and any relevant configurations.
Attach screenshots if helpful.
Review Checklist: