drupal_static_reset is broken

chx - November 2, 2009 - 05:04
Project:Drupal
Version:7.x-dev
Component:base system
Category:bug report
Priority:normal
Assigned:chx
Status:closed
Description

Since #254491-108: Standardize static caching we lost the version which stored the defaults and drupal_static_reset only resets inside drupal_static and does not affect the function that stores a reference to the drupal_static storage. The only reason we see drupal_static_reset working is that after the reset, we unconditionally call drupal_static with the default we want and because inside drupal_static the storage is now unset, the default gets stored. However, if the default would be a costly affair to calculate and we would take to care to pass it to drupal_static once, expecting it to hold for us, things would break. Or if a genius like Casey (really nice job!) wants to make sure we call drupal_static only once as in #619666: Introduce new pattern for drupal_static() in performance-critical functions then suddenly things fall apart. I am attaching a patch that was RTBC'd in the original issue, carries the same amount of lines of code and works a hell lot better by storing the default and doing a real reset. Memory issues were cited -- given that the default is mostly just array() or FALSE, that's not a really good argument compared to the fact that the memory saving version is broken.

AttachmentSizeStatusTest resultOperations
drupal_static_cleanup.patch2 KBIdleFailed: Failed to install HEAD.View details | Re-test

#1

System Message - November 2, 2009 - 05:15
Status:needs review» needs work

The last submitted patch failed testing.

#2

chx - November 4, 2009 - 20:41
Status:needs work» needs review

Sorry for the patch mixup.

AttachmentSizeStatusTest resultOperations
drupal_static_cleanup.patch1.09 KBIdleFailed: 14657 passes, 0 fails, 92 exceptionsView details | Re-test

#3

System Message - November 4, 2009 - 20:55
Status:needs review» needs work

The last submitted patch failed testing.

#4

chx - November 5, 2009 - 07:31
Status:needs work» needs review

catch gave me an important hint to what happens here. Thanks!

AttachmentSizeStatusTest resultOperations
drupal_static_cleanup.patch1.1 KBIdleFailed: 14665 passes, 3 fails, 15456 exceptionsView details | Re-test

#5

System Message - November 5, 2009 - 07:40
Status:needs review» needs work

The last submitted patch failed testing.

#6

chx - November 7, 2009 - 08:23
Status:needs work» needs review

Yeah, yeah, if you reset before drupal_static is called w a default then now you get a notice...

AttachmentSizeStatusTest resultOperations
drupal_static_cleanup.patch1.26 KBIdleFailed: Failed to install HEAD.View details | Re-test

#7

System Message - November 7, 2009 - 08:35
Status:needs review» needs work

The last submitted patch failed testing.

#8

chx - November 7, 2009 - 09:06
Status:needs work» needs review

Hm, right.

AttachmentSizeStatusTest resultOperations
drupal_static_cleanup.patch1.23 KBIdleFailed: 14679 passes, 0 fails, 92 exceptionsView details | Re-test

#9

System Message - November 7, 2009 - 09:20
Status:needs review» needs work

The last submitted patch failed testing.

#10

chx - November 7, 2009 - 09:31
Status:needs work» needs review

OK, no more trying to fix. I rewrote it. The code flow now is a lot clearer, too. First we handle the reset-all case, then the reset-one case and explicitly deal with the "reset called before we have a default" case.

AttachmentSizeStatusTest resultOperations
drupal_static_cleanup.patch1.67 KBIdleFailed: Failed to apply patch.View details | Re-test

#11

sun - November 7, 2009 - 17:55

If this would be wrong, then a lot of tests would fail. So it seems this is almost RTBC.

+++ includes/bootstrap.inc 2009-11-07 09:30:56 +0000
@@ -2066,31 +2066,34 @@ function registry_rebuild() {
   if ($reset) {
...
+    if (array_key_exists($name, $default)) {
+      $data[$name] = $default[$name];
     }
     else {
...
+      // Reset was called before a default is set and yet a variable must be
+      // returned.
+      return $data;
+    }   
   }

Could we add some inline comments here as well?

(Please also note the trailing whites-pace.)

+++ includes/bootstrap.inc 2009-11-07 09:30:56 +0000
@@ -2066,31 +2066,34 @@ function registry_rebuild() {
+  elseif (!array_key_exists($name, $data)) {
+    $default[$name] = $data[$name] = $default_value;
   }

Inline comments here, too, as this seems to be the main static/reference handling.

I'm on crack. Are you, too?

#12

chx - November 7, 2009 - 19:12

Added even more comments. It's now (way) more comments than code.

AttachmentSizeStatusTest resultOperations
drupal_static_cleanup.patch1.81 KBIdleFailed: Failed to apply patch.View details | Re-test

#13

sun - November 7, 2009 - 19:49
Status:needs review» reviewed & tested by the community

Alright, I'm more happy with this.

#14

Dries - November 8, 2009 - 20:36
Status:reviewed & tested by the community» fixed

Looks good to me too. Committed.

#15

effulgentsia - November 10, 2009 - 06:34
Status:fixed» needs review

drupal_static_reset() is still broken when called globally (without passing a $name parameter). This was the case prior to this issue, but I'm attaching the patch here, since it's related to this issue. The bug hasn't manifested yet, because we have no places within core where drupal_static_reset() is called without passing $name. This patch includes a test that fails unless this patch is applied.

AttachmentSizeStatusTest resultOperations
drupal_static_cleanup_15.patch3.04 KBIdlePassed: 14737 passes, 0 fails, 0 exceptionsView details | Re-test

#16

chx - November 10, 2009 - 13:05
Status:needs review» needs work

Nice! But can't you simply do foreach ($default as $name => $value) $data[$name] = $value;?

#17

effulgentsia - November 10, 2009 - 18:33
Status:needs work» needs review

Yes.

AttachmentSizeStatusTest resultOperations
drupal_static_cleanup_17.patch3.03 KBIdlePassed: 14744 passes, 0 fails, 0 exceptionsView details | Re-test

#18

effulgentsia - November 12, 2009 - 01:26

Cross-linking this to #601584: setUp() function for unit and web test cases should reset all resettable statics, because that issue now includes this same fix. If that issue lands first, then this one can be marked "fixed" again as per #14. On the other hand, if this issue lands first, then that one will need to be re-rolled.

#19

chx - November 13, 2009 - 22:17
Status:needs review» reviewed & tested by the community

Thanks.

#20

webchick - November 15, 2009 - 21:41
Status:reviewed & tested by the community» fixed

Committed to HEAD with some minor comment/whitespace clean-up.

#21

effulgentsia - November 16, 2009 - 01:05

Awesome! So, now that global drupal_static_reset() isn't broken, can anyone here help get #601584: setUp() function for unit and web test cases should reset all resettable statics to RTBC level?

#22

System Message - November 30, 2009 - 01:10
Status:fixed» closed

Automatically closed -- issue fixed for 2 weeks with no activity.

 
 

Drupal is a registered trademark of Dries Buytaert.