예제 #1
0
        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()
                );
        }
예제 #2
0
 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));
 }
예제 #3
0
        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()
                );
        }
예제 #4
0
 private void Start() => _subscrption = new CompositeDisposable(_pipeline.Subscribe(rules => OnRulesChange?.Invoke(rules)), _pipeline.Connect());