Alec Thomas wrote:
> On 11/28/07, Alec Thomas <[EMAIL PROTECTED]> wrote:
>
>> On 11/28/07, Alec Thomas <[EMAIL PROTECTED]> wrote:
>>
>>> This is the area that we can improve. Try the attached patch, it caches
>>> the results of get_user_permissions() for up to 5 seconds, which should
>>> massively reduce the number of hits on the database.
>>>
>> Slightly cleaner patch attached.
>>
>
> Testing with an old sqlite copy of the Trac database, I see the
> following results:
>
> Before the patch:
>
> Permission checks on 2702 tickets took 1.29666638374 seconds
>
> After the patch:
>
> Permission checks on 2702 tickets took 0.19308590889 seconds
>
Well, that would do for the default permission policy. There should be
at least some additional cleanup done at a larger interval to clear the
whole cache, so that it doesn't explode over time if the server stays
alive for long periods of time.
New version of the patch attached.
-- Christian
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Trac
Development" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/trac-dev?hl=en
-~----------~----~----~----~------~----~------~--~---
Index: trac/perm.py
===================================================================
--- trac/perm.py (revision 6242)
+++ trac/perm.py (working copy)
@@ -18,6 +18,7 @@
"""Management of permissions."""
+from time import time
from trac.config import ExtensionOption, OrderedExtensionsOption
from trac.core import *
from trac.resource import Resource, get_resource_name
@@ -254,13 +255,36 @@
implements(IPermissionPolicy)
+ CACHE_EXPIRY = 60 # Number of seconds before clearing the whole cache
+ USER_CACHE_EXPIRY = 5 # Number of seconds before reloading user permissions
+
+ def __init__(self):
+ self.permission_cache = {}
+
# IPermissionPolicy methods
def check_permission(self, action, username, resource, perm):
- return PermissionSystem(self.env). \
- get_user_permissions(username).get(action, None)
+ now = time()
+ timestamp = self.permission_cache.get(None, 0)
+ # Prevent an ever growing cache
+ if now - timestamp > self.CACHE_EXPIRY:
+ self.log.debug("Clearing the in-memory permission cache")
+ self.permission_cache.clear()
+ self.permission_cache[None] = now
+ # Cache hit?
+ timestamp, permissions = self.permission_cache.get(username, (0, None))
+ if now - timestamp > self.USER_CACHE_EXPIRY:
+ self.log.debug("Fetching permissions for %s from DB." % username)
+ permissions = PermissionSystem(self.env). \
+ get_user_permissions(username)
+ self.permission_cache[username] = (now, permissions)
+
+ return action in permissions
+
+
+
class PermissionSystem(Component):
"""Sub-system that manages user permissions."""