public static TweekManagementRulesDriver StartNew(HttpGet getter, TweekManagementRulesDriverSettings settings, ILogger logger = null, IMeasureMetrics metrics = null, IScheduler scheduler = null) { var driver = new TweekManagementRulesDriver(getter, settings, logger, metrics, scheduler); driver.Start(); return(driver); }
private TweekManagementRulesDriver(HttpGet getter, TweekManagementRulesDriverSettings settings, ILogger logger = null, IMeasureMetrics metrics = null, IScheduler scheduler = null) { logger = logger ?? NullLogger.Instance; scheduler = scheduler ?? DefaultScheduler.Instance; var measuredGetter = MeasureAsync <string, HttpResponseMessage>(metrics, "download_latest_header", s => getter(s)); var measuredDownloader = MeasureAsync(metrics, "download_ruleset", (HttpResponseMessage message) => message.ExtractRules()); _pipeline = Observable.Create <Dictionary <string, RuleDefinition> >(async(sub, ct) => { var shouldStop = false; try { while (!shouldStop) { var response = await measuredGetter(RULESET_PATH); var newVersion = response.GetRulesVersion(); LastCheckTime = DateTime.UtcNow; if (newVersion == CurrentLabel) { await Delay(settings.SampleInterval, scheduler); continue; } var ruleset = await measuredDownloader(response); sub.OnNext(ruleset); CurrentLabel = newVersion; } } catch (Exception ex) { sub.OnError(ex); shouldStop = true; } ct.Register(() => shouldStop = true); return(() => shouldStop = true); }) .SubscribeOn(scheduler) .Catch((Exception exception) => { logger.LogWarning($"Failed to update rules: \r\n{exception}"); return(Observable.Empty <Dictionary <string, RuleDefinition> >() .Delay(settings.FailureDelay)); }) .Repeat() .Replay(1); }
public void Configure(IServiceCollection services, IConfiguration configuration) { var managementServiceUrl = new Uri(configuration.GetValue <string>("Rules:Management:Url")); var httpClient = new HttpClient { BaseAddress = managementServiceUrl }; var settings = new TweekManagementRulesDriverSettings { SampleIntervalInMs = configuration.GetValue("Rules:Management:SampleIntervalInMs", 30000), FailureDelayInMs = configuration.GetValue("Rules:Management:FailureDelayInMs", 60000) }; services.AddSingleton <IRulesDriver>( ctx => TweekManagementRulesDriver.StartNew(httpClient.GetAsync, settings, ctx.GetService <ILoggerFactory>().CreateLogger("RulesManagementDriver"), ctx.GetService <IMeasureMetrics>())); }
public void Configure(IServiceCollection services, IConfiguration configuration) { var managementServiceUrl = new Uri(configuration.GetValue <string>("Rules:Management:Url")); var httpClient = new HttpClient() { BaseAddress = managementServiceUrl }; var settings = new TweekManagementRulesDriverSettings(); configuration.GetValue <string>("Rules:Management:SampleIntervalInMs")?.Iter(x => settings.SampleIntervalInMs = x); configuration.GetValue <string>("Rules:Management:FailureDelayInMs")?.Iter(x => settings.FailureDelayInMs = x); services.AddSingleton <IRulesDriver>( ctx => TweekManagementRulesDriver.StartNew(httpClient.GetAsync, settings, ctx.GetService <ILoggerFactory>().CreateLogger("RulesManagementDriver"), ctx.GetService <IMeasureMetrics>())); services.AddSingleton <IDiagnosticsProvider>(ctx => new TweekManagementHealthCheck(ctx.GetServices <IRulesDriver>().OfType <TweekManagementRulesDriver>().Single())); }
private TweekManagementRulesDriver(HttpGet getter, TweekManagementRulesDriverSettings settings, ILogger logger = null, IMeasureMetrics metrics = null, IScheduler scheduler = null) { logger = logger ?? NullLogger.Instance; scheduler = scheduler ?? DefaultScheduler.Instance; var measuredGetter = MeasureAsync <string, HttpResponseMessage>(metrics, "download_latest_header", s => getter(s)); var measuredDownloader = MeasureAsync(metrics, "download_ruleset", (HttpResponseMessage message) => message.ExtractRules()); _pipeline = Observable.Create <Dictionary <string, RuleDefinition> >(async(sub, ct) => { try { while (!ct.IsCancellationRequested) { var versionResponse = await measuredGetter(RULESET_LATEST_VERSION_PATH); var latestVersion = await versionResponse.Content.ReadAsStringAsync(); LastCheckTime = scheduler.Now.UtcDateTime; if (latestVersion != CurrentLabel) { var rulesetResponse = await getter(RULESET_PATH); var newVersion = rulesetResponse.GetRulesVersion(); var ruleset = await measuredDownloader(rulesetResponse); sub.OnNext(ruleset); CurrentLabel = newVersion; } await 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); }