Skip to content

Commit

Permalink
MDL-39459 cache: mode included in stats output
Browse files Browse the repository at this point in the history
The cache store mode is now included in the performance stats
printed at the bottom of the page.
It is represented as either [a] [s] or [r] and a title is used
to actually state the mode.
  • Loading branch information
Sam Hemelryk authored and samhemelryk committed Feb 3, 2015
1 parent 4c27f52 commit 7fa57e0
Show file tree
Hide file tree
Showing 6 changed files with 130 additions and 62 deletions.
75 changes: 58 additions & 17 deletions cache/classes/helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -346,68 +346,109 @@ public static function purge_by_event($event) {
/**
* Ensure that the stats array is ready to collect information for the given store and definition.
* @param string $store
* @param string $definition
* @param string $definition A string that identifies the definition.
* @param int $mode One of cache_store::MODE_*. Since 2.9.
*/
protected static function ensure_ready_for_stats($store, $definition) {
protected static function ensure_ready_for_stats($store, $definition, $mode = cache_store::MODE_APPLICATION) {
// This function is performance-sensitive, so exit as quickly as possible
// if we do not need to do anything.
if (isset(self::$stats[$definition][$store])) {
return;
}
if (!array_key_exists($definition, self::$stats)) {
self::$stats[$definition] = array(
$store => array(
'hits' => 0,
'misses' => 0,
'sets' => 0,
'mode' => $mode,
'stores' => array(
$store => array(
'hits' => 0,
'misses' => 0,
'sets' => 0,
)
)
);
} else if (!array_key_exists($store, self::$stats[$definition])) {
self::$stats[$definition][$store] = array(
self::$stats[$definition]['stores'][$store] = array(
'hits' => 0,
'misses' => 0,
'sets' => 0,
);
}
}

/**
* Returns a string to describe the definition.
*
* This method supports the definition as a string due to legacy requirements.
* It is backwards compatible when a string is passed but is not accurate.
*
* @since 2.9
* @param cache_definition|string $definition
* @return string
*/
protected static function get_definition_stat_id_and_mode($definition) {
if (!($definition instanceof cache_definition)) {
// All core calls to this method have been updated, this is the legacy state.
// We'll use application as the default as that is the most common, really this is not accurate of course but
// at this point we can only guess and as it only affects calls to cache stat outside of core (of which there should
// be none) I think that is fine.
debugging('Please update you cache stat calls to pass the definition rather than just its ID.', DEBUG_DEVELOPER);
return array((string)$definition, cache_store::MODE_APPLICATION);
}
return array($definition->get_id(), $definition->get_mode());
}

/**
* Record a cache hit in the stats for the given store and definition.
*
* In Moodle 2.9 the $definition argument changed from accepting only a string to accepting a string or a
* cache_definition instance. It is preferable to pass a cache definition instance.
*
* @internal
* @param string $store
* @param string $definition
* @param cache_definition $store
* @param cache_definition $definition You used to be able to pass a string here, however that is deprecated please pass the
* actual cache_definition object now.
* @param int $hits The number of hits to record (by default 1)
*/
public static function record_cache_hit($store, $definition, $hits = 1) {
self::ensure_ready_for_stats($store, $definition);
self::$stats[$definition][$store]['hits'] += $hits;
list($definitionstr, $mode) = self::get_definition_stat_id_and_mode($definition);
self::ensure_ready_for_stats($store, $definitionstr, $mode);
self::$stats[$definitionstr]['stores'][$store]['hits'] += $hits;
}

/**
* Record a cache miss in the stats for the given store and definition.
*
* In Moodle 2.9 the $definition argument changed from accepting only a string to accepting a string or a
* cache_definition instance. It is preferable to pass a cache definition instance.
*
* @internal
* @param string $store
* @param string $definition
* @param cache_definition $definition You used to be able to pass a string here, however that is deprecated please pass the
* actual cache_definition object now.
* @param int $misses The number of misses to record (by default 1)
*/
public static function record_cache_miss($store, $definition, $misses = 1) {
self::ensure_ready_for_stats($store, $definition);
self::$stats[$definition][$store]['misses'] += $misses;
list($definitionstr, $mode) = self::get_definition_stat_id_and_mode($definition);
self::ensure_ready_for_stats($store, $definitionstr, $mode);
self::$stats[$definitionstr]['stores'][$store]['misses'] += $misses;
}

/**
* Record a cache set in the stats for the given store and definition.
*
* In Moodle 2.9 the $definition argument changed from accepting only a string to accepting a string or a
* cache_definition instance. It is preferable to pass a cache definition instance.
*
* @internal
* @param string $store
* @param string $definition
* @param cache_definition $definition You used to be able to pass a string here, however that is deprecated please pass the
* actual cache_definition object now.
* @param int $sets The number of sets to record (by default 1)
*/
public static function record_cache_set($store, $definition, $sets = 1) {
self::ensure_ready_for_stats($store, $definition);
self::$stats[$definition][$store]['sets'] += $sets;
list($definitionstr, $mode) = self::get_definition_stat_id_and_mode($definition);
self::ensure_ready_for_stats($store, $definitionstr, $mode);
self::$stats[$definitionstr]['stores'][$store]['sets'] += $sets;
}

/**
Expand Down
28 changes: 14 additions & 14 deletions cache/classes/loaders.php
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ public function get($key, $strictness = IGNORE_MISSING) {
$setaftervalidation = false;
if ($result === false) {
if ($this->perfdebug) {
cache_helper::record_cache_miss($this->storetype, $this->definition->get_id());
cache_helper::record_cache_miss($this->storetype, $this->definition);
}
if ($this->loader !== false) {
// We must pass the original (unparsed) key to the next loader in the chain.
Expand All @@ -329,7 +329,7 @@ public function get($key, $strictness = IGNORE_MISSING) {
}
$setaftervalidation = ($result !== false);
} else if ($this->perfdebug) {
cache_helper::record_cache_hit($this->storetype, $this->definition->get_id());
cache_helper::record_cache_hit($this->storetype, $this->definition);
}
// 5. Validate strictness.
if ($strictness === MUST_EXIST && $result === false) {
Expand Down Expand Up @@ -473,8 +473,8 @@ public function get_many(array $keys, $strictness = IGNORE_MISSING) {
$hits++;
}
}
cache_helper::record_cache_hit($this->storetype, $this->definition->get_id(), $hits);
cache_helper::record_cache_miss($this->storetype, $this->definition->get_id(), $misses);
cache_helper::record_cache_hit($this->storetype, $this->definition, $hits);
cache_helper::record_cache_miss($this->storetype, $this->definition, $misses);
}

// Return the result. Phew!
Expand All @@ -500,7 +500,7 @@ public function get_many(array $keys, $strictness = IGNORE_MISSING) {
*/
public function set($key, $data) {
if ($this->perfdebug) {
cache_helper::record_cache_set($this->storetype, $this->definition->get_id());
cache_helper::record_cache_set($this->storetype, $this->definition);
}
if ($this->loader !== false) {
// We have a loader available set it there as well.
Expand Down Expand Up @@ -649,7 +649,7 @@ public function set_many(array $keyvaluearray) {
}
$successfullyset = $this->store->set_many($data);
if ($this->perfdebug && $successfullyset) {
cache_helper::record_cache_set($this->storetype, $this->definition->get_id(), $successfullyset);
cache_helper::record_cache_set($this->storetype, $this->definition, $successfullyset);
}
return $successfullyset;
}
Expand Down Expand Up @@ -1039,7 +1039,7 @@ protected function static_acceleration_get($key) {
}
if ($result) {
if ($this->perfdebug) {
cache_helper::record_cache_hit('** static acceleration **', $this->definition->get_id());
cache_helper::record_cache_hit('** static acceleration **', $this->definition);
}
if ($this->staticaccelerationsize > 1 && $this->staticaccelerationcount > 1) {
// Check to see if this is the last item on the static acceleration keys array.
Expand All @@ -1053,7 +1053,7 @@ protected function static_acceleration_get($key) {
return $result;
} else {
if ($this->perfdebug) {
cache_helper::record_cache_miss('** static acceleration **', $this->definition->get_id());
cache_helper::record_cache_miss('** static acceleration **', $this->definition);
}
return false;
}
Expand Down Expand Up @@ -1779,7 +1779,7 @@ public function get($key, $strictness = IGNORE_MISSING) {
// 4. Load if from the loader/datasource if we don't already have it.
if ($result === false) {
if ($this->perfdebug) {
cache_helper::record_cache_miss($this->storetype, $this->get_definition()->get_id());
cache_helper::record_cache_miss($this->storetype, $this->get_definition());
}
if ($this->get_loader() !== false) {
// We must pass the original (unparsed) key to the next loader in the chain.
Expand All @@ -1794,7 +1794,7 @@ public function get($key, $strictness = IGNORE_MISSING) {
$this->set($key, $result);
}
} else if ($this->perfdebug) {
cache_helper::record_cache_hit($this->storetype, $this->get_definition()->get_id());
cache_helper::record_cache_hit($this->storetype, $this->get_definition());
}
// 5. Validate strictness.
if ($strictness === MUST_EXIST && $result === false) {
Expand Down Expand Up @@ -1838,7 +1838,7 @@ public function set($key, $data) {
$loader->set($key, $data);
}
if ($this->perfdebug) {
cache_helper::record_cache_set($this->storetype, $this->get_definition()->get_id());
cache_helper::record_cache_set($this->storetype, $this->get_definition());
}
if (is_object($data) && $data instanceof cacheable_object) {
$data = new cache_cached_object($data);
Expand Down Expand Up @@ -1962,8 +1962,8 @@ public function get_many(array $keys, $strictness = IGNORE_MISSING) {
$hits++;
}
}
cache_helper::record_cache_hit($this->storetype, $this->get_definition()->get_id(), $hits);
cache_helper::record_cache_miss($this->storetype, $this->get_definition()->get_id(), $misses);
cache_helper::record_cache_hit($this->storetype, $this->get_definition(), $hits);
cache_helper::record_cache_miss($this->storetype, $this->get_definition(), $misses);
}
return $return;

Expand Down Expand Up @@ -2040,7 +2040,7 @@ public function set_many(array $keyvaluearray) {
}
$successfullyset = $this->get_store()->set_many($data);
if ($this->perfdebug && $successfullyset) {
cache_helper::record_cache_set($this->storetype, $definitionid, $successfullyset);
cache_helper::record_cache_set($this->storetype, $this->get_definition(), $successfullyset);
}
return $successfullyset;
}
Expand Down
1 change: 1 addition & 0 deletions cache/upgrade.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Information provided here is intended especially for developers.
- cache::make Argument 4 (final arg) is now unused.
* cache_config_phpunittest has been renamed to cache_config_testing
* New method cache_store::ready_to_be_used_for_testing() that returns true|false if the store is suitable and ready for use as the primary store during unit and acceptance tests.
* cache_helper::get_stats structure we changed to include the cache mode.

=== 2.7 ===
* cache_store::is_ready is no longer abstract, calling cache_store::are_requirements_met by default.
Expand Down
22 changes: 18 additions & 4 deletions lib/moodlelib.php
Original file line number Diff line number Diff line change
Expand Up @@ -9051,11 +9051,25 @@ function get_performance_info() {
$hits = 0;
$misses = 0;
$sets = 0;
foreach ($stats as $definition => $stores) {
$html .= '<span class="cache-definition-stats">';
$html .= '<span class="cache-definition-stats-heading">'.$definition.'</span>';
foreach ($stats as $definition => $details) {
switch ($details['mode']) {
case cache_store::MODE_APPLICATION:
$modeclass = 'application';
$mode = ' <span title="application cache">[a]</span>';
break;
case cache_store::MODE_SESSION:
$modeclass = 'session';
$mode = ' <span title="session cache">[s]</span>';
break;
case cache_store::MODE_REQUEST:
$modeclass = 'request';
$mode = ' <span title="request cache">[r]</span>';
break;
}
$html .= '<span class="cache-definition-stats cache-mode-'.$modeclass.'">';
$html .= '<span class="cache-definition-stats-heading">'.$definition.$mode.'</span>';
$text .= "$definition {";
foreach ($stores as $store => $data) {
foreach ($details['stores'] as $store => $data) {
$hits += $data['hits'];
$misses += $data['misses'];
$sets += $data['sets'];
Expand Down
64 changes: 38 additions & 26 deletions theme/bootstrapbase/less/moodle/debug.less
Original file line number Diff line number Diff line change
Expand Up @@ -45,33 +45,45 @@
margin-right: 10px;
margin-left: 10px;
}
.performanceinfo .cachesused {

/** Cache stats styles **/
#page-footer .performanceinfo .cachesused {
margin-top: 1em;
}
.performanceinfo .cachesused .cache-stats-heading,
.performanceinfo .cachesused .cache-total-stats {
font-weight: bold;
font-size: 110%;
margin-top: 0.3em;
}
#page-footer .performanceinfo .cachesused .cache-definition-stats {
margin: .3em;
display: inline-block;
vertical-align: top;
background-color: @wellBackground;
}
.cache-store-stats {
padding: 0 1.3em;
}
.cache-store-stats.nohits {
background-color: @errorBackground;
}
.cache-store-stats.lowhits {
background-color: @warningBackground;
}
.cache-store-stats.hihits {
background-color: @successBackground;
}

.cache-stats-heading,
.cache-total-stats {
font-weight: bold;
font-size: 110%;
margin-top: 0.3em;
}
.cache-definition-stats {
margin: .3em;
display: inline-block;
vertical-align: top;
background-color: @wellBackground;

.cache-definition-stats-heading span {
display: inline-block;
cursor: default;
}

.cache-store-stats {
padding: 0 1.3em;

&.nohits {
background-color: @errorBackground;
}
&.lowhits {
background-color: @warningBackground;
}
&.hihits {
background-color: @successBackground;
}
}
}
}


#page-footer,
#page-footer .validators,
#page-footer .purgecaches,
Expand Down
2 changes: 1 addition & 1 deletion theme/bootstrapbase/style/moodle.css

Large diffs are not rendered by default.

0 comments on commit 7fa57e0

Please sign in to comment.