[buddypress-trac] [BuddyPress Trac] #3856: Saving activity update action as an array in db

buddypress-trac noreply at wordpress.org
Wed Mar 5 03:35:35 UTC 2014

#3856: Saving activity update action as an array in db
 Reporter:  modemlooper            |       Owner:
     Type:  enhancement            |      Status:  new
 Priority:  normal                 |   Milestone:  2.0
Component:  Activity               |     Version:
 Severity:  normal                 |  Resolution:
 Keywords:  has-patch 2nd-opinion  |

Comment (by boonebgorges):

 imath - Thanks for the feedback. Your comments got me thinking.

 My original idea was to store 'action_data' for each activity item, which
 would then be used at runtime to generate the action strings. This is very
 inelegant, however. The structure of the action_data is always going to be
 different. It's often going to mean storing the same content in the
 activitymeta table over and over and over again (like
 'http://example.com/members/boone'). And it reproduces the problem that
 our current technique has with stale content: when someone changes (eg)
 their username, the activity action doesn't change.

 So, I decided that this was the right time to go for a broader fix. See

 Here's my basic strategy: Not only are strings concatenated at runtime,
 but the data for the strings is also fetched at runtime. The original
 argument against this was performance. But, using some of the caching
 improvements that have gone into trunk during this cycle, I've been able
 to mitigate these performance issues almost completely.

 After activity items are pulled up in `BP_Activity_Activity::get()`, the
 results are run through a filter 'bp_activity_prefetch_object_data'.
 Components then use this hook to loop the activity items to find those
 that "belong" to the component, to identify the associated object, and
 then to prime the cache for that set of objects. So, for example, the
 groups component looks over the activity stream, and for each item with
 'component=groups', it keeps track of the 'item_id' (which is the group
 id). It then does a single query to populate the cache with data related
 to these groups. Then, the _format_activity_action_ callback functions
 (like `bp_groups_format_activity_action_created_group()`) use the regular
 functions like `bp_get_group_permalink()` to create the necessary action
 string, with no performance implications.

 The one place where this kind of pre-fetching is not feasible is with the
 blogs component when running Multisite - there's no way to optimize a
 query that has to `switch_to_blog()` a dozen times. So, in the case of
 new_blog, new_blog_post, and new_blog_comment, I've gone with a variation
 on my original 'action_data' plan. For blog_url and blog_name, which will
 obviously remain the same between activity items related to the same blog,
 I'm using data from bp_blogs_get_blogmeta(). For post_url and post_name,
 I'm creating custom *activitymeta* items. (You'll notice that there are a
 couple of ancillary mods to the blogs component to make this all
 possible.) It's not ideal, but it's not any worse than what we currently
 do, and it performs snappily.

 The other complication is maintaining backward compatibility for the old
 'activity_action' filters. Where possible, I've kept them intact. In some
 cases, the filter is expecting an argument that I don't have easy access
 to - like the `$post` object after a new blog post. To keep overhead to a
 minimum in these cases, I check `has_filter()` before fetching the
 necessary data. My guess is that very, very few people are using these
 filters, but this'll keep it working for those who are, and doesn't cause
 any harm (aside from a few extra lines of code) to those who aren't.

 I've written a whole stack of unit tests, as you can see, but this could
 use some more eyeballs. In particular:

 - Devs: Please let me know what you think of the techniques I've described
 - Everyone: Please test with all sorts of different activity items,
 plugins, etc. It should degrade nicely in cases where components are
 deactivated, where plugins aren't using the new callbacks, etc, but this
 could all use some checking.

Ticket URL: <https://buddypress.trac.wordpress.org/ticket/3856#comment:20>
BuddyPress Trac <http://buddypress.org/>
BuddyPress Trac

More information about the buddypress-trac mailing list