Split application into functional parts to ensure that only needed code is loaded with all dependencies
<!-- triage-serverless v3 PLEASE DO NOT REMOVE THIS SECTION -->
*This page may contain information related to upcoming products, features and functionality.
It is important to note that the information presented is for informational purposes only, so please do not rely on the information for purchasing or planning purposes.
Just like with all projects, the items mentioned on the page are subject to change or delay, and the development, release, and timing of any products, features, or functionality remain at the sole discretion of GitLab Inc.*
<!-- triage-serverless v3 PLEASE DO NOT REMOVE THIS SECTION -->
Currently we run GitLab in multiple contexts:
- Web API
- Web ActionCable
- Web Controllers
- Sidekiq (and various different jobs)
- Sidekiq Cluster
Probably this kind of split is hard, but it appears that we could provide a better code architecture that
would allow to split on this major line:
- Web: API/ActionCable/Controllers
- Sidekiq/Cluster
For example:
- Web: likely would not require Sidekiq Workers and all dependent services
- Sidekiq: likely would not require any API/ActionCable/Controllers/GraphQL and app dependencies to run
Material:
- Blueprint: https://docs.gitlab.com/ee/architecture/blueprints/composable_codebase_using_rails_engines/ (MR: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/50842)
- Discussion (2021/12/09): https://www.youtube.com/watch?v=omn42WO6Osg ([agenda](https://docs.google.com/document/d/10XLemtUYRjucRdT9OnPAPJTI8-RGAepmBpb7G1CN0Io/edit#))
## Pros & Cons
### Pros
- Significantly lower memory usage - For PoC we saved 264.13 MB RSS (30%), or ~137MB savings on the whole fleet
- Significantly shorter application load time on Sidekiq `start-up` event - For Poc - 23.51s (~52%)
- Significantly improved responsiveness of Sidekiq service due to much shorter GC cycles - For PoC - 20% shorter GC cycle
- Significantly easier testing of a portion of the application, ex. changing web_engines/ does require re-running test only for this application layer
- We retained a monolithic architecture of the codebase but we shared database, application models and common libs
- Expected significant saving from the infrastructure side (based on Memory and CPU optimizations)
- Ability to comfortably run on constrained environments by reducing application footprint
- Clearly defined layers allow you to understand where your code will be executed and what are expectations of its execution
### Cons:
- It is harder to implement GraphQL subscriptions as in the case of Sidekiq as we need another way to pass subscriptions
- api_v4 paths can be used in some services that are used by Sidekiq (for example api_v4_projects_path)
url_helpers paths are used in models and services, that could be used by Sidekiq (for example Gitlab::Routing.url_helpers.project_pipelines_path is used by ExpirePipelineCacheService in ExpirePipelineCacheWorker)
- Unnatural non-standard structure of Rails application. Rails engines keep the same structure, but our main application is now containing:
> - engines/
> - gitlab-web
> - app
> - controllers
> - models
> - config
> - lib
> - spec
> - gitlab-core
> - ...
## Impact
### Impact on Self-managed
- Comfortably run on constrained environments by reducing application footprint
- Increased development productivity
- Application loading time is faster
- easier testing of a portion of application
- We can selectively load components on application start (Controlled with ENV variables or config)
### Impact on SaaS/Gitlab.com
- We discussed impact in [Better understand Composable codebase improvements impact on Gitlab.com](https://gitlab.com/gitlab-org/gitlab/-/issues/351553)
- Improved responsiveness of Sidekiq service due to much shorter GC cycles
- Saving cost of infrastructure (TBD - estimated 137GB of memory across the fleet and CPU savings for Sidekiq)
- Easier testing ex. changing `web_engines/` does require re-running the CI test job only for this application layer
### Impact on Developers
- Clearly defined layers allow you to understand where your code will be executed and what are expectations of its execution
- Increased development productivity
- Application loading time is faster
- easier testing of a portion of application
- New folder structure could be confusing for new people
### Impact on our customers
- Web Puma nodes in PoC were not affected much, but we will eventually remove Sidekiq code and its dependencies.
- API Nodes running Puma could also be more responsive, which will reduce memory and CPU pressure, and improve the responsiveness of our API.
epic