-
Notifications
You must be signed in to change notification settings - Fork 833
Add an ability to load an arbitrary list of Cortex modules #3275
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
Conversation
Signed-off-by: Igor Novgorodov <[email protected]>
Signed-off-by: Igor Novgorodov <[email protected]>
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.
Thanks for working on this! I left few comments. @pstibrany what do you think?
CHANGELOG.md
Outdated
* [FEATURE] Implement an ability to load multiple Cortex modules using a comma-separated list. #3272 | ||
- Should be backwards compatible with the current behavior. | ||
- Target list like 'all,compactor' can be used to load the single-binary modules plus some other modules. |
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 suggest a little rephrasing to simplify it:
* [FEATURE] Implement an ability to load multiple Cortex modules using a comma-separated list. #3272 | |
- Should be backwards compatible with the current behavior. | |
- Target list like 'all,compactor' can be used to load the single-binary modules plus some other modules. | |
* [ENHANCEMENT] Allow to specify multiple comma-separated Cortex services to `-target` CLI option (or its respective YAML config option). For example, `-target=all,compactor` can be used to start Cortex single-binary with compactor as well. #3272 |
We consider these improvements "enhancement" and not new core features. Please move the changelog entry to the right place (entries are grouped by type).
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.
Sure, forgot that they're grouped.
pkg/cortex/modules.go
Outdated
// whenever it's not running as an internal dependency (ie. querier or | ||
// ruler's dependency) | ||
canJoinDistributorsRing := (t.Cfg.Target == All || t.Cfg.Target == Distributor) | ||
canJoinDistributorsRing := t.Cfg.Modules[Distributor] || t.Cfg.Modules[All] |
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 should do a similar change in initAlertManager()
too.
pkg/cortex/cortex.go
Outdated
PrintConfig bool `yaml:"-"` | ||
HTTPPrefix string `yaml:"http_prefix"` | ||
Target string `yaml:"target"` | ||
Modules map[string]bool `yaml:"-"` |
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 keeping both Target string
and the new Modules map[string]bool
may lead to bugs in the future. We may forget to check Modules
instead of Target
. A better option may be define a CLI flag custom type in pkg/util/flagext
which is a []string
but implements flag.Value
and yaml.Marshaller/Unmarshaller
to marshal/unmarshal a comma separated string.
We wouldn't have a map, but checking if a module is within the []string
would be as easy as calling util.StringsContain()
.
What do you think?
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.
There's already flagext.StringSlice, should I just use it?
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.
flagext.StringSlice
doesn't support comma-separated argument, only argument with multiple flags. I'm afraid that would be incompatible change in YAML config.
pkg/util/modules/modules.go
Outdated
modules map[string]*module | ||
|
||
// Modules that are already initialized | ||
modulesLoaded map[string]bool |
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 rename "loaded" into "initialised", which is the naming we use here.
pkg/util/modules/modules.go
Outdated
} | ||
|
||
// GetServicesMap returns services map | ||
func (m *Manager) GetServicesMap() map[string]services.Service { |
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 may call it GetInitialisedServices()
and update the comment accordingly.
pkg/util/modules/modules.go
Outdated
|
||
for ix, n := range deps { | ||
// Skip already loaded modules | ||
if m.modulesLoaded[n] { |
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.
Couldn't we just check m.servicesMap
?
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.
That wouldn't work... not all modules have a service.
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.
Thank you for working on this! I suggest we keep the changes to modules.Manager
backwards compatible and not introduce new public API to it (it's always easy to add new methods, and difficult to remove them once they get used), since there are several other projects using this other than Cortex.
pkg/util/modules/modules.go
Outdated
func (m *Manager) InitModuleServices(target string) (map[string]services.Service, error) { | ||
if _, ok := m.modules[target]; !ok { | ||
return nil, fmt.Errorf("unrecognised module name: %s", target) | ||
func (m *Manager) InitModuleServices(name string) 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.
Could we make it work with this signature instead?
func (m *Manager) InitModuleServices(name string) error { | |
func (m *Manager) InitModuleServices(names ...string) (map[string]services.Service, error) |
There are multiple projects using this system, and this is backwards compatible, while your suggestion isn't. Furthermore it keeps the state of initialization outside of this manager.
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.
Sure, didn't know that anything else other than Cortex used it.
pkg/util/modules/modules.go
Outdated
} | ||
|
||
// IsModuleRegistered returns true if given module was registered | ||
func (m *Manager) IsModuleRegistered(mod string) bool { |
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.
Let's not introduce new public methods to manager, that are not needed externally.
Signed-off-by: Igor Novgorodov <[email protected]>
Signed-off-by: Igor Novgorodov <[email protected]>
Signed-off-by: Igor Novgorodov <[email protected]>
Thanks for the comments everyone.
|
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.
Thank you for addressing my feedback! I have left more comments in the spirit of “minimize state”.
Signed-off-by: Igor Novgorodov <[email protected]>
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.
Thank you a lot for your patience. This is on the right track, few more minor nits.
pkg/cortex/cortex.go
Outdated
f.Var((*flagext.StringSliceCSV)(&c.Target), "target", "List of Cortex modules to load, comma separated. "+ | ||
"The alias 'all' can be used in the list to load a number of core modules and will enable single-binary mode. "+ | ||
"Use '-modules' command line flag to get a list of available modules, and to see which modules are included in 'all'.") | ||
|
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.
f.Var((*flagext.StringSliceCSV)(&c.Target), "target", "List of Cortex modules to load, comma separated. "+ | |
"The alias 'all' can be used in the list to load a number of core modules and will enable single-binary mode. "+ | |
"Use '-modules' command line flag to get a list of available modules, and to see which modules are included in 'all'.") | |
f.Var(&c.Target, "target", "Comma-separated list of Cortex modules to load. "+ | |
"The alias 'all' can be used in the list to load a number of core modules and will enable single-binary mode. "+ | |
"Use '-modules' command line flag to get a list of available modules, and to see which modules are included in 'all'.") |
// Set the default module list to 'all' | ||
// Make linter happy | ||
c.Target.Set(All) //nolint:errcheck | ||
|
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.
// Set the default module list to 'all' | |
// Make linter happy | |
c.Target.Set(All) //nolint:errcheck | |
c.Target = []string{All} |
pkg/util/modules/modules_test.go
Outdated
svcs, err = mm.InitModuleServices("service_unknown") | ||
assert.Nil(t, svcs) | ||
assert.Error(t, err, fmt.Errorf("unrecognised module name: service_unknown")) | ||
// Test loading of the module second time (should be noop) |
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 should not be noop -- it should in fact create new services. Can we extend the test to verify that services from first and second invocation of mm.InitModuleServices("serviceC")
are different?
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, the noop part is left from the previous stateful ModuleManager. Fixed
…, update docs Signed-off-by: Igor Novgorodov <[email protected]>
Signed-off-by: Igor Novgorodov <[email protected]>
Integration test failed, but looking at the logs it looks like some other transient issue. |
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 have left some non-blocking nitpicky comments (mostly to minimize the diff), but LGTM. Thank you!
Signed-off-by: Igor Novgorodov <[email protected]>
Done mentioned fixes |
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.
Thank you very much!
Signed-off-by: Igor Novgorodov <[email protected]>
There's a conflict with newer PR #3287, I've merged current master and fixed. |
Looks like tests are unstable. But now it's something else:
|
Yes, this test is flaky. We need to fix it. |
Signed-off-by: Marco Pracucci <[email protected]>
Signed-off-by: Marco Pracucci <[email protected]>
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 did great! LGTM! Will merge as soon as the CI passes.
Signed-off-by: Marco Pracucci <[email protected]>
Add support for by explictely specifying a target in the servcies config. cortexproject/cortex#3275 Signed-off-by: Julien Pivotto <[email protected]>
Add support for by explictely specifying a target in the servcies config. cortexproject/cortex#3275 Signed-off-by: Julien Pivotto <[email protected]>
Add support for by explictely specifying a target in the servcies config. cortexproject/cortex#3275 Signed-off-by: Julien Pivotto <[email protected]>
Add support for by explictely specifying a target in the servcies config. cortexproject/cortex#3275 Signed-off-by: Julien Pivotto <[email protected]>
Add support for by explictely specifying a target in the servcies config. cortexproject/cortex#3275 Signed-off-by: Julien Pivotto <[email protected]>
* Update cortex and add support for multiple modules Add support for by explictely specifying a target in the servcies config. cortexproject/cortex#3275 Signed-off-by: Julien Pivotto <[email protected]>
Signed-off-by: Igor Novgorodov [email protected]
What this PR does:
Adds an ability to load a comma-separated list of modules instead of a single module or 'all'.
This should be backwards-compatible with the current behaviour.
The moduleManager is extended a bit to keep track of already loaded modules.
I don't really like having All as a module, but I'll leave it for now as-is to keep changes compact.
And single-binary detection depends on this in a couple of places.
Ideally we should just alias the word all to a predefined list of modules and load them like they were specified on the command line or in config file.
Which issue(s) this PR fixes:
Fixes #3272
Checklist
CHANGELOG.md
updated - the order of entries should be[CHANGE]
,[FEATURE]
,[ENHANCEMENT]
,[BUGFIX]