-
Improvement
-
Resolution: Won't Fix
-
Minor
-
None
-
4.5
-
None
I noted performance of serving user profile icons is not great especially when there are lots of icons displaying at once, so I wondered if it might be worth investigating the possibility to serve files in a different way:
- Do access checks while rendering the file link, rather than serving a file - this means we don't have to load session, or do a Moodle user login, when serving each file.
- The system uses a signature to confirm that fhe links are legit.
- There is no logging.
- The system uses a hook to serve the files.
- To ensure good performance I also changed the user fields API to load the file details as part of the existing query.
While this was a nice idea (and frankly I think actually serving files this way is way easier than using the pluginfile callback) the performance improvement doesn't seem all that great so I am not sure this is worthwhile.
On my local server (local Postgrs database, local Redis MUC) I did 10 requests from each one, alternately, in both cases with 'force login to view profile images' turned on so that it's the non-public kind of link.
Median times were 171ms for the 'fast' serving vs 197ms for the existing behaviour. I think the performance would be a bit more different with non-local database. The db readsa/writes are 2/0 for the fast one vs 5/1 for the existing, so it is less db effort.
As an example of how to use the new API, to get a URL it's like this:
$url = fast_file::get_url('local_mycomponent', 'myarea', '/file.jpg', $fileid, $contenthash);
|
And then you need a hook callback like this:
public static function grant_fast_file(\core_files\hook\grant_fast_file $hook) {
|
global $CFG;
|
|
// Allow everyone with a capability to download these files.
|
if ($hook->component === 'local_mycomponent' && $hook->area === 'myarea') {
|
if (has_capability('local/mycomponent:dostuff', \context_system::instance()) {
|
$hook->grant();
|
}
|
}
|
}
|
You can specify the file to serve (id, contenthash) either when getting the URL as shown here, which is good for perfomance because you can get them with a join as part of a query if getting files in bulk, or else for one-at-a-time files it's probably easier to do in the hook while granting it (the grant function takes those parameters or you can pass a stored_file object).
For security reasons i.e. to stop developers screwing up and granting the wrong file it would probably be good if fastfile.php checked some more of the parameters actually match the ones in the stored_file - i.e. this code isn't really finished...
- will help resolve
-
MDL-81430 Make pluginfile not need a sessionlock / readonly session
-
- Open
-