-
-
Notifications
You must be signed in to change notification settings - Fork 825
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
(dev/core#635) Deprecate CRM_Core_BAO_Cache for I/O. Optionally redirect I/O to Redis or Memcache. #13489
Conversation
23f5c79
to
c1dd1e4
Compare
c1dd1e4
to
a616f31
Compare
a616f31
to
82d36b3
Compare
CRM/Core/BAO/Cache.php
Outdated
*/ | ||
public static function &getItem($group, $path, $componentID = NULL) { | ||
if ($adapter = CRM_Utils_Constant::value('CIVICRM_BAO_CACHE_ADAPTER')) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From an IDE POV this construct
if (($adapter = CRM_Utils_Constant::value('CIVICRM_BAO_CACHE_ADAPTER')) !== FALSE) {
doesn't give warnings. I believe the case for it is also that it disambiguates between '= means =' & '= is a bug because I forgot the second one'
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@eileenmcnaughton I've pushed up a revision to use that notation. Notes:
- FWIW, my IDE doesn't complain about either the old or new notation. (PHPStorm 2016.2.2.)
CRM_Utils_Constant::value()
returns a default ofNULL
, so I used that instead ofFALSE
.
CRM/Core/BAO/Cache/Psr16.php
Outdated
* @return object | ||
* The data if present in cache, else null | ||
*/ | ||
public static function &getItem($group, $path, $componentID = NULL) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we should be adding new functions with the & before them. Last time I dug into it that was to support Php 4
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tend to agree. I'll change it if you want, but let me explain a little thinking.
Short version: we're essentially overriding CRM_Core_BAO_Cache::&getItem()
, and that does return by reference.
Longer version: Your comment is very on-point in this use-case (and even understates it). The &
is demonstrably pointless. getItem()
delegates to PSR-16 get()
which does not preserve references. In fact, the PSR-16 compliance tests go out of their way to ensure that cache-values do not work like references (even with object
s which are innately more reference-ish). Thus, with the PSR-16 adapter, it's never going to behave like a true reference. I wager that's OK.
But check the way CIVICRM_BAO_CACHE_ADAPTER
is framed -- it basically allow us to swap out the implementation of CRM_Core_BAO_Cache::&getItem()
with $someClass::&getItem()
. This is a sort of contingency... in the highly unlikely scenario that we discover that the implementation in CRM_Core_BAO_Cache_Psr16
is fundamentally problematic, one can deploy a different adapter. I'm not saying that it should happen or will happen. But spec'ing the adapter to precisely follow the original contract gives us more wiggle room.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm still with change.... it's cruft and if we need to change again we can migrate to something else but let's not introduce a new bad pattern
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@eileenmcnaughton I've pushed up b5e7d57
This required moving a little reference-trickery from CRM_Core_BAO_Cache_Psr16
to CRM_Core_BAO_Cache
, but it's still the same trick.
'dashboard', // be.chiro.civi.atomfeeds | ||
'lineitem-editor', // biz.jmaconsulting.lineitemedit | ||
'HRCore_Info', // civihr/uk.co.compucorp.civicrm.hrcore | ||
'CiviCRM setting Spec', // nz.co.fuzion.entitysetting |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could remove this entitysetting one - I consider that replaced by Custom Data on any
82d36b3
to
22bbbdb
Compare
Before ---------------------------------------- * Requests for `CRM_Core_BAO_Cache` (`setItem($data,$group,$path)`, `getItem($group,$path)`, `getItems($group)`, `deleteGroup($group,$path)`) are *always* served by two tiers: (1) an in-memory array (`static::$cache`) and (2) an SQL table. After ---------------------------------------- * There is a config option `define('CIVICRM_BAO_CACHE_ADAPTER', 'CRM_Core_BAO_Cache_Psr16');`. * When disabled (default), `CRM_Core_BAO_Cache` continues using the old code. * When enabled, `CRM_Core_BAO_Cache` changes behavior. Each `$group` is mapped to a PSR-16 object. * The class/implementation for each `$group` depends on the configuration: * In a typical (non-Redis/non-Memcache) deployment, the implementation is `CRM_Utils_Cache_SqlGroup`, which has the same 2-tier structure (in-memory+SQL). * In Redis/Memcache deployment, the implementation combines `FastArrayDecorator` with `CRM_Utils_Cache_Redis` or `CRM_Utils_Cache_Memcache`. This gives a similar 2-tier structure (e.g. in-memory+Redis).
…teGroup() These interfaces predate PSR-16 -- which is more flexible and complete. PSR-16 supports TTLs, default-values, multi-key operations, etc. PSR-16 drivers can be extended/decorated/replaced. There are third-party implementations of PSR-16. And (personally) I find the code which consumes PSR-16 to be more readable+writeable (e.g. `$cache->get($key)` vs `CRM_Core_BAO_Cache::getItem($group, $item)`). However, `CRM_Core_BAO_Cache` has been around forever. I currently count ten distinct cache-groups which rely on it (5 from `civicrm-core` and 5 from `universe`). So we shouldn't remove it outright.
22bbbdb
to
920fa38
Compare
…o return a reference This is following up on the code-review comments from civicrm#13489 (comment)
I tested this & without the new define there is no impact. With the new define it provides an alternative path that works & takes us forwards in our refactoring. This is safe IMHO - merging |
Overview
CRM_Core_BAO_Cache
provides an interface for reading and writing cache data (setItem($data,$group,$path)
,getItem($group,$path)
,getItems($group)
,deleteGroup($group,$path)
). There are two problems with this:CRM_Core_BAO_Cache
is hard-coded to an implementation with a specific data-storage policy (combining astatic::$cache
with a table SQLcivicrm_cache
). It's a fine default, but it's problematic for dev/core#635 -- in rodb configuration, writing tocivicrm_cache
forces the readers to switch to the master DB and generates distributed writes.On the other hand,
CRM_Core_BAO_Cache
has been around forever. We've migrated a few of the weirdest use-cases, but I still count ten distinct cache-groups which rely onCRM_Core_BAO_Cache
(5 fromcivicrm-core
and 5 fromuniverse
). Removing it outright would cause breakage (or at least front-load us with a game of whack-a-mole).This patch is the next step toward phasing-out
CRM_Core_BAO_Cache
:CRM_Core_BAO_Cache
. (Note: The I/O functions are specificallysetItem()
,getItem()
,getItems()
,deleteGroup()
. Other functions -- likecleanKey()
,encode()
,decode()
-- are qualitatively different.)Before
CRM_Core_BAO_Cache
(setItem($data,$group,$path)
,getItem($group,$path)
,getItems($group)
,deleteGroup($group, $item)
) are always served by two tiers: (1) an in-memory array (static::$cache
) and (2) an SQL table.After
There is a config option
define('CIVICRM_BAO_CACHE_ADAPTER', 'CRM_Core_BAO_Cache_Psr16');
.CRM_Core_BAO_Cache
continues using the old code.CRM_Core_BAO_Cache
changes behavior. Each$group
is mapped to a PSR-16 object.The class/implementation for each
$group
depends on the configuration:CRM_Utils_Cache_SqlGroup
, which has the same 2-tier structure (in-memory+SQL).FastArrayDecorator
withCRM_Utils_Cache_Redis
orCRM_Utils_Cache_Memcache
. This gives a similar 2-tier structure (e.g. in-memory+Redis).In RODB configuration, I'm seeing far fewer occasions where it unexpectedly/unnecessarily directs the user the master DB.
Comments
This depends-on and incorporates #13500 and #13496. The commit list looks long, but it is actually only two items (at time of writing):
There are some small ways in which the PSR-16 adapter is different, e.g.
getItems()
will throw an exception. This is actually pretty difficult to implement in pure PSR-16. Fortunately, I can't find anything (incivicrm-core
oruniverse
) which calls it.TRUNCATE TABLE civicrm_cache
). To provide a similar behavior on non-SQL systems, we walk through the list of legacy cache-groups and clear each.CRM_Core_BAO_Cache
with direct SQL IO (civicrm_cache
). The mingling would be poor form, but it's conceivable. Such code would be broken on non-SQL deployments.I think these risks are pretty narrow, but they exist. At this step of the phase-out, the PSR-16 adapter requires an opt-in, so the initial risk is borne by folks who need rodb. I'd vote for dialing up the pressure gradually (e.g. after 2-3 months, change to an opt-out; and after another 2-3, remove the old code).