Using cache mechanism in serendipity_event_entryproperties

Creating and modifying plugins.
Post Reply
FishNiX
Regular
Posts: 40
Joined: Sun Sep 02, 2007 6:32 pm

Using cache mechanism in serendipity_event_entryproperties

Post by FishNiX »

I'm writing a plugin that munges entries and changes the location of mediadb stuff. I'm a little concerned that doing that munging will use too many CPU cycles so obviously I'm looking to cache those modified entries. It looks like the ep_cache stores the munged version of my entries in the DB... How does this work? Are there things I need to do to take advantage of this? If I can use this cache, how do I ensure that I properly flush + cache entries appropriately?

Does adding this take care of it for me, or only when my plugin is installed?

Code: Select all

   function install() {
        serendipity_plugin_api::hook_event('backend_cache_entries', $this->title);
    }

    function uninstall() {
        serendipity_plugin_api::hook_event('backend_cache_purge', $this->title);
        serendipity_plugin_api::hook_event('backend_cache_entries', $this->title);
    }
Thanks!
FishNiX
Regular
Posts: 40
Joined: Sun Sep 02, 2007 6:32 pm

Re: Using cache mechanism in serendipity_event_entryproperti

Post by FishNiX »

It looks to me like "uninstalling" my plugin will actually purge the entire ep_cache_*

Code: Select all

 case 'backend_cache_purge':
                    if (!$is_cache) {
                        return true;
                    }

                    serendipity_db_query("DELETE FROM {$serendipity['dbPrefix']}entryproperties WHERE property LIKE 'ep_cache_%'");
                    break;

and "installing" the plugin will kick off a re-cache of all entries?

Code: Select all

                case 'backend_cache_entries':
                    if (!$is_cache) {
                        return true;
                    }

                    $entries = serendipity_fetchEntries(
                        null,
                        true,
                        $serendipity['fetchLimit'],
                        false,
                        false,
                        'timestamp DESC',
                        '',
                        true
                    );

                    foreach($entries AS $idx => $entry) {
                        $this->updateCache($entry);
                    }
                    return true;
                    break;
Is there a limit to the number of entries that will be munged and re-cached?

Are the install/uninstall hooks only called when actually deleting a plugin or also when making them Active/Inactive?

Thanks again!
garvinhicking
Core Developer
Posts: 30022
Joined: Tue Sep 16, 2003 9:45 pm
Location: Cologne, Germany
Contact:

Re: Using cache mechanism in serendipity_event_entryproperti

Post by garvinhicking »

Hi!

The way the ep_cache works is like this:

Once the plugin is installed and the cache is enabled, each new entry that will be created will create a cached version by executing all plugins that hook into the cachable frontend_display event. The result of this is then saved in the entryproperties table with the ep_cache one.
Now whenever an entry is displayed, instead of executing all the markup plugins' frontend_display hook again, instead the body of the entry is simply switched with the contents of ep_cache. Only non-caching plugins for frontend_display will be executed after this.

This means, whenever a new markup plugin is installed, it would not affect old cached entries. This is why the hook "backend_cache_entries" was created, so that plugins on installing can invalidate the old cache and create the new one, including their content. The same functionality can be executed by the blog admin through the "Cache all entries" link in the sidebar menu.

The uninstall() thing flushes the cache as well, so that what a plugin formerly did to the entry will be undone.

So if your plugin only uses the install() and uninstall() routines, and hook on the backend_cache_entries, this will properly rebuild the whole cache - but not new entries being entered by the user. Which would be bad of course.

This is why the core functionality of any new markup plugin supporting caching should be this:

1. Create a helper method that operates on the entry data (like $this->workData($eventData) or whatever)

2. Hook the frontend_display event, call $this->workData()

3. Create a install() method that hooks into backend_cache_entries.

4. Create a uninstall() method that hooks into backend_cache_purge and backend_cache_entries.

5. In the introspect() method, add a $propbad->add('cachable_events', array('frontend_display' => true)) so that the entryproperty plugin knows that your plugin's frontend_Display hook is cachable.

6. Note that your plugin DOES NOT need to implement any functions on the backend_cache_* events. The serendipity_event_entryproperties is the plugin that pruges and invalidates the entryproperties DB table.

One of the most simply examples for this is the serendipity_event_wordwrap plugin.

Best regards,
Garvin
# Garvin Hicking (s9y Developer)
# Did I help you? Consider making me happy: http://wishes.garv.in/
# or use my PayPal account "paypal {at} supergarv (dot) de"
# My "other" hobby: http://flickr.garv.in/
FishNiX
Regular
Posts: 40
Joined: Sun Sep 02, 2007 6:32 pm

Re: Using cache mechanism in serendipity_event_entryproperti

Post by FishNiX »

Thanks garvin! The explanation helps. I'll let you know how it goes!
FishNiX
Regular
Posts: 40
Joined: Sun Sep 02, 2007 6:32 pm

Re: Using cache mechanism in serendipity_event_entryproperti

Post by FishNiX »

I think I'm on my way here but I have one question for #2. Right now I do a switch case for the event in the normal way... something like this (remved detail for brevity)

Code: Select all

  if (isset($hooks[$event])) {
    switch($event) {
      case 'backend_image_addform':
        ...
        ...
      break;

      case 'backend_image_add':
        ...
        ...
      break;

     case 'backend_preview':
     case 'frontend_display':
        some_logic;
        foreach ($this->markup_elements as $temp) {
          if (serendipity_db_bool($this->get_config($temp['name'], true)) && isset($eventData[$temp['element']])) {
            $element = $temp['element'];
            $eventData[$element] =  $this->workData($eventData[$element]);
           }
        }
     break;	
  }
}
So where do I hook frontend_display? BTW, I'm assuming you mean I need to add a hook to frontend_display, right? add this code:

Code: Select all

serendipity_plugin_api::hook_event('frontend_display', $entry, $addData);
Thanks!
garvinhicking
Core Developer
Posts: 30022
Joined: Tue Sep 16, 2003 9:45 pm
Location: Cologne, Germany
Contact:

Re: Using cache mechanism in serendipity_event_entryproperti

Post by garvinhicking »

Hi!

I'd mean it just like your snippet; there you would add a 'frontend_display' case. Also make sure that you add 'frontend_display' in the introspect() method to your event_hooks array!

HTH,
Garvin
# Garvin Hicking (s9y Developer)
# Did I help you? Consider making me happy: http://wishes.garv.in/
# or use my PayPal account "paypal {at} supergarv (dot) de"
# My "other" hobby: http://flickr.garv.in/
Post Reply