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;
        }
Example #2
0
        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);
        }
Example #3
0
        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);
        }
Example #4
0
        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));
 }