Esempio n. 1
0
        public async Task <T> GetEntryFromCache <T>(string endpoint, string identifier, GetLiveEndpointResultDelegate <T> cacheSetCall, DateTimeOffset cacheExpiration, CacheDurationType cacheDurationType = CacheDurationType.Absolute, bool persistInMemory = true, bool persistOnDisk = false) where T : class
        {
            // Check memory cache first
            var responseItem = persistInMemory ? Get(identifier, endpoint) as T : null;

            // If not in memory cache, check file system cache
            if (responseItem == null)
            {
                responseItem = persistOnDisk ? await GetFromFsCache(endpoint, identifier, cacheSetCall, cacheExpiration, cacheDurationType) : null;

                if (responseItem == null)
                {
                    return(await cacheSetCall.Invoke(identifier, endpoint));
                }

                if (persistInMemory)
                {
                    var policy = new CacheItemPolicy();

                    if (cacheDurationType == CacheDurationType.Absolute)
                    {
                        policy.AbsoluteExpiration = cacheExpiration;
                    }
                    else if (cacheDurationType == CacheDurationType.Sliding)
                    {
                        policy.SlidingExpiration = cacheExpiration.Offset;
                    }

                    base.Set(GetCacheItemFqn(identifier, endpoint), responseItem, policy);
                }
            }

            return(responseItem);
        }
Esempio n. 2
0
        public async Task <T> GetFromFsCache <T>(string endpoint, string identifier, GetLiveEndpointResultDelegate <T> cacheSetCall, DateTimeOffset cacheExpiration, CacheDurationType cacheDurationType = CacheDurationType.Absolute) where T : class
        {
            string niceEndpointName = GetEndpointNiceName(endpoint);

            // Cache it to the file system, if that's enabled or available
            if (cacheExpiration.Offset.TotalSeconds > 0 && !string.IsNullOrEmpty(niceEndpointName) && !string.IsNullOrEmpty(this.CacheDirectory))
            {
                string endpointCacheRoot = $"{niceEndpointName}{CACHE_ENDPOINT_EXTENSION}";

                // TODO: For now while we aren't updating fs cache in this function
                if (!File.Exists(Path.Combine(this.CacheDirectory, endpointCacheRoot)))
                {
                    return(null);
                }

                using (var endpointFileStream = new FileStream(Path.Combine(this.CacheDirectory, endpointCacheRoot), FileMode.Open)) {
                    using (var endpointArchive = new ZipArchive(endpointFileStream, ZipArchiveMode.Update)) {
                        string entryName = identifier + CACHE_ENTRY_EXTENSION;

                        var entryFind = endpointArchive.GetEntry(entryName);

                        // Where we will store the result
                        T result;

                        if (entryFind == null || entryFind.LastWriteTime.Subtract(DateTime.Now) > cacheExpiration.Offset)
                        {
                            entryFind?.Delete();

                            result = await cacheSetCall.Invoke(identifier, endpoint);

                            // TODO: Instead of doing this now, queue it and do them all at once to avoid IO errors
                            // Add new cache entry into zip
                            //entryFind = endpointArchive.CreateEntry(entryName, CompressionLevel.Fastest);

                            //using (var entryStream = entryFind.Open()) {
                            //    ProtoBuf.Serializer.Serialize(entryStream, result);
                            //}
                        }
                        else
                        {
                            result = ProtoBuf.Serializer.Deserialize <T>(entryFind.Open());

                            // If cache duration mode is sliding, then touch the timestamp to update it from this access
                            if (cacheDurationType == CacheDurationType.Sliding)
                            {
                                entryFind.LastWriteTime = DateTimeOffset.Now;
                            }
                        }

                        return(result);
                    }
                }
            }

            return(null);
        }