/// <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()); }
/// <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); }
/// <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>)); }
/// <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))); }
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);
/// <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>)); }
/// <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)); }
/// <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; }
/// <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)); }
/// <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>())); }
// // 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)))); }