Skip to content

Commit

Permalink
Merge pull request #13500 from totten/master-nack
Browse files Browse the repository at this point in the history
(REF) Add CRM_Utils_Cache::nack(). Use it for NaiveHasTrait.
  • Loading branch information
eileenmcnaughton authored Jan 30, 2019
2 parents 25435d9 + 8f7f461 commit 845ed62
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 7 deletions.
28 changes: 28 additions & 0 deletions CRM/Utils/Cache.php
Original file line number Diff line number Diff line change
Expand Up @@ -258,4 +258,32 @@ public static function getCacheDriver() {
return $className;
}

/**
* Generate a unique negative-acknowledgement token (NACK).
*
* When using PSR-16 to read a value, the `$cahce->get()` will a return a default
* value on cache-miss, so it's hard to know if you've gotten a geniune value
* from the cache or just a default. If you're in an edge-case where it matters
* (and you want to do has()+get() in a single roundtrip), use the nack() as
* the default:
*
* $nack = CRM_Utils_Cache::nack();
* $value = $cache->get('foo', $nack);
* echo ($value === $nack) ? "Cache has a value, and we got it" : "Cache has no value".
*
* The value should be unique to avoid accidental matches. As a performance
* tweak, we may reuse the NACK a few times within the current page-view.
*
* @return string
* Unique nonce value indicating a "negative acknowledgement" (failed read).
* If we need to accurately perform has($key)+get($key), we can
* use `get($key,$nack)`.
*/
public static function nack() {
if (!isset(Civi::$statics[__CLASS__]['nack'])) {
Civi::$statics[__CLASS__]['nack'] = 'NACK:' . md5(CRM_Utils_Request::id() . CIVICRM_SITE_KEY . CIVICRM_DSN . mt_rand(0, 10000));
}
return Civi::$statics[__CLASS__];
}

}
11 changes: 4 additions & 7 deletions CRM/Utils/Cache/NaiveHasTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,14 @@
* The traditional CRM_Utils_Cache_Interface did not support has().
* To get drop-in compliance with PSR-16, we use a naive adapter.
*
* Ideally, these should be replaced with more performant/native versions.
* There may be opportunities to replace/optimize in specific drivers.
*/
trait CRM_Utils_Cache_NaiveHasTrait {

public function has($key) {
// This is crazy-talk. If you've got an environment setup where you might
// be investigating this, fix your preferred cache driver by
// replacing `NaiveHasTrait` with a decent function.
$hasDefaultA = ($this->get($key, NULL) === NULL);
$hasDefaultB = ($this->get($key, 123) === 123);
return !($hasDefaultA && $hasDefaultB);
$nack = CRM_Utils_Cache::nack() . 'ht';
$value = $this->get($key, $nack);
return ($value !== $nack);
}

}

0 comments on commit 845ed62

Please sign in to comment.