Beispiel #1
0
        /// <summary>
        /// Try to get the value from cache, with logging.
        /// </summary>
        private bool TryGetOrAdd(CachingQueryRunnerKey key, MessageContext msg, out CachingQueryRunnerValue result, Func <CachingQueryRunnerKey, CachingQueryRunnerValue> valueFactory)
        {
            bool foundValue;

            foundValue = Cache.TryGetOrAdd(key, out result, valueFactory);

            msg.Append(() => "CachingQueryRunner key:" + key);
            if (foundValue)
            {
                var cacheValue = result;
                msg.Append(() => "CachingQueryRunner cache hit");
                msg.Append(() => $"Entry originally cached at {cacheValue.CacheTime}");
            }
            else
            {
                msg.Append(() => "CachingQueryRunner cache miss");
            }

            return(foundValue);
        }
Beispiel #2
0
        /// <summary>
        /// Create cache keys
        /// </summary>
        /// <param name="query">The query</param>
        /// <param name="settings">The query settings</param>
        /// <param name="perUserKey">True if the key is for a specific user; or false if it is to be shared across users.</param>
        /// <returns>The cache key</returns>
        private CachingQueryRunnerKey CreateCacheKeyImpl(StructuredQuery query, QuerySettings settings, bool perUserKey)
        {
            // Get a user-set key
            // (Users may share the same report SQL if they have the same set of read-rules)
            UserRuleSet userRuleSet = null;

            if (settings.RunAsUser != 0)
            {
                userRuleSet = UserRuleSetProvider.GetUserRuleSet(settings.RunAsUser, Permissions.Read);
                if (userRuleSet == null)
                {
                    throw new InvalidOperationException("Expected userRuleSet");   // Assert false
                }
            }

            // Create cache key
            // Cached with userId = -1 if the user
            long userId = perUserKey ? settings.RunAsUser : ShareAcrossUsersCacheKey;
            var  key    = new CachingQueryRunnerKey(query, settings, userRuleSet, userId);

            return(key);
        }
Beispiel #3
0
        /// <summary>
        /// Returns a suitable key for comparing query runs.
        /// </summary>
        /// <returns>A key, or null if the query should not be cached.</returns>
        private CachingQueryRunnerKey CreateCacheKeyAndQuery(StructuredQuery query, QuerySettings settings, out QueryBuild builtQuery)
        {
            // Build the SQL for the query
            // Note: unfortunately this may mutate the query, so keep a copy
            StructuredQuery queryCopy = query.DeepCopy( );

            builtQuery = BuildQueryImpl(queryCopy, settings);

            // Check if query can even participate in cache
            bool doNotCacheResult = builtQuery.SqlIsUncacheable ||
                                    builtQuery.DataIsUncacheable ||
                                    !CachingQueryRunnerKey.DoesRequestAllowForCaching(query, settings);

            if (doNotCacheResult)
            {
                return(null);
            }

            // If we get to this point, then the cache is definitely participating
            // Determine the cache key - either shared across users, or specific to the current user.
            CachingQueryRunnerKey key = CreateCacheKeyImpl(query, settings, builtQuery.DataReliesOnCurrentUser);

            return(key);
        }