public SharedInformer(IInformer <TResource> masterInformer, ILogger logger, Func <TResource, TKey> keySelector, ICache <TKey, TResource> cache, IScheduler scheduler = null) { _cache = cache; _masterScheduler = scheduler ?? new EventLoopScheduler(); _logger = logger; _keySelector = keySelector; _masterObservable = masterInformer .GetResource(ResourceStreamType.ListWatch) .ObserveOn(_masterScheduler) .Do(x => _logger.LogTrace($"Received message from upstream {x}")) .SynchronizeCache(_cache, _keySelector) .Do(msg => { // cache is synchronized as soon as we get at least one message past this point _logger.LogTrace($"Cache v{cache.Version} synchronized: {msg} "); _cacheSynchronized.TrySetResult(true); _logger.LogTrace("_cacheSynchronized.TrySetResult(true)"); }) .Do(_ => YieldToWaitingSubscribers()) .ObserveOn(Scheduler.Immediate) // immediate ensures that all caches operations are done atomically .ObserveOn(_masterScheduler) .Catch <CacheSynchronized <ResourceEvent <TResource> >, Exception>(e => { _cacheSynchronized.TrySetException(e); // _cacheSynchronized.OnError(e); return(Observable.Throw <CacheSynchronized <ResourceEvent <TResource> > >(e)); }) .Finally(() => _cacheSynchronized.TrySetResult(false)) // .SubscribeOn(_masterScheduler) .Publish(); }
public IObservable <ResourceEvent <TResource> > GetResource(ResourceStreamType type) => _informer.GetResource(type, _options);