Refactor environment's dashboard backend
Summary
The Environments Dashboard - -/operations/environments
- has been developed out of the Operations dashboard, and there are a number of technical improvements that should be made. The issues are:
- non-standard controller action names (
OperationsController#environments
andOperationsController#environments_list
) - complex code which retrieves all the data in a single call
- difficulties in extending the existing code due to tight coupling elsewhere
- growing performance issues due to the single call
- array-based pagination
When Environments Dashboard is loaded, there are 2 calls to the backend:
Initial page load
When the page is first loaded via GET https://gitlab.com/-/operations/environments
, it:
- accesses OperationsController#environments
- renders
ee/app/views/operations/environments.html.haml
- loads a VueJS component
#js-environments{ data: environments_data }
This component simply renders the basic page and passes environments_data
:, which is a helper ee/app/helpers/ee/operations_helper.rb
and just passes on the paths from the backend.
'add-path' => add_operations_project_path,
'list-path' => operations_environments_list_path,
etc
Data load
The Vue component (attached to #js-environments
) then loads all of the backend data needed to populate the environments dashboard. This is done via this sequence:
OperationsController#environments_list - `GET https://gitlab.com/-/operations/environments_list`
Dashboard::Environments::ListService
Dashboard::Projects::ListService
ProjectsFinder
The Dashboard::Environments::ListService
uses this preloader code:
ActiveRecord::Associations::Preloader.new.preload(projects, [
:route,
environments_for_dashboard: [
last_visible_pipeline: [
:user,
project: [:route, :group, :project_feature, namespace: :route]
],
last_visible_deployment: [
deployable: [
:metadata,
:pipeline,
project: [:project_feature, :group, :route, namespace: :route]
],
project: [:route, namespace: :route]
],
project: [:project_feature, :group, namespace: :route]
],
namespace: [:route, :owner]
])
Related work
- Project environment dashboard to view environments and deployment statuses
- Environments Dashboard Limits and Optimization
- Performance analysis work in
Expand supported number projects on Environments Dashboard by adding pagination
Improvements
- Move the Environments endpoints into their own REST-complaint controller, or better still move them to GraphQL. For example they could become
EnvironmentDashboardController#index
andEnvironmentDashboardDataController#index
. - Simplify the code in
Dashboard::Projects::ListService
and consider if there are better-fit alternatives to using theProjectsFinder
, for example a new finder that combines the Projects and Environments data directly. - Consider breaking the data load into 2 pieces
- render the projects and possibly environments in the first load
- call additional endpoint(s) to populate the detail
- database-level pagination for projects + environments instead of array pagination (should be OK to bring both back together as the first call).
Operations Dashboard
- It would probably be good to refactor the Operations Dashboard at the same time, producing decoupled shared components.
- The Operations Dashboard uses shared code but does not pass pagination so there is implied knowledge in this test
Risks
- Front-end impact is unknown, and needs investigation.
- Impact on Operations Dashboard
Involved components
- OperationsController
- Dashboard::Environments::ListService
- (To be defined) Frontend components.
Optional: Intended side effects
- performance
- simplify code and allow for future enhancements
- reduce dependencies with the Operations Dashboard
Optional: Missing test coverage
Existing tests look at a small number (usually 1) project + environment, this should be scaled up, perhaps using fixtures or let_it_be
to assist with test performance.