-
Notifications
You must be signed in to change notification settings - Fork 850
Design doc - Generalize Module Service #2542
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
Merged
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,77 @@ | ||
| --- | ||
| title: "Generalize Modules Service to make it extensible" | ||
| linkTitle: "Generalize Modules Service to make it extensible" | ||
| weight: 1 | ||
| slug: generalize-modules | ||
| --- | ||
|
|
||
| - Author: @annanay25 | ||
| - Reviewers: @jtlisi, @pstibrany, @cyriltovena, @pracucci | ||
| - Date: April 2020 | ||
| - Status: Accepted | ||
|
|
||
| ## Overview | ||
|
|
||
| Cortex uses modules to start and operate services with dependencies. Inter-service dependencies are specified in a map and passed to a module manager which ensures that they are initialised in the right order of dependencies. While this works really well, the implementation is tied in specifically to the Cortex struct and is not flexible for use with other projects like Loki, which also require similar forms of dependency management. | ||
|
|
||
| We would like to extend modules in cortex to a generic dependency management framework, that can be used by any project with no ties to cortex. | ||
|
|
||
| ## Specific goals | ||
|
|
||
| - Framework should allow for reusing cortex modules and allow us to: | ||
| - Add new modules | ||
| - Overwrite the implementation of a current module | ||
| - Manage dependencies | ||
| - Framework should allow for building an application from scratch using the `modules` package, with no dependencies on Cortex. For ex: Remove code from Loki that was copied from `pkg/cortex/cortex.go`. | ||
|
|
||
|
|
||
| ## Proposed Design | ||
|
|
||
| ### Modules package | ||
|
|
||
| To make the modules package extensible, we need to abstract away any Cortex specific details from the module manager. The proposed design is to: | ||
|
|
||
| - Make a new component `Manager`, which is envisioned to be a central manager for all modules of the application. It stores modules & dependencies, and will be housed under a new package `pkg/util/modules`. `Manager` has the following methods for interaction: | ||
| ``` | ||
| func (m *Manager) RegisterModule(name string, initFn func() (Service, error)) | ||
| func (m *Manager) AddDependency(name string, dependsOn... string) error | ||
| func (m *Manager) InitModuleServices(target string) (map[string]services.Service, error) | ||
| ``` | ||
|
|
||
| - Modules can be created by the application and registered with `modules.Manager` using `RegisterModule`. The parameters are: | ||
| - `name`: Name of the module | ||
| - `initFn`: A function that will be used to start the module. If it returns nil, and other modules depend on it, `InitModuleServices` will return an error. | ||
|
|
||
| - Dependencies between modules can be added using `AddDependency`. The parameters to the function are: | ||
| - `name`: Name of the module | ||
| - `dependsOn`: A variadic list of modules that the module depends on. | ||
|
|
||
| These need to be added before the call to `InitModuleServices`. | ||
|
|
||
| - The application can be initialized by running `initFn`'s of all the modules in the right order of dependencies by invoking `InitModuleServices` with the target module name. | ||
|
|
||
|
|
||
| ### Changes to `pkg/cortex`: | ||
annanay25 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| - `WrappedService` present in the current `module` design will be deprecated. All `initFn`'s will be wrapped into `WrappedService` by default. | ||
|
|
||
| - While the process of loading modules into `modules.Manager` should be remain as part of the `Cortex.New()` function, `InitModuleServices` should be part of `Cortex.Run()` and to enable this, `modules.Manager` would be made a member of the `Cortex` struct. | ||
annanay25 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
|
|
||
| ## Usage | ||
|
|
||
| Following these changes, the Modules package will be a generic dependency management framework that can be used by any project. | ||
|
|
||
| #### To use the modules framework: | ||
annanay25 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| - Import the `pkg/util/modules` package, and initialize a new instance of the `Manager` using `modules.NewManager()` | ||
| - Create components in the system that implement the services interface (present in `pkg/util/services`). | ||
| - Register each of these components as a module using `Manager.RegisterModule()` by passing name of the module and `initFn` for the module. | ||
| - To add dependencies between modules, use `Manager.AddDependency()` | ||
| - Once all modules are added into `modules.Manager`, initialize the application by calling `Manager.InitModuleServices()` which initializes modules in the right order of dependencies. | ||
|
|
||
|
|
||
| ## Future work | ||
|
|
||
| - Extend the module manager to allow specifying multiple targets as opposed to a single target name supported currently. | ||
| - Factor out `Run()` method to make it independent of Cortex. This will help reduce replicated code in the Loki project as well as help manage `modules.Manager` outside of the Cortex struct. | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.