[Rt-devel] [PATCH] More ACL checks from cache
Jesse Vincent
jesse at bestpractical.com
Thu Apr 20 16:47:36 EDT 2006
On Fri, Apr 21, 2006 at 12:44:33AM +0400, Ruslan Zakirov wrote:
> Hello.
> Here is patch that cut number of the queries we run on the DB by using
> cache more aggressivly.
Any basic stats on how effective this is? I think I'm most comfortable
starting with this in 3.7, since 3.6 is so close to going out the door.
I know it's pedantic, but can this get turned into something that reads
a little easier to someone poking at the code?
(also $big_hashkey doesn't tell me what it's for, just that it's large
;)
> + $_ACL_CACHE->set( $big_hashkey => $hitcount? 1:-1 );
> It's against 3.4.5
>
> --
> Best regards, Ruslan.
> === lib/RT/Principal_Overlay.pm
> ==================================================================
> --- lib/RT/Principal_Overlay.pm (revision 2396)
> +++ lib/RT/Principal_Overlay.pm (local)
> @@ -328,47 +328,40 @@
> # this is a little bit hacky, but basically, now that we've done
> # the ticket roles magic, we load the queue object
> # and ask all the rest of our questions about the queue.
> - push( @{ $args{'EquivObjects'} }, $args{'Object'}->QueueObj );
> + unshift @{ $args{'EquivObjects'} }, $args{'Object'}->QueueObj;
>
> }
>
> - # {{{ If we've cached a win or loss for this lookup say so
> + unshift @{ $args{'EquivObjects'} }, $RT::System
> + unless $self->can('_IsOverrideGlobalACL')
> + && $self->_IsOverrideGlobalACL( $args{'Object'} );
>
> - # {{{ Construct a hashkey to cache decisions in
> - my $hashkey = do {
> - no warnings 'uninitialized';
>
> - # We don't worry about the hash ordering, as this is only
> - # temporarily used; also if the key changes it would be
> - # invalidated anyway.
> - join(
> - ";:;",
> - $self->Id,
> - map {
> - $_, # the key of each arguments
> - ( $_ eq 'EquivObjects' ) # for object arrayref...
> - ? map( _ReferenceId($_), @{ $args{$_} } ) # calculate each
> - : _ReferenceId( $args{$_} ) # otherwise just the value
> - } keys %args
> - );
> - };
> + # {{{ If we've cached a win or loss for this lookup say so
>
> - # }}}
> + # Construct a hashkeys to cache decisions in
> + my $self_id = $self->id;
> + my $big_hashkey = join ";:;", $self_id, $args{'Right'};
> + foreach ( @{ $args{'EquivObjects'} } ) {
> + my $ref_id = _ReferenceId($_);
> + $big_hashkey .= ";:;$ref_id";
>
> - # Returns undef on cache miss
> - my $cached_answer = $_ACL_CACHE->fetch($hashkey);
> - if ( defined $cached_answer ) {
> - if ( $cached_answer == 1 ) {
> - return (1);
> - }
> - elsif ( $cached_answer == -1 ) {
> - return (undef);
> - }
> + my $hashkey = join ";:;", $self_id, $args{'Right'}, $ref_id;
> + my $cached_answer = $_ACL_CACHE->fetch($hashkey);
> + return $cached_answer > 0 if defined $cached_answer;
> }
>
> - my $hitcount = $self->_HasRight( %args );
> + {
> + my $cached_answer = $_ACL_CACHE->fetch($big_hashkey);
> + return $cached_answer > 0 if defined $cached_answer;
> + }
>
> - $_ACL_CACHE->set( $hashkey => $hitcount? 1:-1 );
> +
> + my ($hitcount, $via_obj) = $self->_HasRight( %args );
> +
> + $_ACL_CACHE->set( $big_hashkey => $hitcount? 1:-1 );
> + $_ACL_CACHE->set( "$self_id;:;$args{'Right'};:;$via_obj" => $hitcount? 1:-1 ) if $via_obj;
> +
> return ($hitcount);
> }
>
> @@ -393,10 +386,6 @@
>
> # If an object is defined, we want to look at rights for that object
>
> - push( @objects, 'RT::System' )
> - unless $self->can('_IsOverrideGlobalACL')
> - && $self->_IsOverrideGlobalACL( $args{Object} );
> -
> my ($check_roles, $check_objects) = ('','');
> if( @objects ) {
> my @role_clauses;
> @@ -423,10 +412,11 @@
> }
>
> my $query_base =
> - "SELECT ACL.id from ACL, Groups, Principals, CachedGroupMembers WHERE " .
> + "SELECT ACL.id, ACL.ObjectType, ACL.ObjectId " .
> + "FROM ACL, Groups, Principals, CachedGroupMembers WHERE " .
>
> # Only find superuser or rights with the name $right
> - "(ACL.RightName = 'SuperUser' OR ACL.RightName = '$right') "
> + "(ACL.RightName = 'SuperUser' OR ACL.RightName = '$right') "
>
> # Never find disabled groups.
> . "AND Principals.Disabled = 0 "
> @@ -454,18 +444,25 @@
> . "AND ACL.PrincipalId = Principals.id "
> . "AND ACL.PrincipalType = 'Group' ";
>
> - $self->_Handle->ApplyLimits( \$groups_query, 1 ); #only return one result
> - my $hitcount = $self->_Handle->FetchResult($groups_query);
> - return 1 if $hitcount; # get out of here if success
> + {
> + # fetch only first result
> + $self->_Handle->ApplyLimits( \$groups_query, 1 );
> + my ($hitcount, $obj, $id) = $self->_Handle->FetchResult($groups_query);
> + $obj = "$obj-$id" if $id;
> + return (1, $obj) if $hitcount; # get out of here if success
> + }
>
> # The roles query does the query based on roles
> my $roles_query = $query_base
> . "AND ACL.PrincipalType = Groups.Type "
> . "AND ($check_roles) ";
> - $self->_Handle->ApplyLimits( \$roles_query, 1 ); #only return one result
>
> - $hitcount = $self->_Handle->FetchResult($roles_query);
> - return 1 if $hitcount; # get out of here if success
> + {
> + # fetch only first result
> + $self->_Handle->ApplyLimits( \$roles_query, 1 );
> + my ($hitcount, $obj, $id) = $self->_Handle->FetchResult($roles_query);
> + return (1) if $hitcount; # get out of here if success
> + }
>
> return 0;
> }
> _______________________________________________
> List info: http://lists.bestpractical.com/cgi-bin/mailman/listinfo/rt-devel
>
> Best Practical is hiring! Come hack Perl for us: http://bestpractical.com/about/jobs.html
--
More information about the Rt-devel
mailing list