[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
3856.03.patch.
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
above.
- 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