With 54 projects, a ridiculous amount of ming & mongo calls are executed on a profile page:
{
"url": "/u/brondsem/profile/",
"uptime": 1820,
"call_counts": {
"socket_write": 1,
"jinja": 1,
"mongo": 30396,
"total": 1,
"socket_read": 14,
"ming": 1102
},
"request_category": "profile",
"timings": {
"mongo": 2618,
"ming": 1328,
"socket_write": 0,
"socket_read": 93,
"total": 4528,
"jinja": 4478
}
}
If we end up needing a data structure to cache this, we may want to plan ahead for the possibility of sorting by project activity, registration date, etc.
Originally by: kharechko
Hi. I have tried to reproduce the bug. Have created 50+ empty projects. Ping /u/root/profile/ but my numbers much less then yours:
{"url": "/u/root/profile/", "uptime": 6, "call_counts": {"total": 1, "ming": 572, "jinja": 1, "mongo": 505}, "request_category": "profile", "timings": {"total": 1275, "ming": 342, "jinja": 991, "mongo": 178}}can you give more details? I am interested in type of queries to mongo. can you give me mongo profiling information?
Here's updated profile data. I know we've made some tweaks recently to how the ming & mongo methods are counted to make them more accurate. I think the ming call counts are still about 2x actual so that timing is accurate. (That is, 2 ming methods for every 1 query).
{"url": "/u/brondsem/profile/", "uptime": 482, "call_counts": {"total": 1, "sqlalchemy": 1, "ming": 1155, "jinja": 1, "mongo": 1993}, "request_category": "profile", "timings": {"total": 2787, "sqlalchemy": 2, "ming": 923, "jinja": 2698, "mongo": 1439}}}So those are closer to what you got, but still higher. This is from our production system so it'll take me some time to get more detailed data.
Originally by: kharechko
Please look to Allura/allura/ext/user_profile/templates/user_index.html
If user.my_projects() called, is it really necessary to check "if h.has_access(p, 'read')()". I have tried to removed this condition and number of mongo calls have decreased twice.
with "if h.has_access(p, 'read')()":
> db.system.profile.find({ns: 'allura.project_role'}).sort( { ts : -1 }).count() 176 > db.system.profile.find().sort( { ts : -1 }).count() 263without "if h.has_access(p, 'read')()":
> db.system.profile.find({ns: 'allura.project_role'}).sort( { ts : -1 }).count() 66 > db.system.profile.find().sort( { ts : -1 }).count() 157 [stats] {"url": "/u/root/profile", "uptime": 15, "call_counts": {"total": 1, "ming": 510, "jinja": 1, "mongo": 348}, "request_category": "profile", "timings": {"total": 1300, "ming": 345, "jinja": 996, "mongo": 129}} >Last edit: Anonymous 2015-06-28
Closed #499.
je/42cc_6677Removed
has_accesscall, as Mykola described earlier. I don't think we need that, sincemy_projects()returns project for which user has a named role, and I doubt that named roles without read permissions is useful.If I'm wrong, and we do need that check, we still could reduce mongo call count implementing this check inside
my_projects(), I think.Implemented fix cuts mongo calls count in half. If that's not enough we'll need mongo profiling information (as Mykola mentioned above) to investigate further.
git blameon that line points to 4818583b and [#2235], which explains why that check is important: a project that has restricted 'read' access shouldn't be shown to a user (or anonymous visitor) that doesn't have that permission.Related
Tickets:
#2235Closed #512. Force-pushed
je/42cc_6677This change drops mongo call_counts from 376 to 74 on my test project. I don't sure about
my_projectspersmission checks, though. Look at it carefully, please.Historically, a
ProjectRolewith an emptyroleslist was automatically created for a user when they viewed any given project. We've since optimized that to only upsert when explicitly needed, but just because there exists aProjectRolefor a givenUser/Projectcombination doesn't mean that user actually has any access to the project. Also, there could be noProjectRolefor a given user, but the project could allow*anonymousread, in which case it should be shown to the user.We could check to see if
c.user == selfto skip thehas_accesschecks, but in most cases we're still going to need to callhas_access. :-/The optimization to pull in all
Projects at once instead of usingrole.projectis good, and should be extended tomy_projects_by_role_name. Also, since that is now a separate method to avoid the extra queries needed by the reaching logic, please also make the parameter non-optional.Closed #532. Force-pushed
je/42cc_6677