示例#1
0
 public IObservable <Unit> InsertAll(IList <Category> categories)
 {
     return(blob.GetOrCreateObject <IList <Category> >(KEY_CATEGORIES, () => new List <Category>())
            .Select(source =>
     {
         return categories.Union(source);
     })
            .SelectMany(merged => blob.InsertObject(KEY_CATEGORIES, merged)));
 }
示例#2
0
 public IObservable<Unit> InsertAll(ICollection<Place> places)
 {
     return blob.GetOrCreateObject<IList<Place>>(KEY_PLACES, () => new List<Place>())
         .Select(source => 
             {
                 return places.Union(source);
             })
         .SelectMany(merged => blob.InsertObject(KEY_PLACES, merged));
 }        
示例#3
0
        public Settings()
        {
            blobCache = BlobCache.LocalMachine;

            blobCache.GetOrCreateObject(nameof(IsDebugging), () => false).Subscribe(b => _isDebugging   = b);
            blobCache.GetOrCreateObject(nameof(IsSoundOn), () => false).Subscribe(b => _isSoundOn       = b);
            blobCache.GetOrCreateObject(nameof(HasAstroids), () => true).Subscribe(b => _hasAstroids    = b);
            blobCache.GetOrCreateObject(nameof(MasterVolume), () => 10f).Subscribe(b => _masterVolume   = b);
            blobCache.GetOrCreateObject(nameof(IsFullScreen), () => false).Subscribe(b => _isFullScreen = b);
        }
示例#4
0
        public override T GetOrCreate <T>(T defaultValue, [CallerMemberName] string key = null)
        {
            if (key == null)
            {
                throw new ArgumentNullException(nameof(key));
            }

            _cacheLock.EnterReadLock();

            try
            {
                if (_cache.TryGetValue(key, out object value))
                {
                    return((T)value);
                }
            }
            finally
            {
                _cacheLock.ExitReadLock();
            }

            T returnValue = _blobCache.GetOrCreateObject($"{_cacheKey}:{key}", () => defaultValue)
                            .Do(x => AddToInternalCache(key, x)).Wait();

            return(returnValue);
        }
        public IObservable <Unit> InsertAll(IList <Session> sessions)
        {
            return(blob.GetOrCreateObject <IList <Session> >(KEY_SESSIONS, () => new List <Session>())
                   .Select(source =>
            {
                var checkedSessions = sessions.Where(session => session.IsChecked).ToDictionary(session => session.id);
                var merged = sessions.Union(source);

                return merged.Select(session =>
                {
                    session.IsChecked = checkedSessions.ContainsKey(session.id);
                    return session;
                });
            })
                   .SelectMany(merged =>
            {
                return Observable.Merge(
                    merged.ToObservable()
                    .Select(session => session.category)
                    .ToList().Distinct()
                    .SelectMany(categoryDao.InsertAll),
                    merged.ToObservable()
                    .Select(session => session.place)
                    .ToList().Distinct()
                    .SelectMany(placeDao.InsertAll),
                    blob.InsertObject(KEY_SESSIONS, merged)
                    );
            }));
        }
示例#6
0
        static IObservable <T> GetAndFetchLatestFromIndex <T>(this IBlobCache This,
                                                              string key,
                                                              Func <IObservable <T> > fetchFunc,
                                                              Action <T> removedItemsCallback,
                                                              Func <DateTimeOffset, bool> fetchPredicate = null,
                                                              DateTimeOffset?absoluteExpiration          = null,
                                                              bool shouldInvalidateOnError = false)
            where T : CacheItem
        {
            var idx = Observable.Defer(() => This
                                       .GetOrCreateObject(key, () => CacheIndex.Create(key)))
                      .Select(x => x.IndexKey == null ? CacheIndex.Create(key) : x)
                      .Replay()
                      .RefCount();


            var fetch = idx
                        .Select(x => Tuple.Create(x, fetchPredicate == null || !x.Keys.Any() || fetchPredicate(x.UpdatedAt)))
                        .Where(predicateIsTrue => predicateIsTrue.Item2)
                        .Select(x => x.Item1)
                        .Select(index => index.Clear())
                        .SelectMany(index => fetchFunc()
                                    .Catch <T, Exception>(ex =>
            {
                var shouldInvalidate = shouldInvalidateOnError ?
                                       This.InvalidateObject <CacheIndex>(key) :
                                       Observable.Return(Unit.Default);
                return(shouldInvalidate.SelectMany(__ => Observable.Throw <T>(ex)));
            })
                                    .SelectMany(x => x.Save <T>(This, key, absoluteExpiration))
                                    .Do(x => index.Add(key, x))
                                    );

            var cache = idx
                        .SelectMany(index => This.GetObjects <T>(index.Keys.ToList()))
                        .SelectMany(dict => dict.Values);

            return(cache.Merge(fetch)
                   .Finally(async() =>
            {
                var index = await idx;
                await index.Save(This);

                var list = index.OldKeys.Except(index.Keys);
                if (!list.Any())
                {
                    return;
                }
                var removed = await This.GetObjects <T>(list);
                foreach (var d in removed.Values)
                {
                    removedItemsCallback(d);
                }
                await This.InvalidateObjects <T>(list);
            })
                   .Replay().RefCount());
        }
示例#7
0
        static IObservable <T> GetAndFetchLatestFromIndex <T>(this IBlobCache This,
                                                              string key,
                                                              Func <IObservable <T> > fetchFunc,
                                                              Action <T> removedItemsCallback,
                                                              Func <DateTimeOffset, bool> fetchPredicate = null,
                                                              DateTimeOffset?absoluteExpiration          = null,
                                                              bool shouldInvalidateOnError = false)
            where T : CacheItem
        {
            var fetch = Observable.Defer(() => This.GetOrCreateObject(key, () => CacheIndex.Create(key))
                                         .Select(x => Tuple.Create(x, fetchPredicate == null || !x.Keys.Any() || fetchPredicate(x.UpdatedAt)))
                                         .Where(predicateIsTrue => predicateIsTrue.Item2)
                                         .Select(x => x.Item1)
                                         .SelectMany(index => index.Clear(This, key, absoluteExpiration))
                                         .SelectMany(index =>
            {
                var fetchObs = fetchFunc().Catch <T, Exception>(ex =>
                {
                    var shouldInvalidate = shouldInvalidateOnError ?
                                           This.InvalidateObject <CacheIndex>(key) :
                                           Observable.Return(Unit.Default);
                    return(shouldInvalidate.SelectMany(__ => Observable.Throw <T>(ex)));
                });

                return(fetchObs
                       .SelectMany(x => x.Save <T>(This, key, absoluteExpiration))
                       .Do(x => index.AddAndSave(This, key, x, absoluteExpiration))
                       .Finally(() =>
                {
                    This.GetObjects <T>(index.OldKeys.Except(index.Keys))
                    .Do(dict => This.InvalidateObjects <T>(dict.Keys))
                    .SelectMany(dict => dict.Values)
                    .Do(removedItemsCallback)
                    .Subscribe();
                }));
            }));

            var cache = Observable.Defer(() => This.GetOrCreateObject(key, () => CacheIndex.Create(key))
                                         .SelectMany(index => This.GetObjects <T>(index.Keys))
                                         .SelectMany(dict => dict.Values));

            return(cache.Merge(fetch).Replay().RefCount());
        }
示例#8
0
        private async Task VacuumIfNeeded(IBlobCache x, TimeSpan timeAgo)
        {
            var lastVacuum = await x.GetOrCreateObject(vacuumKey, () => new DateTime());

            if (lastVacuum > DateTime.UtcNow.Subtract(timeAgo))
            {
                return;
            }
            await Vacuum(x);
        }
示例#9
0
 public static IObservable<CacheIndex> AddAndSaveToIndex(IBlobCache cache, string indexKey, CacheItem item,
     DateTimeOffset? absoluteExpiration = null)
 {
     return cache.GetOrCreateObject(indexKey, () => Create(indexKey))
         .Do(index =>
         {
             var k = string.Format(CultureInfo.InvariantCulture, "{0}|{1}", index.IndexKey, item.Key);
             if (!index.Keys.Contains(k))
                 index.Keys.Add(k);
             index.UpdatedAt = DateTimeOffset.UtcNow;
         })
         .SelectMany(index => cache.InsertObject(index.IndexKey, index, absoluteExpiration)
         .Select(x => index));
 }
示例#10
0
 public static IObservable <CacheIndex> AddAndSaveToIndex(IBlobCache cache, string indexKey, CacheItem item,
                                                          DateTimeOffset?absoluteExpiration = null)
 {
     return(cache.GetOrCreateObject(indexKey, () => Create(indexKey))
            .Do(index =>
     {
         var k = string.Format(CultureInfo.InvariantCulture, "{0}|{1}", index.IndexKey, item.Key);
         if (!index.Keys.Contains(k))
         {
             index.Keys.Add(k);
         }
         index.UpdatedAt = DateTimeOffset.UtcNow;
     })
            .SelectMany(index => cache.InsertObject(index.IndexKey, index, absoluteExpiration)
                        .Select(x => index)));
 }
示例#11
0
 /// <summary>
 /// This method adds a new object to the database and updates the
 /// corresponding index.
 /// </summary>
 /// <typeparam name="T"></typeparam>
 /// <param name="blobCache">The cache to retrieve the object from.</param>
 /// <param name="key">The key to look up the cache value with.</param>
 /// <param name="item">The item to add to the database</param>
 /// <param name="maxCacheDuration">
 /// The maximum age of a cache object before the object is treated as
 /// expired and unusable. Cache objects older than this will be treated
 /// as a cache miss.
 /// <returns></returns>
 public static IObservable <T> PutAndUpdateIndex <T>(this IBlobCache blobCache,
                                                     string key,
                                                     Func <IObservable <T> > fetchFunc,
                                                     TimeSpan maxCacheDuration)
     where T : CacheItem
 {
     return(Observable.Defer(() =>
     {
         var absoluteExpiration = blobCache.Scheduler.Now + maxCacheDuration;
         return blobCache.GetOrCreateObject(key, () => CacheIndex.Create(key))
         .SelectMany(index => fetchFunc()
                     .Catch <T, Exception>(Observable.Throw <T>)
                     .SelectMany(x => x.Save <T>(blobCache, key, absoluteExpiration))
                     .Do(x => index.AddAndSave(blobCache, key, x, absoluteExpiration))
                     );
     }));
 }
        public Task <T> GetOrCreate <T>(string key, Func <T> createAction, TimeSpan?expireTimeSpan)
        {
            var t = Task.Run(async() =>
            {
                try
                {
                    DateTimeOffset?offset = expireTimeSpan.HasValue ? DateTimeOffset.UtcNow.Add(expireTimeSpan.Value) : (DateTimeOffset?)null;
                    return(await cache.GetOrCreateObject(key, createAction, offset));
                }
                catch
                {
                    return(default(T));
                }
            });

            t.ConfigureAwait(false);
            return(t);
        }
示例#13
0
        public FeedsViewModel(IBlobCache cache = null)
        {
            Cache = cache ?? Locator.Current.GetService<IBlobCache>();

            Cache.GetOrCreateObject(BlobCacheKeys.Blogs, () => new ReactiveList<BlogViewModel>())
                .Subscribe(blogs => { Blogs = blogs; });

            RefreshAll = ReactiveCommand.CreateAsyncTask(x =>
            {
                foreach (var blog in Blogs)
                {
                    blog.Refresh.InvokeCommand(null);
                }

                return Task.FromResult(Unit.Default);
            });

            RefreshAll.ThrownExceptions.Subscribe(thrownException => { this.Log().Error(thrownException); });

            _isLoading = RefreshAll.IsExecuting.ToProperty(this, x => x.IsLoading);

            PersistData =
                ReactiveCommand.CreateAsyncTask(async x => { await Cache.InsertObject(BlobCacheKeys.Blogs, Blogs); });

            PersistData.ThrownExceptions.Subscribe(thrownException => { this.Log().Error(thrownException); });

            // behaviours

            // when a blog is added or removed, wait for 5 seconds of inactivity before persisting the data as the user may be doing bulk [add|remove] operations.
            this.WhenAnyValue(viewModel => viewModel.Blogs)
                .Throttle(TimeSpan.FromSeconds(5), RxApp.MainThreadScheduler)
                .InvokeCommand(this, viewModel => viewModel.PersistData);

            // When an user adds a new blog to the feed, automatically fetch/cache the contents of the blog.
            // When a blog becomes the selected blog, fetch/cache the contents of the blog.
            this.WhenAnyObservable(viewModel => viewModel.Blogs.ItemsAdded)
                .Merge(this.WhenAnyValue(viewModel => viewModel.SelectedBlog).Where(blogVm => blogVm != null))
                .Subscribe(x => x.Refresh.InvokeCommand(null));

            // post-condition checks
            Condition.Ensures(Cache).IsNotNull();
            Condition.Ensures(RefreshAll).IsNotNull();
            Condition.Ensures(PersistData).IsNotNull();
        }
示例#14
0
        public FeedsViewModel(IBlobCache cache = null)
        {
            Cache = cache ?? Locator.Current.GetService <IBlobCache>();

            Cache.GetOrCreateObject(BlobCacheKeys.Blogs, () => new ReactiveList <BlogViewModel>())
            .Subscribe(blogs => { Blogs = blogs; });

            RefreshAll = ReactiveCommand.CreateAsyncTask(x =>
            {
                foreach (var blog in Blogs)
                {
                    blog.Refresh.InvokeCommand(null);
                }

                return(Task.FromResult(Unit.Default));
            });

            RefreshAll.ThrownExceptions.Subscribe(thrownException => { this.Log().Error(thrownException); });

            _isLoading = RefreshAll.IsExecuting.ToProperty(this, x => x.IsLoading);

            PersistData =
                ReactiveCommand.CreateAsyncTask(async x => { await Cache.InsertObject(BlobCacheKeys.Blogs, Blogs); });

            PersistData.ThrownExceptions.Subscribe(thrownException => { this.Log().Error(thrownException); });

            // behaviours

            // when a blog is added or removed, wait for 5 seconds of inactivity before persisting the data as the user may be doing bulk [add|remove] operations.
            this.WhenAnyValue(viewModel => viewModel.Blogs)
            .Throttle(TimeSpan.FromSeconds(5), RxApp.MainThreadScheduler)
            .InvokeCommand(this, viewModel => viewModel.PersistData);

            // When an user adds a new blog to the feed, automatically fetch/cache the contents of the blog.
            // When a blog becomes the selected blog, fetch/cache the contents of the blog.
            this.WhenAnyObservable(viewModel => viewModel.Blogs.ItemsAdded)
            .Merge(this.WhenAnyValue(viewModel => viewModel.SelectedBlog).Where(blogVm => blogVm != null))
            .Subscribe(x => x.Refresh.InvokeCommand(null));

            // post-condition checks
            Condition.Ensures(Cache).IsNotNull();
            Condition.Ensures(RefreshAll).IsNotNull();
            Condition.Ensures(PersistData).IsNotNull();
        }
示例#15
0
 public async Task <T> Get <T>(string key, T defaultValue)
 {
     return(await _cache.GetOrCreateObject <T>(GetKey(key), () => defaultValue));
 }
示例#16
0
 private async Task VacuumIfNeeded(IBlobCache x, TimeSpan timeAgo) {
     var lastVacuum = await x.GetOrCreateObject(vacuumKey, () => new DateTime());
     if (lastVacuum > DateTime.UtcNow.Subtract(timeAgo))
         return;
     await Vacuum(x);
 }
示例#17
0
		public async Task ReadFromStorage(IBlobCache storage)
		{
			ApiKey = await storage.GetOrCreateObject("ApiKey", () => "");
			AuthUser = await storage.GetOrCreateObject("AuthUser", () => "");
			AuthPass = await storage.GetOrCreateObject("AuthPass", () => "");
			Endpoint = await storage.GetOrCreateObject("Endpoint", () => "https://staging.vpdb.io/api");
			PbxFolder = await storage.GetOrCreateObject("PbxFolder", () => "");
			SyncStarred = await storage.GetOrCreateObject("SyncStarred", () => true);
			MinimizeToTray = await storage.GetOrCreateObject("MinimizeToTray", () => false);
			StartWithWindows = await storage.GetOrCreateObject("StartWithWindows", () => false);
			ReformatXml = await storage.GetOrCreateObject("ReformatXml", () => false);
			XmlFile = await storage.GetOrCreateObject("XmlFile", () => new Dictionary<Platform.PlatformType, string> {{ Platform.PlatformType.VP, "Visual Pinball" }});
			DownloadOnStartup = await storage.GetOrCreateObject("DownloadOnStartup", () => false);
			PatchTableScripts = await storage.GetOrCreateObject("PatchTableScripts", () => true);
			DownloadOrientation = await storage.GetOrCreateObject("DownloadOrientation", () => SettingsManager.Orientation.Portrait);
			DownloadOrientationFallback = await storage.GetOrCreateObject("DownloadOrientationFallback", () => SettingsManager.Orientation.Same);
			DownloadLighting = await storage.GetOrCreateObject("DownloadLighting", () => SettingsManager.Lighting.Day);
			DownloadLightingFallback = await storage.GetOrCreateObject("DownloadLightingFallback", () => SettingsManager.Lighting.Any);
			WindowPosition = await storage.GetOrCreateObject("WindowPosition", () => new Position());
			IsFirstRun = await storage.GetOrCreateObject("IsFirstRun", () => true);
		}
示例#18
0
 async public Task InitAsync()
 {
     _cache     = BlobCache.UserAccount;
     ProfileIds = await _cache.GetOrCreateObject <HashSet <string> >(CACHE_KEY, () => new HashSet <string>());
 }
 /// <summary>
 /// Gets the or create object non-secure
 /// </summary>
 /// <returns>The or create object.</returns>
 /// <param name="key">Key.</param>
 /// <param name="defaultValue">Default value.</param>
 /// <typeparam name="T">The 1st type parameter.</typeparam>
 T GetOrCreateObject <T>(string key, T defaultValue) where T : new()
 {
     return(_deviceCache.GetOrCreateObject(key, () => defaultValue).GetAwaiter().Wait());
 }
示例#20
0
 public IObservable <T> GetOrCreateObject <T>(string key, Func <T> createFunc)
 => _localCache.GetOrCreateObject(key, createFunc);
示例#21
0
 async public Task InitAsync()
 {
     _cache = BlobCache.UserAccount;
     _dict  = await _cache.GetOrCreateObject <Dictionary <string, HistoryModel> >(CACHE_KEY, () => new Dictionary <string, HistoryModel>());
 }
 /// <summary>
 /// get values from secure cache
 /// </summary>
 /// <returns>The or create object secure.</returns>
 /// <param name="key">Key.</param>
 /// <param name="defaultValue">Default value.</param>
 /// <typeparam name="T">The 1st type parameter.</typeparam>
 T GetOrCreateObjectWithSecure <T>(string key, T defaultValue) where T : new()
 {
     return(_secureCache.GetOrCreateObject(key, () => defaultValue).GetAwaiter().Wait());
 }
示例#23
0
 public IObservable <UserSettings> GetUserSettings()
 {
     _logger.Debug("GetUserSettings");
     return(BlobCache.GetOrCreateObject(UserSettingsKey, CreateUserSettings));
 }
示例#24
0
        public async Task ReadFromStorage(IBlobCache storage)
        {
            ApiKey = await storage.GetOrCreateObject("ApiKey", () => "");

            AuthUser = await storage.GetOrCreateObject("AuthUser", () => "");

            AuthPass = await storage.GetOrCreateObject("AuthPass", () => "");

            Endpoint = await storage.GetOrCreateObject("Endpoint", () => "https://api.vpdb.io");

            PinballXFolder = await storage.GetOrCreateObject("PbxFolder", () => "");

            SyncStarred = await storage.GetOrCreateObject("SyncStarred", () => true);

            MinimizeToTray = await storage.GetOrCreateObject("MinimizeToTray", () => false);

            StartWithWindows = await storage.GetOrCreateObject("StartWithWindows", () => false);

            ReformatXml = await storage.GetOrCreateObject("ReformatXml", () => false);

            XmlFile = await storage.GetOrCreateObject("XmlFile", () => new Dictionary <Platform, string> {
                { Platform.VP, "Visual Pinball" }
            });

            DownloadOnStartup = await storage.GetOrCreateObject("DownloadOnStartup", () => false);

            PatchTableScripts = await storage.GetOrCreateObject("PatchTableScripts", () => true);

            DownloadOrientation = await storage.GetOrCreateObject("DownloadOrientation", () => SettingsManager.Orientation.Portrait);

            DownloadOrientationFallback = await storage.GetOrCreateObject("DownloadOrientationFallback", () => SettingsManager.Orientation.Same);

            DownloadLighting = await storage.GetOrCreateObject("DownloadLighting", () => SettingsManager.Lighting.Day);

            DownloadLightingFallback = await storage.GetOrCreateObject("DownloadLightingFallback", () => SettingsManager.Lighting.Any);

            WindowPosition = await storage.GetOrCreateObject("WindowPosition", () => new Position());

            IsFirstRun = await storage.GetOrCreateObject("IsFirstRun", () => true);
        }
示例#25
0
 //TODO: такой же как и GetOrPutInCached
 public static T GetOrPutUserData <T>(string key, Func <T> fetchFunc)
 {
     return(UserData.GetOrCreateObject(key, fetchFunc, DateTimeOffset.MaxValue).Wait());
 }