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); }
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); }
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); }
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); }