Skip to content
Browse files

Merge branch 'MDL-61102-master' of…

  • Loading branch information
David Monllao committed Apr 19, 2018
2 parents c805823 + 73fd566 commit 029944471027f0c4b0cf92220e207cf553eaa034
@@ -74,6 +74,11 @@ abstract class engine {
protected $pluginname = null;

* @var bool If true, should skip schema validity check when checking the search engine is ready
protected $skipschemacheck = false;

* Initialises the search engine configuration.
@@ -417,10 +422,38 @@ public function clear_query_error() {
* This should also check that the search engine configuration is ok.
* If the function $this->should_skip_schema_check() returns true, then this function may leave
* out time-consuming checks that the schema is valid. (This allows for improved performance on
* critical pages such as the main search form.)
* @return true|string Returns true if all good or an error string.
abstract function is_server_ready();

* Tells the search engine to skip any time-consuming checks that it might do as part of the
* is_server_ready function, and only carry out a basic check that it can contact the server.
* This setting is not remembered and applies only to the current request.
* @since Moodle 3.5
* @param bool $skip True to skip the checks, false to start checking again
public function skip_schema_check($skip = true) {
$this->skipschemacheck = $skip;

* For use by subclasses. The engine can call this inside is_server_ready to check whether it
* should skip time-consuming schema checks.
* @since Moodle 3.5
* @return bool True if schema checks should be skipped
protected function should_skip_schema_check() {
return $this->skipschemacheck;

* Adds a document to the search engine.
@@ -133,15 +133,30 @@ public function __construct($engine) {
$this->engine = $engine;

* @var int Record time of each successful schema check, but not more than once per 10 minutes.

* @var int Require a new schema check at least every 4 hours.

* Returns an initialised \core_search instance.
* While constructing the instance, checks on the search schema may be carried out. The $fast
* parameter provides a way to skip those checks on pages which are used frequently. It has
* no effect if an instance has already been constructed in this request.
* @see \core_search\engine::is_installed
* @see \core_search\engine::is_server_ready
* @param bool $fast Set to true when calling on a page that requires high performance
* @throws \core_search\engine_exception
* @return \core_search\manager
public static function instance() {
public static function instance($fast = false) {
global $CFG;

// One per request, this should be purged during testing.
@@ -157,6 +172,17 @@ public static function instance() {
throw new \core_search\engine_exception('enginenotfound', 'search', '', $CFG->searchengine);

// Get time now and at last schema check.
$now = (int)self::get_current_time();
$lastschemacheck = get_config($engine->get_plugin_name(), 'lastschemacheck');

// On pages where performance matters, tell the engine to skip schema checks.
$skipcheck = false;
if ($fast && $now < $lastschemacheck + self::SCHEMA_CHECK_REQUIRED_EVERY) {
$skipcheck = true;

if (!$engine->is_installed()) {
throw new \core_search\engine_exception('enginenotinstalled', 'search', '', $CFG->searchengine);
@@ -165,11 +191,19 @@ public static function instance() {
if ($serverstatus !== true) {
// Skip this error in Behat when faking seach results.
if (!defined('BEHAT_SITE_RUNNING') || !get_config('core_search', 'behat_fakeresult')) {
// Clear the record of successful schema checks since it might have failed.
unset_config('lastschemacheck', $engine->get_plugin_name());
// Error message with no details as this is an exception that any user may find if the server crashes.
throw new \core_search\engine_exception('engineserverstatus', 'search');

// If we did a successful schema check, record this, but not more than once per 10 minutes
// (to avoid updating the config db table/cache too often in case it gets called frequently).
if (!$skipcheck && $now >= $lastschemacheck + self::SCHEMA_CHECK_TRACKING_DELAY) {
set_config('lastschemacheck', $now, $engine->get_plugin_name());

static::$instance = new \core_search\manager($engine);
return static::$instance;
@@ -70,8 +70,6 @@ function definition() {
$mform->addElement('text', 'title', get_string('title', 'search'));
$mform->setType('title', PARAM_TEXT);

$search = \core_search\manager::instance();

$searchareas = \core_search\manager::get_search_areas_list(true);
$areanames = array();
foreach ($searchareas as $areaid => $searcharea) {
@@ -1137,6 +1137,12 @@ public function is_server_ready() {
return $configured;

// As part of the above we have already checked that we can contact the server. For pages
// where performance is important, we skip doing a full schema check as well.
if ($this->should_skip_schema_check()) {
return true;

// Update schema if required/possible.
$schemalatest = $this->check_latest_schema();
if ($schemalatest !== true) {
@@ -54,7 +54,7 @@

$search = \core_search\manager::instance();
$search = \core_search\manager::instance(true);

// Set up custom data for form.
$customdata = ['searchengine' => $search->get_engine()->get_plugin_name()];
@@ -13,16 +13,13 @@ information provided here is intended especially for developers.
options (other than 'relevance' which is default). If there is more than one order then a choice
will be shown to users. (This is an optional feature, existing search engine plugins do not need
to be modified in order to continue working.)

* Module search areas that wish to support group filtering should set the new optional search
document field groupid (note: to remain compatible with earlier versions, do this inside an if
statement so that it only happens on 3.4+) and return true to the supports_group_restriction
function. See documentation in \core_search\base_mod class and example in \mod_forum\search\post.

* When a search engine supports group filtering, the \core_search\manager::search function now
accepts the optional 'groupids' parameter in its $data input. This parameter is an array of one
or more group IDs. If supplied, only results from those groups will be returned.

* Search engine plugins will need to be be modified if they wish to support group filtering.
(Search engines should continue to work unmodified, but will not then support group filtering.)
The modification steps are:
@@ -33,6 +30,11 @@ information provided here is intended especially for developers.
search results to specific groups) and the modified meaning of the second parameter,
$accessinfo (to automatically restrict search results users cannot access due to groups).
See implementation in Solr search engine.
* Search engine plugins can optionally use a new $this->should_skip_schema_check() function to
decide when to skip slow schema checking inside the is_server_ready function, improving user
performance on the search page. The Solr plugin implements this.
* API function \core_search\manager::instance() now includes a $fast parameter to skip schema
checks (as above).

=== 3.4 ===

0 comments on commit 0299444

Please sign in to comment.