예제 #1
0
        public IObservable <IChangeSet <TObject, TKey> > ExpireAfter()
        {
            return(Observable.Create <IChangeSet <TObject, TKey> >(observer =>
            {
                var cache = new IntermediateCache <TObject, TKey>(_source);

                var published = cache.Connect().Publish();
                var subscriber = published.SubscribeSafe(observer);

                var autoRemover = published.ForExpiry(_timeSelector, _interval, _scheduler)
                                  .Finally(observer.OnCompleted)
                                  .Subscribe(keys =>
                {
                    try
                    {
                        cache.Edit(updater => updater.Remove(keys.Select(kv => kv.Key)));
                    }
                    catch (Exception ex)
                    {
                        observer.OnError(ex);
                    }
                });

                var connected = published.Connect();

                return Disposable.Create(() =>
                {
                    connected.Dispose();
                    subscriber.Dispose();
                    autoRemover.Dispose();
                    cache.Dispose();
                });
            }));
        }
예제 #2
0
        public IObservable <IChangeSet <TObject, TKey> > Run()
        {
            return(Observable.Create <IChangeSet <TObject, TKey> >(observer =>
            {
                var sizeLimiter = new SizeLimiter <TObject, TKey>(_size);
                var root = new IntermediateCache <TObject, TKey>(_source);

                var subscriber = root.Connect()
                                 .Transform((t, v) => new ExpirableItem <TObject, TKey>(t, v, DateTime.Now))
                                 .Select(changes =>
                {
                    var result = sizeLimiter.Change(changes);

                    var removes = result.Where(c => c.Reason == ChangeReason.Remove);
                    root.Edit(updater => removes.ForEach(c => updater.Remove(c.Key)));
                    return result;
                })
                                 .Finally(observer.OnCompleted)
                                 .SubscribeSafe(observer);

                return Disposable.Create(() =>
                {
                    subscriber.Dispose();
                    root.Dispose();
                });
            }));
        }
예제 #3
0
        public Watcher(IObservable <IChangeSet <TObject, TKey> > source, IScheduler scheduler)
        {
            _source = source.AsObservableCache();

            var onCompletePublisher = _subscribers.Connect()
                                      .Synchronize(_locker)
                                      .ObserveOn(scheduler)
                                      .SubscribeMany((t, k) => Disposable.Create(t.OnCompleted))
                                      .Subscribe();

            var sourceSubscriber = source.Synchronize(_locker).Subscribe(updates => updates.ForEach(update =>
            {
                var subscriber = _subscribers.Lookup(update.Key);
                if (subscriber.HasValue)
                {
                    scheduler.Schedule(() => subscriber.Value.OnNext(update));
                }
            }));

            _disposer = Disposable.Create(() =>
            {
                onCompletePublisher.Dispose();
                sourceSubscriber.Dispose();

                _source.Dispose();
                _subscribers.Dispose();
            });
        }
예제 #4
0
        public IObservable <IChangeSet <T, TKey> > Run()
        {
            return(Observable.Create <IChangeSet <T, TKey> >(observer =>
            {
                var cache = new IntermediateCache <T, TKey>(_source);

                var published = cache.Connect().Publish();
                var subscriber = published.SubscribeSafe(observer);

                var remover = _evaluator.Finally(observer.OnCompleted)
                              .Subscribe(_ =>
                {
                    try
                    {
                        cache.Clear();
                    }
                    catch (Exception ex)
                    {
                        observer.OnError(ex);
                    }
                });

                var connected = published.Connect();

                return new CompositeDisposable
                {
                    connected,
                    subscriber,
                    remover,
                    cache
                };
            }));
        }