private void GetLocalMachineCache() { var localCache = new Lazy <IBlobCache>(() => { _filesystemProvider.CreateRecursive(_filesystemProvider.GetDefaultLocalMachineCacheDirectory()).SubscribeOn(BlobCache.TaskpoolScheduler).Wait(); return(new SQLitePersistentBlobCache(Path.Combine(_filesystemProvider.GetDefaultLocalMachineCacheDirectory(), "blobs.db"), BlobCache.TaskpoolScheduler)); }); this.LocalMachineCache = localCache.Value; }
protected PersistentBlobCache(string cacheDirectory = null, IFilesystemProvider filesystemProvider = null, IScheduler scheduler = null) { this.CacheDirectory = cacheDirectory ?? GetDefaultRoamingCacheDirectory(); this.Scheduler = scheduler ?? RxApp.TaskpoolScheduler; this.filesystem = filesystemProvider ?? new SimpleFilesystemProvider(); // Here, we're not actually caching the requests directly (i.e. as // byte[]s), but as the "replayed result of the request", in the // AsyncSubject - this makes the code infinitely simpler because // we don't have to keep a separate list of "in-flight reads" vs // "already completed and cached reads" MemoizedRequests = new MemoizingMRUCache<string, AsyncSubject<byte[]>>( (x, c) => FetchOrWriteBlobFromDisk(x, c, false), 20); try { var dir = filesystem.CreateRecursive(CacheDirectory); #if WINRT // NB: I don't want to talk about it. dir.Wait(); #endif } catch (Exception ex) { this.Log().FatalException("Couldn't create cache directory", ex); } var cacheIndex = FetchOrWriteBlobFromDisk(BlobCacheIndexKey, null, true) .Catch(Observable.Return(new byte[0])) .Select(x => Encoding.UTF8.GetString(x, 0, x.Length).Split('\n') .SelectMany(ParseCacheIndexEntry) .ToDictionary(y => y.Key, y => y.Value)) .Select(x => new ConcurrentDictionary<string, CacheIndexEntry>(x)); #if WINRT CacheIndex = cacheIndex.First(); #else cacheIndex.Subscribe(x => CacheIndex = x); #endif flushThreadSubscription = Disposable.Empty; if (!RxApp.InUnitTestRunner()) { flushThreadSubscription = actionTaken .Where(_ => CacheIndex != null) .Throttle(TimeSpan.FromSeconds(30), Scheduler) .SelectMany(_ => FlushCacheIndex(true)) .Subscribe(_ => { this.Log().Debug("Flushing cache"); lastFlushTime = Scheduler.Now; }); } this.Log().Info("{0} entries in blob cache index", CacheIndex.Count); }
protected PersistentBlobCache(string cacheDirectory = null, IFilesystemProvider filesystemProvider = null, IScheduler scheduler = null) { this.CacheDirectory = cacheDirectory ?? GetDefaultRoamingCacheDirectory(); this.Scheduler = scheduler ?? RxApp.TaskpoolScheduler; this.filesystem = filesystemProvider ?? new SimpleFilesystemProvider(); // Here, we're not actually caching the requests directly (i.e. as // byte[]s), but as the "replayed result of the request", in the // AsyncSubject - this makes the code infinitely simpler because // we don't have to keep a separate list of "in-flight reads" vs // "already completed and cached reads" MemoizedRequests = new MemoizingMRUCache <string, AsyncSubject <byte[]> >( (x, c) => FetchOrWriteBlobFromDisk(x, c, false), 20); filesystem.CreateRecursive(CacheDirectory); FetchOrWriteBlobFromDisk(BlobCacheIndexKey, null, true) .Catch(Observable.Return(new byte[0])) .Select(x => Encoding.UTF8.GetString(x, 0, x.Length).Split('\n') .SelectMany(ParseCacheIndexEntry) .ToDictionary(y => y.Key, y => y.Value)) .Select(x => new ConcurrentDictionary <string, CacheIndexEntry>(x)) .Subscribe(x => CacheIndex = x); flushThreadSubscription = Disposable.Empty; if (!RxApp.InUnitTestRunner()) { flushThreadSubscription = actionTaken .Where(_ => CacheIndex != null) .Throttle(TimeSpan.FromSeconds(30), Scheduler) .SelectMany(_ => FlushCacheIndex(true)) .Subscribe(_ => { log.Debug("Flushing cache"); lastFlushTime = Scheduler.Now; }); } log.Info("{0} entries in blob cache index", CacheIndex.Count); }
protected PersistentBlobCache( string cacheDirectory = null, IFilesystemProvider filesystemProvider = null, IScheduler scheduler = null, Action <AsyncSubject <byte[]> > invalidateCallback = null) { BlobCache.EnsureInitialized(); this.filesystem = filesystemProvider ?? RxApp.DependencyResolver.GetServices <IFilesystemProvider>().LastOrDefault(); if (this.filesystem == null) { throw new Exception("No IFilesystemProvider available. This should never happen, your RxUI DependencyResolver is broken"); } this.CacheDirectory = cacheDirectory ?? filesystem.GetDefaultRoamingCacheDirectory(); this.Scheduler = scheduler ?? RxApp.TaskpoolScheduler; // Here, we're not actually caching the requests directly (i.e. as // byte[]s), but as the "replayed result of the request", in the // AsyncSubject - this makes the code infinitely simpler because // we don't have to keep a separate list of "in-flight reads" vs // "already completed and cached reads" memoizedRequests = new MemoizingMRUCache <string, AsyncSubject <byte[]> >( (x, c) => FetchOrWriteBlobFromDisk(x, c, false), 20, invalidateCallback); try { var dir = filesystem.CreateRecursive(CacheDirectory); #if WINRT // NB: I don't want to talk about it. dir.Wait(); #endif } catch (Exception ex) { this.Log().FatalException("Couldn't create cache directory", ex); } var cacheIndex = FetchOrWriteBlobFromDisk(BlobCacheIndexKey, null, true) .Catch(Observable.Return(new byte[0])) .Select(x => Encoding.UTF8.GetString(x, 0, x.Length).Split('\n') .SelectMany(ParseCacheIndexEntry) .ToDictionary(y => y.Key, y => y.Value)) .Select(x => new ConcurrentDictionary <string, CacheIndexEntry>(x)); #if WINRT CacheIndex = cacheIndex.First(); #else cacheIndex.Subscribe(x => CacheIndex = x); #endif flushThreadSubscription = Disposable.Empty; if (!RxApp.InUnitTestRunner()) { flushThreadSubscription = actionTaken .Where(_ => CacheIndex != null) .Throttle(TimeSpan.FromSeconds(30), Scheduler) .SelectMany(_ => FlushCacheIndex(true)) .Subscribe(_ => this.Log().Debug("Flushing cache")); } this.Log().Info("{0} entries in blob cache index", CacheIndex.Count); }
public IObservable <Unit> CreateRecursive(string path) { return(_inner.CreateRecursive(path)); }