apigee-edge-drupal icon indicating copy to clipboard operation
apigee-edge-drupal copied to clipboard

Improve performance of app listing pages

Open mxr576 opened this issue 2 years ago • 3 comments

Description

We were debugging performance issues related to app listing pages for an unnamed Apigee customer. As part of that process, we enabled the Apigee Edge Debug module and inspected outgoing API calls.

We realized that developer and team app listing pages send as many API calls as many apps they list for different reasons, which basically leads to the ORM's infamous N+1 problem,

So for a start, we do not and cannot permanently cache app credentials... therefore we had/have tricky solutions in the code to fetch them on demand from the API gateway when needed.

Problem 1: When display modes are in use

When display modes are configured to be used for display apps on admin/config/apigee-edge/app-settings/developer-apps/display-settings or on /admin/config/apigee-edge/app-settings/team-apps/display-settings then the root cause of the problem is the the selected display mode ("Default" by default) also used for rendering entries in the list - even if a minimal subset of the fields are rendered on the list - and the Default display mode displays the "Credentials" field that triggered on-demand fetching on API key(s) in an app.

This can be reproduced by setting the display mode and refreshing the app listing page of the user and checking logs generated by the debug module. The number of API calls to /apps/[uuid] endpoint with an Apigee Edge instance connection should raise your concerns and that is created by $entity->getCredentials() in apigee_edge_entity_view() here.

When Credentials field is removed from the display mode the same problem arises, also originating in apigee_edge_entity_view() but triggered by the $app_warnings_checker->getWarnings($entity) here.

Proposed solution

Entity list builder MUST use a dedicated view mode for listing apps in the list or should not use any. Most probably the refactoring should start in \Drupal\apigee_edge\Entity\ListBuilder\EdgeEntityListBuilder::render() that involves \Drupal\apigee_edge\Entity\ListBuilder\EdgeEntityListBuilder::getDisplaySettings() and returns the same display mode as it is used on viewing a single app entity.

Regarding the issue with the Warnings field... No better idea than this is inevitable... and probably on lazy building the list with BigPipe can help or fetching and displaying the information from JS via API calls for every list item one by one.

Problem 2: When display modes are disabled

The same issue arises but the call stack is pointed to \Drupal\apigee_edge\Entity\ListBuilder\AppListBuilder::buildWarningRow() that eventually calls \Drupal\apigee_edge\Entity\App::getCredentials() for every entity on the list one by one.

Proposed solution

... Bigpipe and lazy building or fetch and display from JS via API calls...

Apigee Info

N/A

Screenshots

If applicable, add screenshots to help explain your problem.

Notes

Version Info

Latest 2.x/3.x no changes in this regard in any supported versions.

mxr576 avatar Sep 27 '23 15:09 mxr576

So I made a POC for solving Problem 2 with Bigpipe and it seems to be working. It changes the render array since now what was a '#theme' => 'status_messages', becomes a '#lazy_builder' => '..' which can break Apigee UI customization.

Peek 2023-09-28 12-35.webm

mxr576 avatar Sep 28 '23 10:09 mxr576

Hi, any update for a fix please ?

ke-wq avatar Sep 12 '24 14:09 ke-wq

Hi, any update for a fix please ?

ke-wq avatar Oct 07 '24 08:10 ke-wq