Exemplo n.º 1
0
 public async Task Set <T>(string key, T item, CancellationToken cancel) where T : class, new()
 {
     var    cachedItem      = new CachedItem <T>(item);
     string serializeObject = Serialize(cachedItem);
     await multilayerCache.SetAsync(
         key,
         Encoding.UTF8.GetBytes(serializeObject),
         cancel);
 }
Exemplo n.º 2
0
        public T GetOrUpdate <T>(string key, Func <DateTimeOffset> getLastModificationTime, Func <T> getItem, CancellationToken cancel = default) where T : class, new()
        {
            logger.LogInformation($"get cached item, key={key}");
            var            value = multilayerCache.Get(key);
            CachedItem <T> cachedItem;

            T RefreshItem()
            {
                var item = getItem();

                cachedItem = new CachedItem <T>(item);
                string serializeObject = Serialize(cachedItem);

                value = Encoding.UTF8.GetBytes(serializeObject);
                Task.Run(() => multilayerCache.Set(key, value, cacheEntryOptions));
                return(item);
            }

            if (value == null)
            {
                appTelemetry.RecordMetric("cache-miss", 1, ("key", key));
                return(RefreshItem());
            }

            var json = Encoding.UTF8.GetString(value);

            cachedItem = JsonConvert.DeserializeObject <CachedItem <T> >(json);
            var needRefresh = false;

            if (cachedItem.CreatedOn.Add(settings.TimeToLive) < DateTimeOffset.UtcNow)
            {
                appTelemetry.RecordMetric("cache-expired", 1, ("key", key));
                needRefresh = true;
            }
            else
            {
                var lastUpdateTime = getLastModificationTime();
                if (lastUpdateTime != default && lastUpdateTime > cachedItem.CreatedOn)
                {
                    needRefresh = true;
                }
            }

            if (needRefresh)
            {
                // ReSharper disable once MethodSupportsCancellation
                Task.Factory.StartNew(RefreshItem, TaskCreationOptions.LongRunning);
            }

            return(cachedItem.Value);
        }
Exemplo n.º 3
0
        private string Serialize <T>(CachedItem <T> cachedItem) where T : class, new()
        {
            var tempFile = Path.GetTempFileName();

            if (File.Exists(tempFile))
            {
                File.Delete(tempFile);
            }

            using (var stream = File.OpenWrite(tempFile))
            {
                using (var writer = new StreamWriter(stream))
                {
                    using (var jsonWriter = new JsonTextWriter(writer))
                    {
                        var serializer = new JsonSerializer
                        {
                            Formatting                 = Formatting.None,
                            MaxDepth                   = 3,
                            ReferenceLoopHandling      = ReferenceLoopHandling.Ignore,
                            PreserveReferencesHandling = PreserveReferencesHandling.Objects,
                            NullValueHandling          = NullValueHandling.Ignore
                        };
                        serializer.Serialize(jsonWriter, cachedItem);
                        jsonWriter.Flush();
                    }
                }
            }

            var serializedString = File.ReadAllText(tempFile);

            if (File.Exists(tempFile))
            {
                File.Delete(tempFile);
            }

            return(serializedString);
        }
Exemplo n.º 4
0
        public async Task <T> GetOrUpdateAsync <T>(
            string key,
            Func <Task <DateTimeOffset> > getLastModificationTime,
            Func <Task <T> > getItem,
            CancellationToken cancel) where T : class, new()
        {
            logger.LogInformation($"get cached item, key={key}");
            var value = await multilayerCache.GetAsync(key, cancel);

            CachedItem <T> cachedItem;

            async Task <T> RefreshItem()
            {
                var item = await getItem();

                cachedItem = new CachedItem <T>(item);
                string serializeObject = Serialize(cachedItem);

                value = Encoding.UTF8.GetBytes(serializeObject);
                logger.LogInformation($"updating cache {key}...");
#pragma warning disable 4014
                // ReSharper disable once MethodSupportsCancellation
                multilayerCache.SetAsync(key, value, cacheEntryOptions);
#pragma warning restore 4014
                return(item);
            }

            if (value == null)
            {
                appTelemetry.RecordMetric("cache-miss", 1, ("key", key));
                return(await RefreshItem());
            }

            var json = Encoding.UTF8.GetString(value);
            cachedItem = JsonConvert.DeserializeObject <CachedItem <T> >(json);
            var needRefresh = false;
            if (cachedItem.CreatedOn.Add(settings.TimeToLive) < DateTimeOffset.UtcNow)
            {
                appTelemetry.RecordMetric("cache-expired", 1, ("key", key));
                needRefresh = true;
            }
            else
            {
                var lastUpdateTime = await getLastModificationTime();

                if (lastUpdateTime != default && lastUpdateTime > cachedItem.CreatedOn)
                {
                    needRefresh = true;
                }
            }

            if (needRefresh)
            {
#pragma warning disable 4014
                // ReSharper disable once MethodSupportsCancellation
                Task.Factory.StartNew(RefreshItem);
#pragma warning restore 4014
            }

            return(cachedItem.Value);
        }