public ITrackingCollection <IPullRequestModel> GetPullRequests(ISimpleRepositoryModel repo) { // Since the api to list pull requests returns all the data for each pr, cache each pr in its own entry // and also cache an index that contains all the keys for each pr. This way we can fetch prs in bulk // but also individually without duplicating information. We store things in a custom observable collection // that checks whether an item is being updated (coming from the live stream after being retrieved from cache) // and replaces it instead of appending, so items get refreshed in-place as they come in. var keyobs = GetUserFromCache() .Select(user => string.Format(CultureInfo.InvariantCulture, "{0}|{1}|pr", user.Login, repo.Name)); var col = new TrackingCollection <IPullRequestModel>(); var source = Observable.Defer(() => keyobs .SelectMany(key => hostCache.GetAndFetchLatestFromIndex(key, () => apiClient.GetPullRequestsForRepository(repo.CloneUrl.Owner, repo.CloneUrl.RepositoryName) .Select(PullRequestCacheItem.Create), item => col.RemoveItem(Create(item)), TimeSpan.FromMinutes(5), TimeSpan.FromDays(1)) ) .Select(Create) ); col.Listen(source); return(col); }
public void ListeningTwiceWorks() { var count = 10; ITrackingCollection<Thing> col = new TrackingCollection<Thing>(); col.NewerComparer = OrderedComparer<Thing>.OrderByDescending(x => x.UpdatedAt).Compare; col.ProcessingDelay = TimeSpan.Zero; var list1 = new List<Thing>(Enumerable.Range(1, count).Select(i => GetThing(i, i, count - i, "Run 1")).ToList()); var list2 = new List<Thing>(Enumerable.Range(1, count).Select(i => GetThing(i, i, i + count, "Run 2")).ToList()); var subj = new ReplaySubject<Unit>(); subj.OnNext(Unit.Default); var disp = col.OriginalCompleted.Subscribe(x => subj.OnCompleted()); col.Listen(list1.ToObservable()); col.Subscribe(); subj.Wait(); disp.Dispose(); col.Listen(list2.ToObservable()); subj = new ReplaySubject<Unit>(); subj.OnNext(Unit.Default); disp = col.OriginalCompleted.Subscribe(x => subj.OnCompleted()); col.Subscribe(); subj.Wait(); disp.Dispose(); CollectionAssert.AreEqual(list2, col); }
void Run2() { var count = 10; var col = new TrackingCollection<Thing>(); col.ProcessingDelay = TimeSpan.FromMilliseconds(20); col.NewerComparer = OrderedComparer<Thing>.OrderByDescending(x => x.UpdatedAt).Compare; list.ItemsSource = col; var source = Observable.Merge( Observable.Generate(0, i => i < count, i => i + 1, i => i, i => TimeSpan.FromMilliseconds(5)) .Select(i => GetThing(i, i, i, "Run 1")), Observable.Generate(0, i => i < count, i => i + 1, i => i, i => TimeSpan.FromMilliseconds(7)) .Select(i => GetThing(i, i, i + 1, "Run 2")) ); col.Listen(source); col.Subscribe(); }
public ITrackingCollection<IPullRequestModel> GetPullRequests(ISimpleRepositoryModel repo) { // Since the api to list pull requests returns all the data for each pr, cache each pr in its own entry // and also cache an index that contains all the keys for each pr. This way we can fetch prs in bulk // but also individually without duplicating information. We store things in a custom observable collection // that checks whether an item is being updated (coming from the live stream after being retrieved from cache) // and replaces it instead of appending, so items get refreshed in-place as they come in. var keyobs = GetUserFromCache() .Select(user => string.Format(CultureInfo.InvariantCulture, "{0}|{1}|pr", user.Login, repo.Name)); var col = new TrackingCollection<IPullRequestModel>(); var source = Observable.Defer(() => keyobs .SelectMany(key => hostCache.GetAndFetchLatestFromIndex(key, () => apiClient.GetPullRequestsForRepository(repo.CloneUrl.Owner, repo.CloneUrl.RepositoryName) .Select(PullRequestCacheItem.Create), item => col.RemoveItem(Create(item)), TimeSpan.FromMinutes(5), TimeSpan.FromDays(1)) ) .Select(Create) ); col.Listen(source); return col; }