CiviCRM Community Forums (archive)

*

News:

Have a question about CiviCRM?
Get it answered quickly at the new
CiviCRM Stack Exchange Q+A site

This forum was archived on 25 November 2017. Learn more.
How to get involved.
What to do if you think you've found a bug.



  • CiviCRM Community Forums (archive) »
  • Old sections (read-only, deprecated) »
  • Developer Discussion (Moderator: Donald Lobo) »
  • Lack of consistency in GroupContactCache
Pages: [1]

Author Topic: Lack of consistency in GroupContactCache  (Read 1021 times)

jcasharpe

  • I post occasionally
  • **
  • Posts: 57
  • Karma: 5
    • Woodlands Church
  • CiviCRM version: 4.4.6
  • CMS version: Drupal 7
  • MySQL version: MariaDB 10.0.13
  • PHP version: 5.5
Lack of consistency in GroupContactCache
May 25, 2013, 04:24:46 pm
The current implementation of GroupContactCache attempts to create some illusion of consistency but actually only does if you assume a single user accessing Civi. This is the fundamental problem behind CRM-12466 and the reason why a call to loadAll with no arguments is made to try to ensure consistency.

In GroupContactCache::add the following workflow occurs:

a. remove all group cache entries for all groups being refreshed
b. for each group being refreshed refill this group

So any queries that attempt to use the GroupContactCache between a and b utilising a group that is being refreshed will get an inconsistent view of the cache. You stated earlier that you expect the cache behaviour to be consistent but if someone executes a search between a and b above then they will get an inconsistent view of the cache. You could reformulate the add function to do:

for each group:
   Lock cache table
   Remove all cache entries for group
   Refresh group entries
   end lock

which ensures that you have a consistent view of the groups. Note that you can't use row level locking because you are removing the rows here, which is unfortunate because locking the table for update is not really scalable.

Also in Contact_BAO_Query::addGroupContactCache there is a call to GroupContactCache::load($smartGroupId) which obviously populates the cache table at the point that the sql query is being constructed but doesn't do anything to ensure that it will still be valid at the point the query is actually executed.

Contact::delete calls Contact_BAO_query::remove. Unless smartGroupTimeout is set to 0 this will only refresh the groups that have timed out. This potentially leaves contact ids to the deleted contact in the GroupContact cache. Contact::delete should do something like DELETE from group_contact_cache WHERE contact_id=deleted_contact_id instead and then let the normal timeout mechanism refresh the smart groups (relationships mean that this might cause other members to be removed / added to groups) GroupContact::addContactToGroup has exactly the same issue.

In fact every call to GroupContactCache::remove() has similar issues!

Now the real question comes down to; should we actually be providing immediate consistency within the GroupContactCache? We have the smartGroupCache timeout variable which controls how frequently the cache gets refreshed, so given how difficult it is to actually provide consistency maybe just working to within the cache timeout is reasonable?

« Last Edit: May 25, 2013, 04:52:27 pm by jcasharpe »

totten

  • Administrator
  • Ask me questions
  • *****
  • Posts: 695
  • Karma: 64
Re: Lack of consistency in GroupContactCache
May 28, 2013, 08:48:29 pm
Looks like I missed an exciting thread on CRM-12466. ;)

1. dlobo had a comment in CRM-12466 which seemed to say that he added locking to GroupContactCache::load (and thereby to GroupContactCache::loadAll), but I don't see it. Did that not actually go in?

http://issues.civicrm.org/jira/browse/CRM-12466?focusedCommentId=50309&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-50309

https://github.com/civicrm/civicrm-core/blob/master/CRM/Contact/BAO/GroupContactCache.php

2. Everyone seems agree that the current cache strategy isn't actually ideal -- but it feels like a major change in cache-strategy (e.g. doing incremental updates instead of full rebuilds; or refactoring for better parallel processing) would be a sizable undertaking. So instead we need to find the compromise which manages the symptoms best. (I think there may be more architectural options, but I'm reading on this pretty late.)

3. I may be misreading, but the controversy seems to be over whether its better to provide consistency (which is non-performant but more usable -- a policy which is better suited to small / low-usage deployments) or to provide to stronger performance guarantees (which sacrifices consistency but provides a better experience in large / high-usage deployments). Does this policy trade-off need to be made in code? Wouldn't it be straightforward to add a configuration option like "Allow dirty smart-groups" -- choose "Enable" if you want Civi's UI to be fast-but-inconsistent, choose "Disable" if you want slow-but-consistent? The option would be respected by UIs (e.g. if you enable dirty smart-groups, then the "Group" tab will never proactively rebuild the cache). If you chose to enable dirty smart-groups, then you would need to setup a cron job to handle rebuilds in the background.

jcasharpe

  • I post occasionally
  • **
  • Posts: 57
  • Karma: 5
    • Woodlands Church
  • CiviCRM version: 4.4.6
  • CMS version: Drupal 7
  • MySQL version: MariaDB 10.0.13
  • PHP version: 5.5
Re: Lack of consistency in GroupContactCache
May 29, 2013, 01:16:42 pm
1. Likewise I don't see it but think something is there as I'm getting lots of timeouts due to the group_contact_cache table being locked.

2. The problem with incremental updates is its really hard to do it right; smart groups can encode complex relationships between groups and contacts so it becomes tricky to work out what invalidates what.

3. The real issue is about bounding the runtime; I don't want any of my page loads to return a 504 which is what is currently happening. Ideally I want a consistent view but practically an inconsistent view is probably ok. Basically what I currently have deployed is the 'dirty' option. I've removed the rebuild from the group tab and have had to change my cron frequency from every minute to every 15 minutes as the default is for the group cache to get rebuilt on every run, every hour is too infrequent as I have to run with a limit of 10 and I have over 500 groups. I had to go to 15 minutes because with 1 minute I end up with lock contention on the table which impacts page loads giving frequent 504's.

Donald Lobo

  • Administrator
  • I’m (like) Lobo ;)
  • *****
  • Posts: 15963
  • Karma: 470
    • CiviCRM site
  • CiviCRM version: 4.2+
  • CMS version: Drupal 7, Joomla 2.5+
  • MySQL version: 5.5.x
  • PHP version: 5.4.x
Re: Lack of consistency in GroupContactCache
May 29, 2013, 04:30:26 pm

1. seems like i lost that commit in my various git branches. i'll work on it right now and do a commit before 4.3.4

2. agreed, i'd really love to figure out how to be a wee bit smarter on that. i suspect if we ignore complex smart groups but are a bit smarter about simple smart groups (for some definitition of simple and complex) that would be a big step forward

3. once 4.3.4 is out, would be great if you can submit a patch with the following changes:

a. use the limit paramter from the scheduled job to limit the number of smart groups evaluated with loadAll
b. Implement the dirty option as you/totten have described

lobo
A new CiviCRM Q&A resource needs YOUR help to get started. Visit our StackExchange proposed site, sign up and vote on 5 questions

Donald Lobo

  • Administrator
  • I’m (like) Lobo ;)
  • *****
  • Posts: 15963
  • Karma: 470
    • CiviCRM site
  • CiviCRM version: 4.2+
  • CMS version: Drupal 7, Joomla 2.5+
  • MySQL version: 5.5.x
  • PHP version: 5.4.x
Re: Lack of consistency in GroupContactCache
May 29, 2013, 05:25:31 pm

https://github.com/civicrm/civicrm-core/pull/910
A new CiviCRM Q&A resource needs YOUR help to get started. Visit our StackExchange proposed site, sign up and vote on 5 questions

Pages: [1]
  • CiviCRM Community Forums (archive) »
  • Old sections (read-only, deprecated) »
  • Developer Discussion (Moderator: Donald Lobo) »
  • Lack of consistency in GroupContactCache

This forum was archived on 2017-11-26.