book_get_books() cache becomes stale when batch-inserting book pages

deviantintegral - January 17, 2009 - 22:57
Project:Drupal
Version:6.x-dev
Component:book.module
Category:bug report
Priority:normal
Assigned:Unassigned
Status:needs review
Issue tags:Newbie
Description

I'm working on the Skeleton Outlines module, which lets users define templates of entire books. It works by storing node data and then calling drupal_execute() on that data to construct the book outline.

The problem is that book_get_books() keeps a static variable of all books. So the first time it's called, it works as expected, but then subsequent calls in the same request can fail because the newly-created book doesn't exist in the cache. This patch adds a reset parameter to book_get_books().

I will be working on a test for this soon, but if there is something obvious I've missed then please let me know :)

I've attached patches for D7 and D6, and I imagine it would make sense to backport to D5 as well.

AttachmentSizeStatusTest resultOperations
reset_book_cache_6.x.patch822 bytesIdleFailed: Failed to apply patch.View details | Re-test
reset_book_cache_7.x.patch801 bytesIdleFailed: Failed to apply patch.View details | Re-test

#1

deviantintegral - January 18, 2009 - 00:22
Assigned to:deviantintegral» Anonymous

Here is the start of a test. It's still broken in that somehow the nodes are being created in the actual DB, not in the simpletest DB. I'll work on this again in the next few days.

AttachmentSizeStatusTest resultOperations
360377_reset_book_cache_7.x_1.patch3.37 KBIdleFailed: 9268 passes, 0 fails, 13 exceptionsView details | Re-test

#2

deviantintegral - January 22, 2009 - 17:34
Status:needs work» needs review

Here is a patch with a working test. The test is dependent on #297972: drupal_execute is incompatible with batch API.

In book.module:

  1. The $reset parameter is added as above.
  2. After inserting or deleting a book, book_get_books(TRUE) is called to reset the cache.

And in book.test:

  1. A new method, createBookDrupalExecute() is created, as we can't use drupalPost() to expose the bug.
  2. It then checks to see if the book outline differs when the new book is created, and if it is back to the original state after deleting the new book.

Review / testing / comments would all be appreciated!

AttachmentSizeStatusTest resultOperations
reset_book_cache_7.x_2.patch3.43 KBIdleFailed: Failed to apply patch.View details | Re-test

#3

moshe weitzman - January 22, 2009 - 18:31

Yet another use case for a centralized static variable cache.

#4

deviantintegral - January 22, 2009 - 18:55

Here is a patch for Drupal 6 as well. It is pretty much the same except that it excludes the test.

A centralized cache does make sense, especially if it had some way of easily exposing to developers that something is cached per request. It's not obvious until you look inside book_get_books() that a static comes into play, leading to much frustration.

AttachmentSizeStatusTest resultOperations
360377_reset_book_cache_6.x_2.patch1.45 KBIdleFailed: Failed to apply patch.View details | Re-test

#5

System Message - January 22, 2009 - 19:05
Status:needs review» needs work

The last submitted patch failed testing.

#6

deviantintegral - July 29, 2009 - 16:09
Status:needs work» needs review

Setting to needs review as the bot tried to test the 6.x patch I posted.

#7

Wies Hubbers - August 17, 2009 - 09:04
Version:7.x-dev» 6.x-dev

I have the same issue here! I add book dynamically and I use book_get_books to get to them.

#8

deviantintegral - August 18, 2009 - 03:10

The Drupal 7 issue was addressed with the implementation of drupal_static over at #480412: Update book module to use drupal_static().

@wies, can you review the patch against Drupal 6?

#9

idflood - September 3, 2009 - 13:06

I applied the patch to Drupal 6 head without any error. ( no further testing yet ). How can I help?

#10

deviantintegral - November 18, 2009 - 02:04
Issue tags:+Newbie

Thanks idflood; if you could provide feedback about the code itself, so others reading this issue have more info about what you reviewed. Some good guidelines are here: http://drupal.org/patch/review

 
 

Drupal is a registered trademark of Dries Buytaert.