From 0188af39a1a5013db388545a6d7c7bdbe566a4c1 Mon Sep 17 00:00:00 2001 From: Paul Holden Date: Wed, 6 Oct 2021 17:28:35 +0100 Subject: [PATCH] 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). --- lib/phpunit/classes/util.php | 3 +++ reportbuilder/classes/manager.php | 34 ++++++++++++++++++++++++------- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/lib/phpunit/classes/util.php b/lib/phpunit/classes/util.php index c7f318e14dc..4f8ee14e978 100644 --- a/lib/phpunit/classes/util.php +++ b/lib/phpunit/classes/util.php @@ -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')) { diff --git a/reportbuilder/classes/manager.php b/reportbuilder/classes/manager.php index 015cc3f948f..c46fe804272 100644 --- a/reportbuilder/classes/manager.php +++ b/reportbuilder/classes/manager.php @@ -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 = []; + } } /** -- 2.43.0