perf(files): Move cache garbage collection to a background job#52980
perf(files): Move cache garbage collection to a background job#52980provokateurin wants to merge 2 commits intomasterfrom
Conversation
The test failure looks really suspicious, but I don't see how it could be related 🤔 |
b991c0e to
432611a
Compare
I can reliably reproduce it locally and on master it is just fine. |
|
As far as I can tell the FS isn't correctly setup any more, as WebDAV currently relies on the way this file cache garbage collection already sets up the FS (really bad I know). I think this is similar to how previous attempts went, but I'll give it another shot. |
|
So the files webdav plugin needs to call the setup manager? |
| $this->userManager->callForSeenUsers(function (IUser $user) use ($cache): void { | ||
| $userId = $user->getUID(); | ||
|
|
||
| try { | ||
| $cache->gc($userId); | ||
| } catch (Exception $e) { | ||
| $this->logger->warning('Exception when running cache gc.', [ | ||
| 'app' => 'files', | ||
| 'user' => $userId, | ||
| 'exception' => $e, | ||
| ]); | ||
| } | ||
| }); |
There was a problem hiding this comment.
Will this scale correctly if there are millions of users? I would at least add an offset, like in trashbin : so the job is able to pick up from the latest user.
server/apps/files_trashbin/lib/BackgroundJob/ExpireTrash.php
Lines 32 to 71 in fa2ed6b
Note that some work is also ongoing to support parallel run of the job, as it is taking too long to go through all the users with only one instance of the job: #52825
You could use a similar approach as for trashbin and versions where a job is scheduled for a user when needed. But I also understand that the gc call was run on every request, so this might not be practical.
server/apps/files_trashbin/lib/Trashbin.php
Lines 854 to 863 in fa2ed6b
There was a problem hiding this comment.
You are right that this might not be very performant.
It might not be so bad in reality, as the chunking v1 should not be used by any client anymore and thus the GC operation should be quite fast.
So it's mostly setting up the FS that takes all the time.
What do you think?
There was a problem hiding this comment.
I would go directly to what I did for the trashbin. But if you think parallel job won't be needed, I would at least add the offset logic, as for sure, it will be needed for large instances.
Thinking about it, can we come up with a better way to know if gc is needed for a user? Not sure how those files are denoted, maybe an SQL query would do the job.
There was a problem hiding this comment.
True, maybe we can just get a list of users that have at least one file in the cache, then it should be way cheaper.
I think so yes, but so far I have not found the right place where this needs to happen 😅 |
432611a to
b39e743
Compare
|
I think I managed to initialize the FS in the right place, but unfortunately had to hijack the auth for it as there is no way to correctly run code in beforeMethod but after the auth is done. |
Signed-off-by: provokateurin <[email protected]>
Signed-off-by: provokateurin <[email protected]>
b39e743 to
daf3659
Compare
|
The more I look into this the more it seems like this code is actually dead. Line 586 in c879bab I also just removed this and run a bunch of phpunit tests and there were no failures caused by it. |
Summary
Unlike previous attempts I did not try to change much of the logic, just stopped calling the GC in each request from base.php and moved that to a background job.
This brings down the base query count when calling /index.php/204 with basic auth credentials via curl from 22 to 14, because the FS doesn't need to be setup anymore before the controller is even called.
Checklist