public RulesRepository(IRulesDriver rulesDriver, IRulesetVersionProvider versionProvider, TimeSpan failureDelay, TimeSpan maxWaitTimeout, ILogger logger = null, IScheduler scheduler = null) { logger = logger ?? NullLogger.Instance; scheduler = scheduler ?? DefaultScheduler.Instance; _pipeline = Observable.Defer(versionProvider.OnVersion) .Timeout(maxWaitTimeout) .Do(_ => LastCheckTime = scheduler.Now.UtcDateTime) .DistinctUntilChanged() .Do(version => logger.LogInformation($"Detected new rules version: {version}")) .Select(version => Observable.FromAsync(ct => rulesDriver.GetRuleset(version, ct)).Do(_ => CurrentLabel = version)) .Switch() .Do(_ => logger.LogInformation("Updated rules")) .SubscribeOn(scheduler) .Catch((Exception exception) => { logger.LogWarning(exception, "Failed to update rules"); return(Observable.Empty <Dictionary <string, RuleDefinition> >() .Delay(failureDelay)); }) .Repeat() .Replay(1); _subscription = new CompositeDisposable( _pipeline.Subscribe(rules => OnRulesChange?.Invoke(rules)), _pipeline.Connect() ); }
public BlobRulesDriver(Uri url, IWebClientFactory webClientFactory, IScheduler scheduler = null) { _url = url; _subject = new ReplaySubject <Dictionary <string, RuleDefinition> >(1); scheduler = scheduler ?? TaskPoolScheduler.Default; _subscription = Observable.Interval(TimeSpan.FromSeconds(30)) .StartWith(0) .SubscribeOn(scheduler) .Select((_) => Observable.FromAsync(async() => { using (var client = webClientFactory.Create()) { client.Encoding = Encoding.UTF8; return(await client.DownloadStringTaskAsync(_url)); } })) .Switch() .DistinctUntilChanged() .Select(JsonConvert.DeserializeObject <Dictionary <string, RuleDefinition> >) .DistinctUntilChanged(new DictionaryEqualityComparer <string, RuleDefinition>(new RuleDefinitionComparer())) .Catch((Exception exception) => { //Trace.TraceWarning($"Failed to update rules from {url}\r\n{exception}"); return(Observable.Empty <Dictionary <string, RuleDefinition> >().Delay(TimeSpan.FromMinutes(1))); }) .Repeat() .Do(_subject) .Subscribe(x => OnRulesChange?.Invoke(x)); }
public MinioRulesDriver(IRulesClient rulesClient, MinioRulesDriverSettings settings, ILogger logger = null, IScheduler scheduler = null) { logger = logger ?? NullLogger.Instance; scheduler = scheduler ?? DefaultScheduler.Instance; _pipeline = Observable.Create <Dictionary <string, RuleDefinition> >(async(sub, ct) => { try { while (!ct.IsCancellationRequested) { var latestVersion = await rulesClient.GetVersion(ct); LastCheckTime = scheduler.Now.UtcDateTime; if (latestVersion != CurrentLabel) { var ruleset = await rulesClient.GetRuleset(latestVersion, ct); sub.OnNext(ruleset); CurrentLabel = latestVersion; } await Observable.Return(Unit.Default).Delay(settings.SampleInterval, scheduler); } } catch (Exception ex) { sub.OnError(ex); } }) .SubscribeOn(scheduler) .Catch((Exception exception) => { logger.LogWarning(exception, "Failed to update rules"); return(Observable.Empty <Dictionary <string, RuleDefinition> >() .Delay(settings.FailureDelay)); }) .Repeat() .Replay(1); _subscription = new CompositeDisposable( _pipeline.Subscribe(rules => OnRulesChange?.Invoke(rules)), _pipeline.Connect() ); }
private void Start() => _subscrption = new CompositeDisposable(_pipeline.Subscribe(rules => OnRulesChange?.Invoke(rules)), _pipeline.Connect());