Пример #1
0
        /// <summary>
        /// This is the non-generic analog of JsonSerializationMixin.GetAndFetchLatest[1]
        /// We shouldn't make modifications to this that alter its behavior from the generic
        /// version. By having this we can keep our two GetAndRefresh methods extremely
        /// similar and thus trust that what works in one will work in the other.
        ///
        /// 1. https://github.com/akavache/Akavache/blob/1b19bb56d/Akavache/Portable/JsonSerializationMixin.cs#L202-L236
        /// </summary>
        static IObservable <byte[]> GetAndFetchLatestBytes(
            this IBlobCache blobCache,
            string key,
            Func <IObservable <byte[]> > fetchFunc,
            Func <DateTimeOffset, bool> fetchPredicate = null,
            DateTimeOffset?absoluteExpiration          = null)
        {
            var fetch = Observable.Defer(() => blobCache.GetCreatedAt(key))
                        .Select(x => fetchPredicate == null || x == null || fetchPredicate(x.Value))
                        .Where(predicateIsTrue => predicateIsTrue)
                        .SelectMany(_ =>
            {
                return(fetchFunc()
                       .SelectMany(x => blobCache.Invalidate(key).Select(__ => x))
                       .SelectMany(x => blobCache.Insert(key, x, absoluteExpiration).Select(__ => x)));
            });

            var result = blobCache.Get(key).Select(x => Tuple.Create(x, true))
                         .Catch(Observable.Return(new Tuple <byte[], bool>(null, false)));

            return(result
                   .SelectMany(x => x.Item2
                    ? Observable.Return(x.Item1)
                    : Observable.Empty <byte[]>())
                   .Concat(fetch)
                   .Replay()
                   .RefCount());
        }
Пример #2
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. An explicit key is provided rather than the URL itself.
        /// </summary>
        /// <param name="blobCache">The blob cache associated with the action.</param>
        /// <param name="key">The key to store with.</param>
        /// <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 blobCache, string key, string url, IDictionary <string, string> headers = null, bool fetchAlways = false, DateTimeOffset?absoluteExpiration = null)
        {
            if (blobCache is null)
            {
                throw new ArgumentNullException(nameof(blobCache));
            }

            var doFetch       = MakeWebRequest(new Uri(url), headers).SelectMany(x => ProcessWebResponse(x, url, absoluteExpiration));
            var fetchAndCache = doFetch.SelectMany(x => blobCache.Insert(key, x, absoluteExpiration).Select(_ => x));

            IObservable <byte[]> ret;

            if (!fetchAlways)
            {
                ret = blobCache.Get(key).Catch(fetchAndCache);
            }
            else
            {
                ret = fetchAndCache;
            }

            var conn = ret.PublishLast();

            conn.Connect();
            return(conn);
        }
Пример #3
0
        /// <summary>
        /// Get an object from the cache and deserialize it via the JSON
        /// serializer.
        /// </summary>
        /// <typeparam name="T">The type of item.</typeparam>
        /// <param name="blobCache">The cache to get the item.</param>
        /// <param name="key">The key to look up in the cache
        /// modified key name. If this is true, GetAllObjects will not find this object.</param>
        /// <returns>A Future result representing the object in the cache.</returns>
        public static IObservable <T> GetObject <T>(this IBlobCache blobCache, string key)
        {
            if (blobCache is IObjectBlobCache objCache)
            {
                return(objCache.GetObject <T>(key));
            }

            return(blobCache.Get(GetTypePrefixedKey(key, typeof(T))).SelectMany(DeserializeObject <T>));
        }
        public static Task <bool> ContainsKey(this IBlobCache blobCache, string key)
        {
            var tcs = new TaskCompletionSource <bool>();

            blobCache.Get(key).Subscribe(
                x => tcs.SetResult(true),
                ex => tcs.SetResult(false));

            return(tcs.Task);
        }
        /// <summary>
        /// Get an object from the cache and deserialize it via the JSON
        /// serializer.
        /// </summary>
        /// <param name="key">The key to look up in the cache.</param>
        /// <param name="noTypePrefix">Use the exact key name instead of a
        /// modified key name. If this is true, GetAllObjects will not find this object.</param>
        /// <returns>A Future result representing the object in the cache.</returns>
        public static IObservable <T> GetObject <T>(this IBlobCache This, string key)
        {
            var objCache = This as IObjectBlobCache;

            if (objCache != null)
            {
                return(objCache.GetObject <T>(key));
            }

            return(This.Get(GetTypePrefixedKey(key, typeof(T))).SelectMany(DeserializeObject <T>));
        }
Пример #6
0
        /// <summary>
        /// Load an image from the blob cache.
        /// </summary>
        /// <param name="blobCache">The blob cache to load the image from.</param>
        /// <param name="key">The key to look up in the cache.</param>
        /// <param name="desiredWidth">Optional desired width, if not specified will be the default size.</param>
        /// <param name="desiredHeight">Optional desired height, if not specified will be the default size.</param>
        /// <returns>A Future result representing the bitmap image. blobCache
        /// Observable is guaranteed to be returned on the UI thread.</returns>
        public static IObservable <IBitmap> LoadImage(this IBlobCache blobCache, string key, float?desiredWidth = null, float?desiredHeight = null)
        {
            if (blobCache is null)
            {
                throw new ArgumentNullException(nameof(blobCache));
            }

            return(blobCache.Get(key)
                   .SelectMany(ThrowOnBadImageBuffer)
                   .SelectMany(x => BytesToImage(x, desiredWidth, desiredHeight)));
        }
Пример #7
0
 public async Task <T> GetFromCache <T>(string cacheName)
 {
     try
     {
         return(JsonSerializer.Deserialize <T>
                (
                    Encoding.UTF8.GetString(await cache.Get(cacheName)),
                    SerializationOptions.Default
                ));
     }
     catch (Exception)
     {
         return(default);
Пример #8
0
        /// <summary>
        /// Get an object from the cache and deserialize it via the JSON
        /// serializer.
        /// </summary>
        /// <typeparam name="T">The type of item.</typeparam>
        /// <param name="blobCache">The cache to get the item.</param>
        /// <param name="key">The key to look up in the cache
        /// modified key name. If this is true, GetAllObjects will not find this object.</param>
        /// <returns>A Future result representing the object in the cache.</returns>
        public static IObservable <T?> GetObject <T>(this IBlobCache blobCache, string key)
        {
            if (blobCache is null)
            {
                throw new ArgumentNullException(nameof(blobCache));
            }

            if (blobCache is IObjectBlobCache objCache)
            {
                return(objCache.GetObject <T>(key));
            }

            return(blobCache.Get(GetTypePrefixedKey(key, typeof(T))).SelectMany(DeserializeObject <T>));
        }
Пример #9
0
        /// <summary>
        /// Gets a dictionary filled with the specified keys with their corresponding values.
        /// </summary>
        /// <param name="blobCache">The blob cache to extract the values from.</param>
        /// <param name="keys">The keys to get the values for.</param>
        /// <returns>A observable with the specified values.</returns>
        public static IObservable <IDictionary <string, byte[]> > Get(this IBlobCache blobCache, IEnumerable <string> keys)
        {
            if (blobCache is IBulkBlobCache bulkCache)
            {
                return(bulkCache.Get(keys));
            }

            return(keys.ToObservable()
                   .SelectMany(x =>
            {
                return blobCache.Get(x)
                .Select(y => new KeyValuePair <string, byte[]>(x, y))
                .Catch <KeyValuePair <string, byte[]>, KeyNotFoundException>(_ => Observable.Empty <KeyValuePair <string, byte[]> >());
            })
                   .ToDictionary(k => k.Key, v => v.Value));
        }
Пример #10
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. An explicit key is provided rather than the URL itself.
        /// </summary>
        /// <param name="key">The key to store with.</param>
        /// <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 key, string url, IDictionary<string, string> headers = null, bool fetchAlways = false, DateTimeOffset? absoluteExpiration = null)
        {
            var doFetch = MakeWebRequest(new Uri(url), headers).SelectMany(x => ProcessWebResponse(x, url, absoluteExpiration));
            var fetchAndCache = doFetch.SelectMany(x => This.Insert(key, x, absoluteExpiration).Select(_ => x));

            var ret = default(IObservable<byte[]>);
            if (!fetchAlways)
            {
                ret = This.Get(key).Catch(fetchAndCache);
            }
            else 
            {
                ret = fetchAndCache;
            }

            var conn = ret.PublishLast();
            conn.Connect();
            return conn;
        }
Пример #11
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. An explicit key is provided rather than the URL itself.
        /// </summary>
        /// <param name="key">The key to store with.</param>
        /// <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 key, string url, IDictionary <string, string> headers = null, bool fetchAlways = false, DateTimeOffset?absoluteExpiration = null)
        {
            var doFetch       = MakeWebRequest(new Uri(url), headers).SelectMany(x => ProcessWebResponse(x, url, absoluteExpiration));
            var fetchAndCache = doFetch.SelectMany(x => This.Insert(key, x, absoluteExpiration).Select(_ => x));

            var ret = default(IObservable <byte[]>);

            if (!fetchAlways)
            {
                ret = This.Get(key).Catch(fetchAndCache);
            }
            else
            {
                ret = fetchAndCache;
            }

            var conn = ret.PublishLast();

            conn.Connect();
            return(conn);
        }
 public IObservable <byte[]> Get(string key)
 {
     return(_inner.Get(key));
 }
Пример #13
0
 /// <summary>
 /// Load an image from the blob cache.
 /// </summary>
 /// <param name="key">The key to look up in the cache.</param>
 /// <returns>A Future result representing the bitmap image. This
 /// Observable is guaranteed to be returned on the UI thread.</returns>
 public static IObservable <IBitmap> LoadImage(this IBlobCache This, string key, float?desiredWidth = null, float?desiredHeight = null)
 {
     return(This.Get(key)
            .SelectMany(ThrowOnBadImageBuffer)
            .SelectMany(x => bytesToImage(x, desiredWidth, desiredHeight)));
 }
        public object Get(string key, Type type)
        {
            var valueByteArray = blobCache.Get(key).Wait();

            return(serializationManager.Deserialize(valueByteArray, type));
        }
 /// <summary>
 /// This will return a pointer to a data stream representing the file, from cache. If there is nothing in cache, the empty
 /// sequence is returned.
 /// </summary>
 /// <param name="file">The file we should fetch - from local storage or elsewhere. Null if it isn't local and can't be fetched.</param>
 public static IObservable <IRandomAccessStream> GetFileFromCache(this IFile file, IBlobCache cache)
 {
     return(cache.Get(file.FileDataKey())
            .Select(bytes => bytes.AsRORAByteStream())
            .Catch <IRandomAccessStream, KeyNotFoundException>(e => Observable.Empty <IRandomAccessStream>()));
 }
Пример #16
0
 //
 // Summary:
 //     Attempt to return data 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.
 //
 // Parameters:
 //   key:
 //     The key to associate with the object.
 //
 //   fetchFunc:
 //     A Func which will asynchronously return the latest value for the bytes should
 //     the cache not contain the key. Observable.Start is the most straightforward
 //     way (though not the most efficient!) to implement this Func.
 //
 //   absoluteExpiration:
 //     An optional expiration date.
 //
 // Returns:
 //     A Future result representing the bytes from the cache.
 public static IObservable <byte[]> GetOrFetch(this IBlobCache This, string key, Func <IObservable <byte[]> > fetchFunc, DateTimeOffset?absoluteExpiration = null)
 {
     return(This.Get(key)
            .Catch <byte[], Exception>(_ => Observable.Defer(() => fetchFunc())
                                       .SelectMany(value => This.Insert(key, value, absoluteExpiration).Select(dummy => value))));
 }