Skip to content

Conversation

@come-nc
Copy link
Contributor

@come-nc come-nc commented May 13, 2025

PR for #54155

Summary

  1. Use symfony tools to compile all routes
  2. Cache that in a local cache
  3. Load from cache instead of parsing routes on each request
  4. Do the same for the generator postponed to follow-up if needed
  5. Check whether cache reset is needed in some situations

Checklist

@come-nc come-nc self-assigned this May 13, 2025
@come-nc come-nc added the 2. developing Work in progress label May 13, 2025
@come-nc come-nc added this to the Nextcloud 32 milestone May 13, 2025
@come-nc
Copy link
Contributor Author

come-nc commented May 13, 2025

Notes:

  1. Big win on core routes like login. ~100ms saved
  2. Smaller win on apps/ routes, ~20ms saved
  3. On apps/ routes, 2MB more memory usage, could be avoided by caching by app, but then we lose part of the time improvement
  4. We lose routes pointing to a closure, because that cannot be serialized. This is not used a lot and mainly used for including files throuh IRoute::actionInclude. We should deprecate that and add a work-around, but I’m short on ideas, we might have to load the routes again for these ones (if we cache in which file they are it might not be that expensive).

@come-nc come-nc requested a review from provokateurin May 14, 2025 09:55
@come-nc come-nc force-pushed the feat/cache-routes branch from abc0a2e to 99b3377 Compare May 14, 2025 20:58
@come-nc
Copy link
Contributor Author

come-nc commented May 16, 2025

  1. Do the same for the generator

I am not sure if it makes sense for generations, as that’s used less often I suppose?
We could still implement in a follow-up if needed.

  1. Check whether cache reset is needed in some situations

Cache has a prefix using applications versions, so we’re fine on this point.

@come-nc come-nc requested a review from ChristophWurst May 16, 2025 15:25
@come-nc come-nc added 3. to review Waiting for reviews and removed 2. developing Work in progress labels May 16, 2025
@come-nc
Copy link
Contributor Author

come-nc commented May 16, 2025

Ready for reviews. Should not be merged yet so that we can compare with master performances more easily.

Copy link
Member

@provokateurin provokateurin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reviewed commit-by-commit so it is a bit messy because some commits should have been squashed to make sense 🙈

@come-nc
Copy link
Contributor Author

come-nc commented May 19, 2025

@provokateurin see https://github.com/nextcloud/server/blob/master/lib/private/Server.php#L705-L713

@come-nc come-nc force-pushed the feat/cache-routes branch from ed23cd2 to fb4fe2d Compare May 20, 2025 16:08
Copy link
Member

@ChristophWurst ChristophWurst left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Didn't test

@come-nc come-nc marked this pull request as ready for review June 2, 2025 14:20
@come-nc come-nc requested a review from a team as a code owner June 2, 2025 14:20
@come-nc come-nc requested review from artonge, skjnldsv and sorbaugh and removed request for a team June 2, 2025 14:20
@come-nc come-nc force-pushed the feat/cache-routes branch from fb4fe2d to c847510 Compare June 2, 2025 14:45
@come-nc
Copy link
Contributor Author

come-nc commented Jun 2, 2025

Failing CI is related.

Current theory:

  • In some cases after enabling an application its routes are missing from cached routes
  • This is supposed to be avoided by the cache prefix based on application versions, but that does not take into account disabled/enabled applications, only the version in DB

I will try to use only enabled applications for the cache prefix.

@come-nc come-nc force-pushed the feat/cache-routes branch from 83d96b3 to 4105837 Compare June 2, 2025 16:37
@come-nc come-nc force-pushed the feat/cache-routes branch 2 times, most recently from 3ced68c to 69a04e5 Compare June 3, 2025 14:44
@come-nc come-nc force-pushed the feat/cache-routes branch from c72cb36 to 5565eda Compare June 5, 2025 12:32
come-nc added 10 commits June 5, 2025 17:58
This is not ideal because serializing the routecollection is not easy.
It seems Symfony has its own way of doing things by dumping routes to a
 PHP file, maybe that would be better, but it would mean pulling a new
 symfony dependency and maybe refactor our Router.

Signed-off-by: Côme Chilliet <[email protected]>
This makes sure the cached routes are updated after enabling a
 previously disabled application

Signed-off-by: Côme Chilliet <[email protected]>
@come-nc come-nc force-pushed the feat/cache-routes branch from 5565eda to 89f51a8 Compare June 5, 2025 15:59
come-nc added 2 commits June 5, 2025 18:03
Avoids a corner case issue if one application was disabled and another
 one enabled with the same version, just to be safe.

Signed-off-by: Côme Chilliet <[email protected]>
This avoids cache issues if some apps are only enabled for some groups,
 by loading the routes from all apps enabled for anyone, not only the
 current user.
If the queried application is disabled for the current user based on
 groups, the middleware will cancel the query.

Signed-off-by: Côme Chilliet <[email protected]>
@come-nc come-nc added the pending documentation This pull request needs an associated documentation update label Jun 5, 2025
Signed-off-by: Côme Chilliet <[email protected]>
@come-nc come-nc enabled auto-merge June 5, 2025 16:42
@skjnldsv skjnldsv disabled auto-merge June 5, 2025 18:05
@skjnldsv skjnldsv merged commit b8b229c into master Jun 5, 2025
205 of 207 checks passed
@skjnldsv skjnldsv deleted the feat/cache-routes branch June 5, 2025 18:05
if (!$cachedRoutes) {
parent::loadRoutes();
$cachedRoutes = $this->serializeRouteCollection($this->root);
$this->cache->set($key, $cachedRoutes, 3600);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The key does not include any version number, so this probably means its always cached also on updates?
Because then there is no way to flush on update if the routes have changed, no?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, the cache have a global prefix with all apps version numbers, see

$prefixClosure = function () use ($logQuery, $serverVersion): ?string {

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

3. to review Waiting for reviews pending documentation This pull request needs an associated documentation update performance 🚀

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants