/// <inheritdoc/> public void Upsert <T>(VersionedDataKind <T> kind, T item) where T : IVersionedData { Exception failure = null; IVersionedData newState = item; try { newState = _core.UpsertInternal(kind, item); } catch (Exception e) { // Normally, if the underlying store failed to do the update, we do not want to update the cache - // the idea being that it's better to stay in a consistent state of having old data than to act // like we have new data but then suddenly fall back to old data when the cache expires. However, // if the cache TTL is infinite, then it makes sense to update the cache always. if (!_caching.IsInfiniteTtl) { throw; } failure = e; } if (_itemCache != null) { _itemCache.Set(new CacheKey(kind, item.Key), newState); } if (_allCache != null) { // If the cache has a finite TTL, then we should remove the "all items" cache entry to force // a reread the next time All is called. However, if it's an infinite TTL, we need to just // update the item within the existing "all items" entry (since we want things to still work // even if the underlying store is unavailable). if (_caching.IsInfiniteTtl) { try { var cachedAll = _allCache.Get(kind); _allCache.Set(kind, cachedAll.SetItem(item.Key, newState)); } catch (Exception) { } // An exception here means that we did not have a cached value for All, so it tried to query // the underlying store, which failed (not surprisingly since it just failed a moment ago // when we tried to do an update). This should not happen in infinite-cache mode, but if it // does happen, there isn't really anything we can do. } else { _allCache.Remove(kind); } } if (failure != null) { throw failure; } }
/// <summary> /// <see cref="IFeatureStore.Upsert"/> /// </summary> public void Upsert <T>(VersionedDataKind <T> kind, T item) where T : IVersionedData { IVersionedData newState = _core.UpsertInternal(kind, item); if (_itemCache != null) { _itemCache.Set(new CacheKey(kind, item.Key), newState); } if (_allCache != null) { _allCache.Remove(kind); } }