Quantcast
Viewing all articles
Browse latest Browse all 19292

archon810 on "[Self-diagnosed and fixed] W3 Total Cache bug in faulty object caching"

Now for part 2.

Relevant files:

  • lib/W3/Cache/Base.php
  • lib/W3/Cache/Memcached.php
  • lib/W3/Cache/ObjectCache.php

The solution above basically means that only 2 buckets with keys '' (blank) and 0 will exist. The cached data will be split between these 2 buckets:

[20-Apr-2014 00:42:20 UTC] APDEBUG setting key version for group  to 44
[20-Apr-2014 00:42:20 UTC] APDEBUG setting key version for group 0 to 14
[20-Apr-2014 00:42:20 UTC] APDEBUG setting key version for group  to 44
[20-Apr-2014 00:42:20 UTC] APDEBUG setting key version for group 0 to 14

That seems to work, but the intention of the code that deals with object caching is to make the buckets correspond to groups (like 'options', 'transient', etc), at least that's what I gather from reading the code.

The main problem is that the $group value isn't passed from ObjectCache.php to the respective plugins, such as Apc.php, Memcached.php, etc. This means that the groups for all objects will be set to the defaults, hence 0 and 1 (see part 1 above for why we have the discrepancy in the first place).

I think the right fix is to also pass the $group value along as well. I'm not sure my patch is 100% complete - it should still be checked by a core developer, but the idea is to do this:

Index: lib/W3/ObjectCache.php
===================================================================
--- lib/W3/ObjectCache.php      (revision 891523)
+++ lib/W3/ObjectCache.php      (working copy)
@@ -164,7 +164,7 @@
                   !in_array($group, $this->nonpersistent_groups) &&
                     $this->_check_can_cache_runtime($group)) {
             $cache = $this->_get_cache(null, $group);
-            $v = $cache->get($key);
+            $v = $cache->get($key, $group);
             if (is_array($v) && $v['content'] != null)
                 $value = $v['content'];
             else
@@ -234,7 +234,7 @@

         $this->cache[$key] = $data;

-        if ($this->_caching &&
+        if ($this->_caching &&
                 !in_array($group, $this->nonpersistent_groups) &&
                 $this->_check_can_cache_runtime($group)) {
             $cache = $this->_get_cache(null, $group);
@@ -251,7 +251,7 @@

             $v = array('content' => $data);
             return $cache->set($key, $v,
-                ($expire ? $expire : $this->_lifetime));
+                ($expire ? $expire : $this->_lifetime), $group);
         }

         return true;
@@ -277,7 +277,7 @@
         if ($this->_caching && !in_array($group, $this->nonpersistent_groups)) {
             $cache = $this->_get_cache(null, $group);

-            return $cache->delete($key);
+            return $cache->delete($key, $group);
         }

         return true;

At this point, going back to the log produces something like:

[20-Apr-2014 01:00:39 UTC] APDEBUG setting key version for group post_tag to
[20-Apr-2014 01:00:40 UTC] APDEBUG setting key version for group posts to
[20-Apr-2014 01:00:40 UTC] APDEBUG setting key version for group category to
[20-Apr-2014 01:00:40 UTC] APDEBUG setting key version for group post_tag_relationships to
[20-Apr-2014 01:00:40 UTC] APDEBUG setting key version for group category_relationships to
[20-Apr-2014 01:00:40 UTC] APDEBUG setting key version for group post_format_relationships to
[20-Apr-2014 01:00:40 UTC] APDEBUG setting key version for group post_meta to
[20-Apr-2014 01:00:40 UTC] APDEBUG setting key version for group users to
[20-Apr-2014 01:00:40 UTC] APDEBUG setting key version for group userlogins to
[20-Apr-2014 01:00:40 UTC] APDEBUG setting key version for group useremail to
[20-Apr-2014 01:00:40 UTC] APDEBUG setting key version for group userslugs to
[20-Apr-2014 01:00:40 UTC] APDEBUG setting key version for group user_meta to
[20-Apr-2014 01:07:45 UTC] APDEBUG setting key version for group default to 15
[20-Apr-2014 01:07:45 UTC] APDEBUG setting key version for group options to 15
[20-Apr-2014 01:07:46 UTC] APDEBUG setting key version for group transient to 15

I'm too tired to figure out if it's a good or a bad thing that the key versions are the same for different groups, but at least they seem to be consistent across get() and set().

I'm hoping Frederick, who I've been trying to reach to work on this bug, or someone from the W3TC dev team will see this, respond, and evaluate.

Thank you and good luck, everyone.


Viewing all articles
Browse latest Browse all 19292

Trending Articles