Hooking into the postbit, without multiple db queries?

Jaxel

Well-known member
I'm trying to write an add-on which has postbit widgets, like medals. the widget information is stored in a database table and tend to reference specific usergroups. On a postbit call, it will query the database for all the medals, and recursively check to see if that user is a member of that medals usergroup. this all works well...

the problem comes in because the postbit is called 25 times on a page, once per post. and then if course the hook queries the database 25 times for medals. it's there a way to get around this issue?
 
I'm trying to write an add-on which has postbit widgets, like medals. the widget information is stored in a database table and tend to reference specific usergroups. On a postbit call, it will query the database for all the medals, and recursively check to see if that user is a member of that medals usergroup. this all works well...

the problem comes in because the postbit is called 25 times on a page, once per post. and then if course the hook queries the database 25 times for medals. it's there a way to get around this issue?
You can use DataRegistry or SimpleCache to do as much caching as possible, and then when the medel status updates, update the cache entry as well. An alternative is the Zend Caching mechanisms which has a tagging feature so that you can massively CRUD all cache entries, but I have yet to find an entrypoint in XenForo.

Codes you need to write:
1. Hook into initDependencies for first-time caching
2. In DataWriter, override postSave (and postDelete) to regenerate cache
3. In templateHook, grab the cache again and do the check.

In this case, I think you want to cache the criterias.
 
Hmm... I see your mod "Usergroup Ranks" is very similar to what I wanted to do... but you're not caching your "getAllActiveUserGroupRanks" query... doesn't this add 20-25 queries to every page load?
 
Hook preparePostJoinOptions on model_post and add in any subqueries/joins you need. The usergroup check might be difficult/impossible as a subquery though, in that case things get hairy and you would need to look at involving some good old fashioned global variables - gather a list of user ids using preparePost, query for all of them at once in your template hook and store the result (optionally in a cache), then use this result each time you render. And there might be a better way of doing it, I'm not thinking too clearly atm :p
 
Hmm... I see your mod "Usergroup Ranks" is very similar to what I wanted to do... but you're not caching your "getAllActiveUserGroupRanks" query... doesn't this add 20-25 queries to every page load?
I haven't pushed my updated code yet. If you want to see some code in action I can push them in a few hours, on the road ATM.
 
I confirm the DataRegistry & SimpleCache are working great and are really easy to use (see the links).


I'm curious to know more about it, could you please keep us inform?
Just got back from home, did some reading. It was returning false because my local dev copy has no caching mechanism, so I set up a caching method, and XenForo_Application::get('cache') now returns Zend_Cache_Core properly.

I'll definitely experiment with this class because the tag feature makes it very suitable for massive cache storing, especially pre-rendered HTML.
 
I confirm the DataRegistry & SimpleCache are working great and are really easy to use (see the links).


I'm curious to know more about it, could you please keep us inform?
(Not sure if alerts are resent when editing posts, so please excuse me for my triple post...)

It looks like the DataRegistry mirrors the data to the database and to the caching mechanism, however DataRegistry doesn't support tags. I'll include an extended version of DataRegistry in my next update of my addon so it supports tags.

(I should also stop hijacking somebody else's thread already...)
 
Top Bottom