1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Hooking into the postbit, without multiple db queries?

Discussion in 'XenForo Development Discussions' started by Jaxel, Mar 24, 2013.

  1. Jaxel

    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?
  2. tyteen4a03

    tyteen4a03 Well-Known Member

    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.
    cclaerhout likes this.
  3. Jaxel

    Jaxel Well-Known Member

    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?
  4. cclaerhout

    cclaerhout Well-Known Member

    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?
  5. tyteen4a03

    tyteen4a03 Well-Known Member

    XenForo loads Zend_Cache in XenForo_Application, but XenForo_Application::get('cache') seems to return null. It's strange since loadCache is a lazyLoader entry.

    Look up Zend_Cache_Core for more information.
    cclaerhout likes this.
  6. Luke F

    Luke F Well-Known Member

    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
    cclaerhout likes this.
  7. tyteen4a03

    tyteen4a03 Well-Known Member

    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.
  8. tyteen4a03

    tyteen4a03 Well-Known Member

    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.
  9. tyteen4a03

    tyteen4a03 Well-Known Member

    (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...)

Share This Page