There are lot of duplicate ming queries for a threaded discussion. The following is logged by timermiddleware, when viewing a ticket page that had 2 comments by admin1, when logged in as admin1.
get args=(<class 'allura.model.auth.User'>, ObjectId('4fbc01a69c104009d2000407')) kwargs={} find args=(<class 'allura.model.project.Project'>, {'deleted': False, 'shortname': u'u/admin1'}) kwargs={}... find args=(<class 'allura.model.project.Project'>, {'deleted': False, 'shortname': u'u/admin1'}) kwargs={}... find args=(<class 'allura.model.project.ProjectFile'>, {'category': 'icon', 'project_id': ObjectId('4fbc01a69c104009d2000408')}) kwargs={}... find args=(<class 'allura.model.project.Project'>, {'deleted': False, 'shortname': u'u/admin1'}) kwargs={}... find args=(<class 'allura.model.project.Project'>, {'deleted': False, 'shortname': u'u/admin1'}) kwargs={}... find args=(<class 'allura.model.project.ProjectFile'>, {'category': 'icon', 'project_id': ObjectId('4fbc01a69c104009d2000408')}) kwargs={}... get args=(<class 'allura.model.auth.User'>, ObjectId('4fbc01a69c104009d2000407')) kwargs={} get args=(<class 'allura.model.auth.User'>, ObjectId('4fbc01a69c104009d2000407')) kwargs={} get args=(<class 'allura.model.index.ArtifactReference'>, u'allura/model/discuss/Post#6f62e5c2eec5ff46a51fb65a4d91efcba41b1aaf/tickets@testall/p/sourceforge/net') kwargs={}... find args=(<class 'allura.model.index.ArtifactReference'>, {'references': u'allura/model/discuss/Post#6f62e5c2eec5ff46a51fb65a4d91efcba41b1aaf/tickets@testall/p/sourceforge/net'}) kwargs={}... get args=(<class 'allura.model.discuss.Thread'>, u'f0cd42a4') kwargs={} get args=(<class 'allura.model.discuss.Discussion'>, ObjectId('4fbc059b9c104012b2000030')) kwargs={} get args=(<class 'allura.model.project.AppConfig'>, ObjectId('4fbc059b9c104012b200002e')) kwargs={} get args=(<class 'allura.model.project.AppConfig'>, ObjectId('4fbc059b9c104012b200002e')) kwargs={} find args=(<class 'allura.model.discuss.DiscussionAttachment'>, {'post_id': u'6f62e5c2eec5ff46a51fb65a4d91efcba41b1aaf.tickets@testall.p.sourceforge.net', 'type': 'attachment'}) kwargs={}... get args=(<class 'allura.model.auth.User'>, None) kwargs={} get args=(<class 'allura.model.index.ArtifactReference'>, u'forgetracker/model/ticket/Ticket#4fbd3f079c1040225a000002') kwargs={}... get args=(<class 'allura.model.project.Project'>, ObjectId('4fbc059b9c104012b2000000')) kwargs={} find args=(<class 'allura.model.project.AppConfig'>, {'options.mount_point': None, 'project_id': ObjectId('4fbc059b9c104012b2000000')}) kwargs={}... get args=(<class 'forgetracker.model.ticket.Ticket'>, ObjectId('4fbd3f079c1040225a000002')) kwargs={} get args=(<class 'allura.model.discuss.Post'>, None) kwargs={} get args=(<class 'allura.model.auth.User'>, ObjectId('4fbc01a69c104009d2000407')) kwargs={} find args=(<class 'allura.model.project.Project'>, {'deleted': False, 'shortname': u'u/admin1'}) kwargs={}... find args=(<class 'allura.model.project.Project'>, {'deleted': False, 'shortname': u'u/admin1'}) kwargs={}... find args=(<class 'allura.model.project.ProjectFile'>, {'category': 'icon', 'project_id': ObjectId('4fbc01a69c104009d2000408')}) kwargs={}... find args=(<class 'allura.model.project.Project'>, {'deleted': False, 'shortname': u'u/admin1'}) kwargs={}... find args=(<class 'allura.model.project.Project'>, {'deleted': False, 'shortname': u'u/admin1'}) kwargs={}...
The user-icon portions of these queries have been addressed; those are cached as of [9667df]
Allura/allura/model/discuss.py:find_posts:
short circuit if self.posts is already present and avoid requerying
artifactreference bulk preload and cache
this was the biggest; each post has to check for backreferenced artifacts before checking for related artifacts. bulk querying for all these and caching them as instance attrs allows
us to skip all the individual checks
ForgeDiscussion/forgediscussion/model/forum.py:ForumThread.subscribed
it's super() call was memoized, but this invocation wasn't
memoize Allura/allura/model/notification.py:Mailbox.subscribed
i believe this shaved one ming call off; not much but can't hurt
edit post HTML isn't present when not logged in, so nothing to be done there
there still seem to be more Project fetches than should be needed, but didn't really find a good way to identify truly unnecessary ones or reduce those
final counts - 6 total posts, 2 top level, 1 related artifact and one backrefd
before: mongo": 172, "ming": 104,
after: mongo": 135, "ming": 84,
find_posts
- self.posts is aRelationProperty('Post', via='thread_id')
which seems like it'd always exist and contain all associated posts. And not be using the page, limit, timestamp, style params? Test failure maybe related:allura.lib.widgets.discuss:Thread
i think is the widget used on all of themdef prepare_context
is a main lifecycle method on widgets, can the bulk load happen there?def subscribed
using@memoize
self
param anduser_id
param its going to be a really big forever cache. Maybe ok though since we're already doing it in a very similar place.@classmethod
?def related_artifacts
callingself.refs
(probably 1 extra query for the thread itself)New call counts are: "ming": 85, "mongo": 135.