/// <summary> /// Download data from an HTTP URL and insert the result into the /// cache. If the data is already in the cache, this returns /// a cached value. The URL itself is used as the key. /// </summary> /// <param name="url">The URL to download.</param> /// <param name="headers">An optional Dictionary containing the HTTP /// request headers.</param> /// <param name="fetchAlways">Force a web request to always be issued, skipping the cache.</param> /// <param name="absoluteExpiration">An optional expiration date.</param> /// <returns>The data downloaded from the URL.</returns> public IObservable<byte[]> DownloadUrl(IBlobCache This, string url, IDictionary<string, string> headers = null, bool fetchAlways = false, DateTimeOffset? absoluteExpiration = null) { var doFetch = new Func<IObservable<byte[]>>(() => MakeWebRequest(new Uri(url), headers).ToObservable()); if (fetchAlways) { return This.GetAndFetchLatest(url, doFetch, absoluteExpiration: absoluteExpiration).TakeLast(1); } else { return This.GetOrFetchObject(url, doFetch, absoluteExpiration); } }
/// <summary> /// This method attempts to returned a cached value, while /// simultaneously calling a Func to return the latest value. When the /// latest data comes back, it replaces what was previously in the /// cache. /// /// This method is best suited for loading dynamic data from the /// Internet, while still showing the user earlier data. /// /// This method returns an IObservable that may return *two* results /// (first the cached data, then the latest data). Therefore, it's /// important for UI applications that in your Subscribe method, you /// write the code to merge the second result when it comes in. /// /// This also means that awaiting this method is a Bad Idea(tm), always /// use Subscribe. /// </summary> /// <typeparam name="T">The type of item to get.</typeparam> /// <param name="blobCache">The cache to get the item.</param> /// <param name="key">The key to store the returned result under.</param> /// <param name="fetchFunc">A method that will fetch the task.</param> /// <param name="fetchPredicate">An optional Func to determine whether /// the updated item should be fetched. If the cached version isn't found, /// this parameter is ignored and the item is always fetched.</param> /// <param name="absoluteExpiration">An optional expiration date.</param> /// <param name="shouldInvalidateOnError">If this is true, the cache will /// be cleared when an exception occurs in fetchFunc.</param> /// <param name="cacheValidationPredicate">An optional Func to determine /// if the fetched value should be cached.</param> /// <returns>An Observable stream containing either one or two /// results (possibly a cached version, then the latest version).</returns> public static IObservable <T?> GetAndFetchLatest <T>( this IBlobCache blobCache, string key, Func <Task <T> > fetchFunc, Func <DateTimeOffset, bool>?fetchPredicate = null, DateTimeOffset?absoluteExpiration = null, bool shouldInvalidateOnError = false, Func <T, bool>?cacheValidationPredicate = null) { if (blobCache is null) { throw new ArgumentNullException(nameof(blobCache)); } return(blobCache.GetAndFetchLatest(key, () => fetchFunc().ToObservable(), fetchPredicate, absoluteExpiration, shouldInvalidateOnError, cacheValidationPredicate)); }
private void LoadEntries() { if (IsBusy) { return; } IsBusy = true; LogEntries.Clear(); try { _cache.GetAndFetchLatest("entries", async() => await _tripLogService.GetEntriesAsync()) .Subscribe(x => LogEntries = new ObservableCollection <TripLogEntry>(x), ex => System.Diagnostics.Debug.WriteLine("No Key")); } finally { IsBusy = false; } }
void LoadEntries() { if (IsBusy) { return; } IsBusy = true; LogEntries.Clear(); try { //Load data from the cache and then get entries from azure database _cache.GetAndFetchLatest("entries", async() => await _tripLogDataService.GetEntriesAsync()) .Subscribe(entries => LogEntries = new ObservableCollection <TripLogEntry>(entries)); } finally { IsBusy = false; } }
void LoadEntries() { if (IsBusy) { return; } IsBusy = true; LogEntries.Clear(); try { // Load from local cache and then immediately load from API _cache.GetAndFetchLatest("entries", async() => await _tripLogService.GetEntriesAsync()) .Subscribe(entries => LogEntries = new ObservableCollection <TripLogEntry>(entries)); } finally { IsBusy = false; } }
public IObservable <T> GetAndFetch <T>(Func <Task <T> > restAction) where T : BaseModel, new() { return(localBlobCache.GetAndFetchLatest(typeof(T).Name, restAction)); }
public IObservable <Post> GetPost(string id) => _cache.GetAndFetchLatest(id, async() => await GetPostAsync(id), offset => IsOffsetReached(offset, _cachedPostTime));