コード例 #1
0
            public async Task <T> GetAsync <T>(string key)
            {
                var identity = $"google-drive-{_id}-{key}";
                var value    = await _blobCache.GetOrFetchObject(identity, () => Task.FromResult(default(T)));

                return(value);
            }
コード例 #2
0
ファイル: YoutubeSongFinder.cs プロジェクト: yongjan/Espera
        public IObservable <IReadOnlyList <YoutubeSong> > GetSongsAsync(string searchTerm = null)
        {
            searchTerm = searchTerm ?? string.Empty;

            return(Observable.Defer(() => requestCache.GetOrFetchObject(BlobCacheKeys.GetKeyForYoutubeCache(searchTerm),
                                                                        () => RealSearch(searchTerm), DateTimeOffset.Now + CacheDuration)));
        }
コード例 #3
0
        public static IObservable <T> CacheApiResult <T>(
            this IObservable <T> source,
            string cacheKey,
            IBlobCache blobCache,
            IFullLogger?logger   = null,
            IScheduler?scheduler = null,
            bool forceUpdate     = false,
            TimeSpan expiration  = default)
        {
            expiration = expiration == TimeSpan.Zero ? Constants.DefaultCacheExpirationTimeOut : expiration;

            if (forceUpdate)
            {
                // TODO: [rlittlesii: July 30, 2020] Add retry and cached
                return(source.SelectMany(async value =>
                {
                    await blobCache.InsertObject(cacheKey, value, expiration);

                    logger?.Debug($"CACHE: Writing {{Value}} to cache with key: {{CacheKey}}", value, cacheKey);

                    return value;
                }));
            }

            blobCache
            .GetObject <T>(cacheKey)
            .Subscribe(obj => logger?.Debug("Found: {@Object}", obj));

            // TODO: [rlittlesii: July 30, 2020] Add retry and cached
            return(blobCache
                   .GetOrFetchObject(
                       cacheKey,
                       () => source.Timeout(Constants.DefaultRequestTimeout), DateTimeOffset.Now.Add(expiration)));
        }
コード例 #4
0
    public IObservable <string> GetSomeStrings()
    {
        var key           = "somestrings";
        var cachedStrings = Cache.GetOrFetchObject(key, DoGetStrings,
                                                   Cache.Scheduler.Now.Add(Timeout));

        //Return an observerable here instead of "blocking" with a task. -LC
        return(cachedStrings.Take(1));
    }
コード例 #5
0
        /// <summary>
        /// Attempt to return an object from the cache. If the item doesn't
        /// exist or returns an error, call a Func to create a new one.
        ///
        /// For most Internet applications, this method is the best method to
        /// call to fetch static data (i.e. images) from the network.
        /// </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 associate with the object.</param>
        /// <param name="fetchFunc">A Func which will return
        /// the latest value for the object should the cache not contain the
        /// key. </param>
        /// <param name="absoluteExpiration">An optional expiration date.</param>
        /// <returns>A Future result representing the deserialized object from
        /// the cache.</returns>
        public static IObservable <T?> GetOrCreateObject <T>(this IBlobCache blobCache, string key, Func <T> fetchFunc, DateTimeOffset?absoluteExpiration = null)
        {
            if (blobCache is null)
            {
                throw new ArgumentNullException(nameof(blobCache));
            }

            return(blobCache.GetOrFetchObject(key, () => Observable.Return(fetchFunc()), absoluteExpiration));
        }
コード例 #6
0
 private static async Task <string> GetOrFetchAsync(IBlobCache cache, DateTimeOffset?absoluteExpiration)
 {
     return(await cache.GetOrFetchObject("a", async() =>
     {
         await Task.Delay(500);
         var a = $"b{Interlocked.Increment(ref _cnt)}";
         Console.WriteLine("A:" + a);
         return a;
     }, absoluteExpiration));
 }
コード例 #7
0
        private async void EnsureLoggedInIfTokenSaved()
        {
            var persistentId = Id.ToString();
            var model        = await _blobCache.GetOrFetchObject(persistentId, () => Task.FromResult(default(ProviderModel)));

            if (model?.User == null || model?.Token == null)
            {
                return;
            }
            _gitHub.Credentials = new Credentials(model.User, model.Token);
            _currentUserName    = model.User;
            _isAuthenticated.OnNext(true);
        }
コード例 #8
0
        /// <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);
            }
        }
コード例 #9
0
        /// <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));
            }
        }
コード例 #10
0
        public SearchViewModel(IScreen hostScreen, ILoginMethods loginMethods, [Named("UserAccount")] IBlobCache userCache)
        {
            HostScreen    = hostScreen;
            SearchResults = new ReactiveCollection <ISongTileViewModel>();
            var playApi = loginMethods.CurrentAuthenticatedClient;

            if (playApi == null)
            {
                hostScreen.Router.Navigate.Execute(RxApp.GetService <IWelcomeViewModel>());
                return;
            }

            var canSearch = this.WhenAny(x => x.SearchQuery, x => !String.IsNullOrWhiteSpace(x.Value));

            PerformSearch = new ReactiveAsyncCommand(canSearch);

            this.ObservableForProperty(x => x.SearchQuery)
            .Throttle(TimeSpan.FromMilliseconds(700), RxApp.DeferredScheduler)
            .InvokeCommand(PerformSearch);

            var searchResults = PerformSearch.RegisterAsyncObservable(_ =>
                                                                      userCache.GetOrFetchObject(
                                                                          "search__" + SearchQuery,
                                                                          () => playApi.Search(SearchQuery),
                                                                          RxApp.TaskpoolScheduler.Now + TimeSpan.FromMinutes(1.0)));

            SearchResults = searchResults
                            .Do(_ => SearchResults.Clear())
                            .SelectMany(list => list.ToObservable())
                            .LoggedCatch(this, Observable.Empty <Song>())
                            .CreateCollection(x => (ISongTileViewModel) new SongTileViewModel(x, playApi));

            PerformSearch.ItemsInflight.StartWith(0)
            .Select(x => x > 0 ? Visibility.Visible : Visibility.Hidden)
            .ToProperty(this, x => x.SearchBusySpinner);

            PerformSearch.ThrownExceptions.Subscribe(_ => { });

            GoBack = new ReactiveCommand();
            GoBack.InvokeCommand(hostScreen.Router.NavigateBack);
        }
コード例 #11
0
        public async Task <T> GetOrFetchObjectAsync <T>(string key, Func <Task <T> > fetchFunc, DateTimeOffset?absoluteExpiration = default(DateTimeOffset?))
        {
            if (string.IsNullOrWhiteSpace(key))
            {
                throw new InvalidOperationException($"{nameof(key)} cannot be null or white space.");
            }

            if (fetchFunc == null)
            {
                throw new InvalidOperationException($"{nameof(fetchFunc)} cannot be null.");
            }

            try
            {
                return(await localBlobCache.GetOrFetchObject(key, fetchFunc, absoluteExpiration));
            }
            catch (KeyNotFoundException e)
            {
                throw new InvalidOperationException($"{nameof(key)} not found: {e.Message}.");
            }
        }
コード例 #12
0
 public async Task <T> GetOrFetchObjectAsync <T>(string key, Func <Task <T> > fetchFunc, DateTimeOffset?absoluteExpiration = default(DateTimeOffset?))
 {
     return(await localBlobCache.GetOrFetchObject(key, fetchFunc, absoluteExpiration));
 }
コード例 #13
0
        /// <summary>
        /// Convenience routine to help with caching and extracting the page size from the cache.
        /// </summary>
        /// <param name="cache"></param>
        /// <param name="pageKey"></param>
        /// <param name="sizeCalcFunc"></param>
        /// <returns></returns>
        public static IObservable <IWalkerSize> GetOrFetchPageSize(this IBlobCache cache, string pageKey, Func <IObservable <IWalkerSize> > sizeCalcFunc)
        {
            var sizeKey = pageKey + "-DefaultPageSize";

            return(cache.GetOrFetchObject <IWalkerSize>(sizeKey, sizeCalcFunc, DateTime.Now + Settings.PageCacheTime));
        }
コード例 #14
0
 /// <summary>
 /// Attempt to return an object from the cache. If the item doesn't
 /// exist or returns an error, call a Func to return the latest
 /// version of an object and insert the result in the cache.
 ///
 /// For most Internet applications, this method is the best method to
 /// call to fetch static data (i.e. images) from the network.
 /// </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 associate with the object.</param>
 /// <param name="fetchFunc">A Func which will asynchronously return
 /// the latest value for the object should the cache not contain the
 /// key. </param>
 /// <param name="absoluteExpiration">An optional expiration date.</param>
 /// <returns>A Future result representing the deserialized object from
 /// the cache.</returns>
 public static IObservable <T> GetOrFetchObject <T>(this IBlobCache blobCache, string key, Func <Task <T> > fetchFunc, DateTimeOffset?absoluteExpiration = null)
 {
     return(blobCache.GetOrFetchObject(key, () => fetchFunc().ToObservable(), absoluteExpiration));
 }
コード例 #15
0
 /// <summary>
 /// Attempt to return an object from the cache. If the item doesn't
 /// exist or returns an error, call a Func to create a new one.
 ///
 /// For most Internet applications, this method is the best method to
 /// call to fetch static data (i.e. images) from the network.
 /// </summary>
 /// <param name="key">The key to associate with the object.</param>
 /// <param name="fetchFunc">A Func which will return
 /// the latest value for the object should the cache not contain the
 /// key. </param>
 /// <param name="absoluteExpiration">An optional expiration date.</param>
 /// <returns>A Future result representing the deserialized object from
 /// the cache.</returns>
 public static IObservable <T> GetOrCreateObject <T>(this IBlobCache This, string key, Func <T> fetchFunc, DateTimeOffset?absoluteExpiration = null)
 {
     return(This.GetOrFetchObject(key, () => Observable.Return(fetchFunc()), absoluteExpiration));
 }
コード例 #16
0
        public IObservable <IReadOnlyList <SoundCloudSong> > GetSongsAsync(string searchTerm = null)
        {
            searchTerm = searchTerm ?? string.Empty;

            IObservable <IReadOnlyList <SoundCloudSong> > retrievalFunc = Observable.Defer(() =>
                                                                                           requestCache.GetOrFetchObject(BlobCacheKeys.GetKeyForSoundCloudCache(searchTerm), () =>
                                                                                                                         string.IsNullOrWhiteSpace(searchTerm) ? GetPopularSongs() : SearchSongs(searchTerm), DateTimeOffset.Now + CacheDuration));

            return(retrievalFunc.Catch <IReadOnlyList <SoundCloudSong>, Exception>(ex =>
                                                                                   Observable.Throw <IReadOnlyList <SoundCloudSong> >(new NetworkSongFinderException("SoundCloud search failed", ex)))
                   .Select(x => x.Where(y => y.IsStreamable || y.IsDownloadable).ToList())
                   .Do(SetupSongUrls));
        }
コード例 #17
0
 public Task <T> GetOrFetchObject <T>(string key, Func <Task <T> > fetchFunc)
 {
     return(_cache.GetOrFetchObject(key, fetchFunc).ToTask());
 }