MDL-72588 reportbuilder: performance improvement to report loader.

Statically cache list of loaded reports during request lifecycle,
this ensures that computationally heavy initialisation routines
in system reports are only executed once (e.g. the access tab).
This commit is contained in:
Paul Holden 2021-10-06 17:28:35 +01:00 committed by David Matamoros
parent 42481d5c43
commit 0188af39a1
2 changed files with 30 additions and 7 deletions

View File

@ -255,6 +255,9 @@ class phpunit_util extends testing_util {
if (class_exists('\core_course\customfield\course_handler')) {
\core_course\customfield\course_handler::reset_caches();
}
if (class_exists('\core_reportbuilder\manager')) {
\core_reportbuilder\manager::reset_caches();
}
// Clear static cache within restore.
if (class_exists('restore_section_structure_step')) {

View File

@ -33,9 +33,15 @@ use core_reportbuilder\local\report\base;
*/
class manager {
/** @var base $instances */
private static $instances = [];
/**
* Return an instance of a report class from the given report persistent
*
* We statically cache the list of loaded reports during request lifecycle, to allow this method to be called
* repeatedly without potential performance problems initialising the same report multiple times
*
* @param report $report
* @param array $parameters
* @return base
@ -43,16 +49,30 @@ class manager {
* @throws source_unavailable_exception
*/
public static function get_report_from_persistent(report $report, array $parameters = []): base {
$source = $report->get('source');
$instancekey = $report->get('id');
if (!array_key_exists($instancekey, static::$instances)) {
$source = $report->get('source');
// Throw exception for invalid or unavailable report source.
if (!self::report_source_exists($source)) {
throw new source_invalid_exception($source);
} else if (!self::report_source_available($source)) {
throw new source_unavailable_exception($source);
// Throw exception for invalid or unavailable report source.
if (!self::report_source_exists($source)) {
throw new source_invalid_exception($source);
} else if (!self::report_source_available($source)) {
throw new source_unavailable_exception($source);
}
static::$instances[$instancekey] = new $source($report, $parameters);
}
return new $source($report, $parameters);
return static::$instances[$instancekey];
}
/**
* Run reset code after unit tests to reset the instance cache
*/
public static function reset_caches(): void {
if (PHPUNIT_TEST) {
static::$instances = [];
}
}
/**