/// <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);
            }
        }
Beispiel #2
0
        /// <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));
        }
Beispiel #3
0
 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;
     }
 }
Beispiel #4
0
        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;
            }
        }
Beispiel #5
0
        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;
            }
        }
Beispiel #6
0
 public IObservable <T> GetAndFetch <T>(Func <Task <T> > restAction) where T : BaseModel, new()
 {
     return(localBlobCache.GetAndFetchLatest(typeof(T).Name, restAction));
 }
Beispiel #7
0
 public IObservable <Post> GetPost(string id) =>
 _cache.GetAndFetchLatest(id,
                          async() => await GetPostAsync(id),
                          offset => IsOffsetReached(offset, _cachedPostTime));