Rules Cache Rebuild Locking

Public

Locking for the case the cache has to be rebuilt. Avoids stampeding.

</> CopyGet raw version
php
  1. function &rules_get_cache($cid = 'data') {
  2. // Make use of the fast, advanced drupal static pattern.
  3. static $drupal_static_fast;
  4. if (!isset($drupal_static_fast)) {
  5. $drupal_static_fast['cache'] = &drupal_static(__FUNCTION__, array());
  6. }
  7. $cache = &$drupal_static_fast['cache'];
  8.  
  9. if (!isset($cache[$cid])) {
  10. // The main 'data' cache includes translated strings, so each language is
  11. // cached separately.
  12. $cid_suffix = $cid == 'data' ? ':' . $GLOBALS['language']->language : '';
  13.  
  14. if ($get = cache_get($cid . $cid_suffix, 'cache_rules')) {
  15. $cache[$cid] = $get->data;
  16. }
  17. else {
  18. $lock_type = 'generic';
  19. if ($cid === 'data') {
  20. $lock_type = 'data';
  21. }
  22. elseif (strpos($cid, 'comp_') === 0) {
  23. $lock_type = 'comp_';
  24. }
  25. elseif (strpos($cid, 'event_') === 0) {
  26. $lock_type = 'event_';
  27. }
  28. // Prevent stampeding. The rules cache can become quite enormous and take
  29. // some time to build - thus make sure we're rebuilding it just once at
  30. // the same time.
  31. while (!lock_acquire(__FUNCTION__ . $lock_type, 60)) {
  32. watchdog('rules', 'Cache rebuild locking triggered.', NULL, WATCHDOG_WARNING);
  33. // Now wait until the lock is released.
  34. lock_wait(__FUNCTION__ . $lock_type);
  35. // If the lock is released it's likely the cache was rebuild. Thus check
  36. // again if we can fetch it from the persistent cache.
  37. if ($get = cache_get($cid . $cid_suffix, 'cache_rules')) {
  38. $cache[$cid] = $get->data;
  39. return $cache[$cid];
  40. }
  41. }
  42. }
  43. if ($cid === 'data') {
  44. // There is no 'data' cache so we need to rebuild it. Make sure subsequent
  45. // cache gets of the main 'data' cache during rebuild get the interim
  46. // cache by passing in the reference of the static cache variable.
  47. _rules_rebuild_cache($cache['data']);
  48. }
  49. elseif (strpos($cid, 'comp_') === 0) {
  50. $cache[$cid] = FALSE;
  51. _rules_rebuild_component_cache($cid);
  52. }
  53. elseif (strpos($cid, 'event_') === 0) {
  54. $cache[$cid] = FALSE;
  55. RulesEventSet::rebuildEventCache();
  56. }
  57. else {
  58. $cache[$cid] = FALSE;
  59. }
  60. if (isset($lock_type)) {
  61. lock_release(__FUNCTION__ . $lock_type);
  62. }
  63.  
  64. }
  65. return $cache[$cid];
  66. }