cached_content

22 views
Skip to first unread message

Matt Read

unread,
Apr 11, 2013, 12:32:40 PM4/11/13
to habar...@googlegroups.com
I've been trying to think of a way to use the cached_content field. My
thinking is that I can stored the rendered output of the post content
($post->content_out) in here to avoid triggering all the formatting
plugins over and over again, ie. markdown, acronyms, etc..

The problem I'm having is in the implementation.

1. I could implement filter_post_content_out_0 (0 priority to run
first), check if there is cached content and return that. The problem
is, after returning the cached content, all the the other filters still
run, defeating the purpose.

2. I could implement filter_post_cached_content_out, and if there is
cached_content return it, otherwise return just content_out. The problem
here is that all themes need to call $post->cached_content_out, not
$post->content_out.

There is also an issue with "shorttags". I would prefer to still run the
shorttag stuff, as the content may be dynamic, and caching it's output
not ideal.

One idea I had was to modify Post::__get() so that when you called the
content_out, it would first see if there was cached_content_out
($cached_content = Plugins::filter('posts_content_out', null);) and
return that result without running filters (other than shorttag). If
there is no result proceed normally with filters. This way, if the
plugin doing the caching is deactivated, cached_content_out will return
null (even if cached_content field contains data) and go on normally
with running filters.

Second Idea was to allow plugins to stop a filter from running any more.
Something like Plugins::deregister('filter', 'post_content_out',
$priority);. But this has far greater implications.

Any thoughts?

Discuss...

Chris Meller

unread,
Apr 11, 2013, 12:39:01 PM4/11/13
to Habari Dev
I vaguely recall an IRC discussion about cached_content in which the prevailing thought seemed to be closer to #1, handled in core. I'm not sure that we got into the technical details of making sure the cached content then isn't filtered, too, so that's still an issue.

You also have to worry about watching for updated content and "expiring" the cached content (and likely not writing out a new post revision every time), so there's a lot of extra duplicate logic that would have to be included in a plugin if core didn't somehow handle it.




--
--
To post to this group, send email to habar...@googlegroups.com
To unsubscribe from this group, send email to habari-dev-unsubscribe@googlegroups.com
For more options, visit this group at http://groups.google.com/group/habari-dev
--- You received this message because you are subscribed to the Google Groups "habari-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to habari-dev+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.



Chris J. Davis

unread,
Apr 11, 2013, 12:54:33 PM4/11/13
to habar...@googlegroups.com
I am using cached_content on coworkspace, but interacting with it directly via an auth_ajax call. Having a more user friendly way of interacting with it would be ace. I have some concern in regards to having post_conten_out checking for cached content and returning it, since it might adversely affect things like pretty code, depending on how we handle it. I could be surprised though.
> --
> --
> To post to this group, send email to habar...@googlegroups.com
> To unsubscribe from this group, send email to habari-dev-...@googlegroups.com
> For more options, visit this group at http://groups.google.com/group/habari-dev
> --- You received this message because you are subscribed to the Google Groups "habari-dev" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to habari-dev+...@googlegroups.com.

Matt Read

unread,
Apr 11, 2013, 2:14:43 PM4/11/13
to habar...@googlegroups.com
On 11/04/2013 12:39 PM, Chris Meller wrote:
> I vaguely recall an IRC discussion about cached_content in which the
> prevailing thought seemed to be closer to #1, handled in core. I'm not
> sure that we got into the technical details of making sure the cached
> content then isn't filtered, too, so that's still an issue.
>
> You also have to worry about watching for updated content and
> "expiring" the cached content (and likely not writing out a new post
> revision every time), so there's a lot of extra duplicate logic that
> would have to be included in a plugin if core didn't somehow handle it.
>

In my plugins scenario I would only be updating the cached_content
whenever content is modified. Storing with no expiry, as I don't see a
need to re-cache it every x hours. Idea being I want to store the
filtered content once, and not run markdown et. al every page load.

In this scenario I would need to not cache "shorttags" output; Also
cached_content revisions could be used for something. I had not thought
about revisions.

However there may be a plugin that wants to deal with expiring the
content. Said plugin could store a serialized version of the content
with meta data in this cache store, or store meta data in info fields,
or Cache::set() a token for said post, etc.. It may be more ideal to
have a specific expires field in the post's row, save unserializing or
querying info fields? Assuming this was going to be part of core, and
not handled by plugin.

Chris Meller

unread,
Apr 11, 2013, 2:57:36 PM4/11/13
to Habari Dev

On Thu, Apr 11, 2013 at 2:14 PM, Matt Read <ma...@mattread.com> wrote:
In my plugins scenario I would only be updating the cached_content whenever content is modified. Storing with no expiry, as I don't see a need to re-cache it every x hours. Idea being I want to store the filtered content once, and not run markdown et. al every page load.

I actually meant expires in the sense that any time content changes it needs to be refreshed, there probably isn't any value in doing it automatically at a certain interval. Also remember that any changes in the active plugins could alter the output of post content: both activated / deactivated changes, as well as new versions (it could provide a new filter).

Matt Read

unread,
Apr 11, 2013, 3:12:45 PM4/11/13
to habar...@googlegroups.com
You always complicate things :P

I guess my plugin would react to an activation by triggering a cron job to regenerate the cache stores. This would be a mighty big hammer for a small nail. I would be more inclined to provide a regenerate button in the plugin config or some such, to trigger a cron.

but if content changes, plugins can check if content field is updated (old value vs. new value) I think. Must check to see if those are available.

Owen Winkler

unread,
Apr 11, 2013, 3:18:20 PM4/11/13
to habar...@googlegroups.com
This is an interesting topic. I'd love for the functionality to be
mostly transparent to themes, such that you'd never directly access
$post->cached_content, simply continue to use $post->content or
$post->content_out like always.

I don't think that the cached_content field should work like a
traditional time-expiry cache. The typical use case is much less
complex than what would be required to support time-based cache expiry.
Plugins that wanted to attempt this could still do so, but I'm not
personally sure of the value.

I suggest adding a "post_prerender_content" filter that is executed when
the cached_content value needs to be generated. This would usually be
used in two places: One when the content is changed (so that the new
value can be rendered and stored), and one when the cached_content field
is empty (which would happen for existing content that had not been
pre-rendered). Obviously, this would require a change in the plugins
that offer filters that would be useful to pre-render.

If you want to invalidate the cache, you just delete the value in the
cache field.

This idea could potentially be expensive if no content values are cached
and all of the values need to be both pre-rendered AND stored. I've
been considering a separate system that would queue object writes until
after the buffer is flushed. This is already needed for object writes
from FormUI forms, since each field is saved discretely. (For example,
saving a Post would generate one UPDATE query for each field changed
unless all of these individual writes were queued until the end of
execution.)

As to invalidating cache when plugins are added, this is done simply
with "UPDATE posts SET cached_content = ''" whenever an event occurs
that triggers a cache reset. I think, though, that executing this query
(via some API method) should either be the prerogative of a plugin that
implements the prerender filter, or (if we want to get super-fancy)
Habari should detect when a plugin that uses the prerender filter is
enabled/disabled and execute a cache reset at that time.

I've made some of the changes described above, and pushed them to a new
branch for review:
https://github.com/habari/system/commit/e460d551657ff1c6bc60ae895faa292101ecf01b

Please note that in this code the "internal" filter is something already
used by the publishing form to obtain the raw, unfiltered value out of a
Post field when using __get().

Owen

Matt Read

unread,
Apr 11, 2013, 3:42:59 PM4/11/13
to habar...@googlegroups.com
On 11/04/2013 3:18 PM, Owen Winkler wrote:
> This is an interesting topic. I'd love for the functionality to be
> mostly transparent to themes, such that you'd never directly access
> $post->cached_content, simply continue to use $post->content or
> $post->content_out like always.
>
> I don't think that the cached_content field should work like a
> traditional time-expiry cache. The typical use case is much less
> complex than what would be required to support time-based cache
> expiry. Plugins that wanted to attempt this could still do so, but
> I'm not personally sure of the value.
>
> I suggest adding a "post_prerender_content" filter that is executed
> when the cached_content value needs to be generated. This would
> usually be used in two places: One when the content is changed (so
> that the new value can be rendered and stored), and one when the
> cached_content field is empty (which would happen for existing content
> that had not been pre-rendered). Obviously, this would require a
> change in the plugins that offer filters that would be useful to
> pre-render.

I like the idea of this filter. In fact is solves my shorttags problem
as well. The markdown plugins et. al would just need to change to this
filter, while still allowing for dynamic content to render (like
shorttags or others).

This would also be useful for comment_content if it has a cached_content
field. Case in point, the at-comment-names plugin; with many comments it
EATS ALL THE MEMORIES! too much looping :(

> If you want to invalidate the cache, you just delete the value in the
> cache field.
>
> This idea could potentially be expensive if no content values are
> cached and all of the values need to be both pre-rendered AND stored.
> I've been considering a separate system that would queue object writes
> until after the buffer is flushed. This is already needed for object
> writes from FormUI forms, since each field is saved discretely. (For
> example, saving a Post would generate one UPDATE query for each field
> changed unless all of these individual writes were queued until the
> end of execution.)

The queue would work best, if possible.

>
> As to invalidating cache when plugins are added, this is done simply
> with "UPDATE posts SET cached_content = ''" whenever an event occurs
> that triggers a cache reset. I think, though, that executing this
> query (via some API method) should either be the prerogative of a
> plugin that implements the prerender filter, or (if we want to get
> super-fancy) Habari should detect when a plugin that uses the
> prerender filter is enabled/disabled and execute a cache reset at that
> time.

This could also lead to many plugins all "invalidating cache" at the
same time. Unless it was a trigger/filter to set a value to run it
later, like in your queue.
Reply all
Reply to author
Forward
0 new messages