public async Task InMemoryModelStorageProvider_Successful_OnChange() { // arrange var services = new ServiceCollection(); services.AddTransient <IModelStorageProvider, InMemoryModelStorageProvider>(); var provider = services.BuildServiceProvider(); var storage = provider.GetRequiredService <IModelStorageProvider>(); using var cts = new CancellationTokenSource(); var modelName = "testModel"; var modelText = "This is test for the model memory stream"; var changed = false; var changeToken = ChangeToken.OnChange( () => storage.GetReloadToken(), () => changed = true); // save using (var stream = new MemoryStream()) { var modelBytes = Encoding.UTF8.GetBytes(modelText); stream.Write(modelBytes, 0, modelBytes.Length); stream.Position = 0; await storage.SaveModelAsync(modelName, stream, cts.Token); } Assert.True(changed); }
static void Main(string[] args) { var config = new Config(); ChangeToken.OnChange( () => config.GetReloadToken(), () => { Console.WriteLine(config.Value); }); Task.Run(() => { var i = 1; while (i < 5) { config.Value = i.ToString(); i++; } }); Console.Read(); }
public void IChangeToken_CancellationToken_ExchangeTokenBeforeOnRelaod() { // - 回调本该执行一次, 但是这里调用了两次, 说明同一个token被绑定上了两次而不是在每一个新token上绑定 - var token = new ConfigurationReloadToken(); int times = 0; ChangeToken.OnChange(() => token, () => { token = new ConfigurationReloadToken(); times++; }); token.OnReload(); // -> 2次 Assert.Equal(2, times); token.OnReload(); // -> 0次 Assert.Equal(2, times); // - 正确的调用一次的方式 - var t = new ConfigurationReloadToken(); var count = 0; ChangeToken.OnChange(() => t, () => { count++; }); Interlocked.Exchange(ref t, new ConfigurationReloadToken()).OnReload(); Assert.Equal(1, count); Interlocked.Exchange(ref t, new ConfigurationReloadToken()).OnReload(); Assert.Equal(2, count); }
public ConventionalRoutingActionDescriptorCollectionProvider( IEnumerable <IActionDescriptorProvider> actionDescriptorProviders, IEnumerable <IActionDescriptorChangeProvider> actionDescriptorChangeProviders, IRouteTemplateResolver routeTemplateResolver, IOptions <SwaggerRoutingOptions> swaggerRoutingOptions) { _routeTemplateResolver = routeTemplateResolver; _actionDescriptorProviders = actionDescriptorProviders .OrderBy(p => p.Order) .ToArray(); _actionDescriptorChangeProviders = actionDescriptorChangeProviders.ToArray(); _lock = new object(); // IMPORTANT: this needs to be the last thing we do in the constructor. Change notifications can happen immediately! ChangeToken.OnChange( GetCompositeChangeToken, UpdateCollection); if (swaggerRoutingOptions != null) { _swaggerRoutingOptions = swaggerRoutingOptions.Value; } }
private Dictionary <string, ILocalizationDictionary> GetDictionaries() { var dictionaries = _dictionaries; if (dictionaries != null) { return(dictionaries); } lock (_syncObj) { dictionaries = _dictionaries; if (dictionaries != null) { return(dictionaries); } if (!_subscribedForChanges) { ChangeToken.OnChange(() => _virtualFileProvider.Watch(_virtualPath.EnsureEndsWith('/') + "*.*"), () => { _dictionaries = null; }); _subscribedForChanges = true; } dictionaries = _dictionaries = CreateDictionaries(); } return(dictionaries); }
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { ChangeToken.OnChange(() => Configuration.GetReloadToken(), onChange); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Home/Error"); } app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); }); }
public MvcEndpointDataSource( IActionDescriptorCollectionProvider actions, MvcEndpointInvokerFactory invokerFactory, ParameterPolicyFactory parameterPolicyFactory, RoutePatternTransformer routePatternTransformer) { _actions = actions; _invokerFactory = invokerFactory; _parameterPolicyFactory = parameterPolicyFactory; _routePatternTransformer = routePatternTransformer; ConventionalEndpointInfos = new List <MvcEndpointInfo>(); AttributeRoutingConventionResolvers = new List <Func <ActionDescriptor, DefaultEndpointConventionBuilder> >(); // IMPORTANT: this needs to be the last thing we do in the constructor. Change notifications can happen immediately! // // It's possible for someone to override the collection provider without providing // change notifications. If that's the case we won't process changes. if (actions is ActionDescriptorCollectionProvider collectionProviderWithChangeToken) { ChangeToken.OnChange( () => collectionProviderWithChangeToken.GetChangeToken(), UpdateEndpoints); } }
/// <summary> /// Initializes a new instance of the <see cref="ConfigReloadingProxy{TInterface}"/> class. /// </summary> /// <param name="section">The configuration section that defines the object that this class creates.</param> /// <param name="defaultTypes"> /// An object that defines the default types to be used when a type is not explicitly specified by a /// configuration section. /// </param> /// <param name="valueConverters"> /// An object that defines custom converter functions that are used to convert string configuration /// values to a target type. /// </param> /// <param name="declaringType">If present the declaring type of the member that this instance is a value of.</param> /// <param name="memberName">If present, the name of the member that this instance is the value of.</param> /// <param name="resolver"> /// An object that can retrieve constructor parameter values that are not found in configuration. This /// object is an adapter for dependency injection containers, such as Ninject, Unity, Autofac, or /// StructureMap. Consider using the <see cref="Resolver"/> class for this parameter, as it supports /// most dependency injection containers. /// </param> protected ConfigReloadingProxy(IConfiguration section, DefaultTypes defaultTypes, ValueConverters valueConverters, Type declaringType, string memberName, IResolver resolver) { if (typeof(TInterface) == typeof(IEnumerable <>)) { throw new InvalidOperationException("The IEnumerable interface is not supported."); } if (typeof(IEnumerable).GetTypeInfo().IsAssignableFrom(typeof(TInterface))) { throw new InvalidOperationException( $"Interfaces that inherit from IEnumerable are not supported: '{typeof(TInterface).FullName}'"); } _section = section ?? throw new ArgumentNullException(nameof(section)); _defaultTypes = defaultTypes ?? ConfigurationObjectFactory.EmptyDefaultTypes; _valueConverters = valueConverters ?? ConfigurationObjectFactory.EmptyValueConverters; _declaringType = declaringType; _memberName = memberName; _resolver = resolver ?? Resolver.Empty; _hash = GetHash(); Object = CreateObject(); ChangeToken.OnChange(section.GetReloadToken, () => ReloadObject(false)); }
private static String GetDateStringFromChangeToken(ChangeToken ct) { string ticks = ct.StringValue.Split(';')[3]; DateTime dt = new DateTime(Convert.ToInt64(ticks)); return(string.Format("{0} {1}", dt.ToShortDateString(), dt.ToLongTimeString())); }
/// <summary> /// <para> /// Use Puppy Logger, remember to <see cref="AddLogger" /> before <c> UseLogger </c>. /// In Configure of Application Builder, you need inject "IApplicationLifetime /// appLifetime" to use Logger. /// </para> /// <para> /// You can access log via URL config by <see cref="LoggerConfig.ViewLogUrl" /> and /// Search for <see cref="LogEntity.Id" />, <see cref="LogEntity.Message" />, /// <see cref="LogEntity.Level" />, <see cref="LogEntity.CreatedTime" /> (with string /// format is <c> "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK" </c>, ex: "2017-08-24T00:56:29.6271125+07:00") /// </para> /// </summary> /// <param name="app"> </param> /// <param name="loggerFactory"></param> /// <param name="appLifetime"> Ensure any buffered events are sent at shutdown </param> /// <returns></returns> /// <remarks> /// <para> /// Auto add request header <c> "Id" </c>, <c> "RequestTime" </c> and <c> /// EnableRewind </c> for Request to get <c> Request Body </c> when logging. /// </para> /// <para> /// The file will be written using the <c> UTF-8 encoding </c> without a byte-order mark. /// </para> /// <para> Auto reload config when the appsettings.json changed </para> /// </remarks> public static IApplicationBuilder UseLogger(this IApplicationBuilder app, ILoggerFactory loggerFactory, IApplicationLifetime appLifetime) { // Re-Build the config for Logger - parameters _configuration.BuildLoggerConfig(_configSection); // Build the config for Logger - methods Log.BuildLogger(); // Add Logger for microsoft logger factory loggerFactory.AddSerilog(); // Ensure any buffered events are sent at shutdown appLifetime.ApplicationStopped.Register(Serilog.Log.CloseAndFlush); // Add middleware to inject Request Id app.UseMiddleware <LoggerMiddleware>(); ChangeToken.OnChange(_configuration.GetReloadToken, () => { // Re-Build the config for Logger - parameters _configuration.BuildLoggerConfig(); // Re-Build the config for Logger - methods Log.BuildLogger(); Log.Warning("Puppy Logger Changed Configuration"); }); return(app); }
public FileServerSwitch(IHostingEnvironment hostingEnvironment, IOptions <ServerFileSwitchOptions> options) { _options = options.Value; _fileProvider = _fileProvider = _options.FileProvider ?? hostingEnvironment.WebRootFileProvider; FileChanged(); ChangeToken.OnChange(() => _fileProvider.Watch(_options.FilePath), FileChanged); }
static void Main(string[] args) { ReadConfig(fileProvider); ChangeToken.OnChange( () => fileProvider.Watch("settings.json"), () => { Console.WriteLine("File Changed============================"); ReadConfig(fileProvider); } ); //foreach (var file in fileProvider.GetDirectoryContents("")) //{ // if (file.IsDirectory) // { // Console.WriteLine($" - { file.Name}"); // } // else // { // Console.WriteLine($" { file.Name} - {file.Length} bytes"); // } //} //Console.ReadLine(); Console.ReadLine(); }
public static ChangeQuery GetChangeQueryNewUpdate(string ListId, TraceWriter log) { // ATENTION: Change Token made for only the last minute and for new Items !! ChangeToken lastChangeToken = new ChangeToken(); ChangeQuery myChangeQuery = new ChangeQuery(false, false); try { lastChangeToken.StringValue = string.Format("1;3;{0};{1};-1", ListId, DateTime.Now.AddMinutes(-1).ToUniversalTime().Ticks.ToString()); ChangeToken newChangeToken = new ChangeToken(); newChangeToken.StringValue = string.Format("1;3;{0};{1};-1", ListId, DateTime.Now.ToUniversalTime().Ticks.ToString()); myChangeQuery.Item = true; // Get only Item changes myChangeQuery.Add = true; // Get only new and updated Items myChangeQuery.Update = true; // Get only new and updated Items myChangeQuery.ChangeTokenStart = lastChangeToken; myChangeQuery.ChangeTokenEnd = newChangeToken; } catch (Exception ex) { log.Info($"Error in GetChangeQueryNewUpdate: " + ex.ToString()); } return(myChangeQuery); }
public WeatherForecastController(ILogger <WeatherForecastController> logger, IOptions <LearningOptions> learningOptions, IOptionsSnapshot <LearningOptions> learningOptionsSnapshot, IOptionsMonitor <LearningOptions> learningOptionsMonitor, IOptionsSnapshot <ThemeOptions> themeOptionsSnapshot, IConfiguration configuration ) { _logger = logger; _learningOptions = learningOptions; _learningOptionsSnapshot = learningOptionsSnapshot; _learningOptionsMonitor = learningOptionsMonitor; _configuration = configuration; _themeOptionsSnapshot = themeOptionsSnapshot; _learningOptionsMonitor.OnChange((options, value) => { _logger.LogInformation($"OnChnage => {JsonConvert.SerializeObject(options)}"); }); //ChangeToken + IFileProvider 实现对文件的监听 var filePath = @"C:\Users\admin\Downloads\德利得-三星发货订单接口测试流程.txt"; var directory = System.IO.Path.GetDirectoryName(filePath); var fileProvider = new PhysicalFileProvider(directory); ChangeToken.OnChange( () => fileProvider.Watch("德利得-三星发货订单接口测试流程.txt"), () => { _logger.LogInformation("孔乙己,你一定又偷人家书了吧"); } ); }
public static IServiceCollection AddGlobalVariable(this IServiceCollection services, IConfiguration configuration) { services.AddHttpContextAccessor(); services.TryAddSingleton <IActionContextAccessor, ActionContextAccessor>(); ReadDbConfig(configuration); //freesql services.AddFreeSql(); DbInstanceFactory.dbConfig = GlobalContext.DefaultDbConfig; ChangeToken.OnChange(() => configuration.GetReloadToken(), () => { //GlobalVariableModel.BackUpHost = configuration.GetSection("BackupHost").Value; ReadDbConfig(configuration); if (GlobalContext.DefaultDbConfig.MasterConnection != DbInstanceFactory.dbConfig.MasterConnection) { services.RemoveAll <IFreeSql>(); services.AddFreeSql(); DbInstanceFactory.dbConfig = GlobalContext.DefaultDbConfig; } }); return(services); }
public AppSettings(IConfiguration configuration, IHostEnvironment env, ILogger <AppSettings> logger) { _configuration = configuration; ChangeToken.OnChange(configuration.GetReloadToken, async() => { Interlocked.Increment(ref _count); await Task.Delay(500); if (Interlocked.Decrement(ref _count) > 0) { return; } var result = await Task.WhenAll( HasChangedAsync(Path.Combine(env.ContentRootPath, "appsettings.json"), _settingsFileHash), HasChangedAsync(Path.Combine(env.ContentRootPath, $"appsettings.{env.EnvironmentName}.json"), _envSettingsFileHash) ).ConfigureAwait(false); if (result.Any(x => x)) { logger.LogInformation("Fire Changed event..."); OnChanged(EventArgs.Empty); } }); }
public void Configure(IApplicationBuilder app, IConfiguration config, IWebHostEnvironment env) { #region snippet2 ChangeToken.OnChange( () => config.GetReloadToken(), (state) => InvokeChanged(state), env); #endregion if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Error"); } app.UseStaticFiles(); app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapRazorPages(); }); }
internal static void StaticOnChange() { // <Static> CancellationTokenSource cancellationTokenSource = new(); CancellationChangeToken cancellationChangeToken = new(cancellationTokenSource.Token); Func <IChangeToken> producer = () => { // The producer factory should always return a new change token. // If the token's already fired, get a new token. if (cancellationTokenSource.IsCancellationRequested) { cancellationTokenSource = new(); cancellationChangeToken = new(cancellationTokenSource.Token); } return(cancellationChangeToken); }; Action consumer = () => Console.WriteLine("The callback was invoked."); using (ChangeToken.OnChange(producer, consumer)) { cancellationTokenSource.Cancel(); } // Outputs: // The callback was invoked. // </Static> }
public static void Run() { var builder = new ConfigurationBuilder(); builder.AddJsonFile(null, $@"C:\WorkStation\Code\GitHubCode\CoreApp\CoreWebApp\appsettings.json", true, true); var configuration = builder.Build(); Task.Run(() => { ChangeToken.OnChange(() => configuration.GetReloadToken(), () => { Console.WriteLine("Configuration has changed"); }); }); var optionsChangeTokenSource = new ConfigurationChangeTokenSource <MyOption>(configuration); var configureOptions = new NamedConfigureFromConfigurationOptions <MyOption>(string.Empty, configuration); var optionsFactory = new OptionsFactory <MyOption>(new List <IConfigureOptions <MyOption> >() { configureOptions }, new List <IPostConfigureOptions <MyOption> >()); var optionsMonitor = new OptionsMonitor <MyOption>(optionsFactory, new List <IOptionsChangeTokenSource <MyOption> >() { optionsChangeTokenSource }, new OptionsCache <MyOption>()); optionsMonitor.OnChange((option, name) => { Console.WriteLine($@"optionsMonitor Detected Configuration has changed,current Value is {option.TestOption}"); }); Thread.Sleep(600000); }
public SiteCookieAuthenticationOptions( IOptionsFactory<CookieAuthenticationOptions> factory, IEnumerable<IOptionsChangeTokenSource<CookieAuthenticationOptions>> sources, IOptionsMonitorCache<CookieAuthenticationOptions> cache, IOptions<MultiTenantOptions> multiTenantOptionsAccessor, IPostConfigureOptions<CookieAuthenticationOptions> cookieOptionsInitializer, IHttpContextAccessor httpContextAccessor, ILogger<SiteCookieAuthenticationOptions> logger ) { _multiTenantOptions = multiTenantOptionsAccessor.Value; _cookieOptionsInitializer = cookieOptionsInitializer; _httpContextAccessor = httpContextAccessor; _log = logger; _factory = factory; _sources = sources; _cache = cache; foreach (var source in _sources) { ChangeToken.OnChange<string>( () => source.GetChangeToken(), (name) => InvokeChanged(name), source.Name); } }
public CosmosDBConfigurationProvider(WebHostBuilderContext context, CosmosDBConfiguration configuration, IWatcherClient watcherClient, IParser <string> parser) { _context = context ?? throw new ArgumentNullException(nameof(context)); _configuration = configuration ?? throw new ArgumentNullException(nameof(configuration)); _parser = parser ?? throw new ArgumentNullException(nameof(parser)); if (watcherClient == null) { throw new ArgumentNullException(nameof(watcherClient)); } if (string.IsNullOrWhiteSpace(configuration.ConnectionString)) { throw new ArgumentNullException(nameof(configuration), "Connectionstring is missing from configuration"); } if (string.IsNullOrWhiteSpace(configuration.Database)) { throw new ArgumentNullException(nameof(configuration), "Database is missing from configuration"); } if (string.IsNullOrWhiteSpace(configuration.PrimaryKey)) { throw new ArgumentNullException(nameof(configuration), "Primary key is missing from configuration"); } if (_configuration.ReloadOnChange) { _changeTokenRegistration = ChangeToken.OnChange(watcherClient.Watch, LoadSettings); } }
/// <summary> /// Adds a new configuration source, retrieves the provider for the source, and /// adds a change listener that triggers a reload of the provider whenever a change /// is detected. /// </summary> /// <param name="source">The configuration source to add.</param> /// <returns>The same <see cref="IConfigurationBuilder"/>.</returns> public IConfigurationBuilder Add(IConfigurationSource source) { if (source == null) { throw new ArgumentNullException(nameof(source)); } // Ads this source and its associated provider to the source // and provider references in this class. We make sure to load // the data from the provider so that values are properly initialized. _sources.Add(source); var provider = source.Build(this); provider.Load(); // Add a handler that will detect when the the configuration // provider has reloaded data. This will invoke the RaiseChanged // method which maps changes in individual providers to the change // token on the WebAssemblyHostConfiguration object. _changeTokenRegistrations.Add(ChangeToken.OnChange(() => provider.GetReloadToken(), () => RaiseChanged())); // We keep a list of providers in this class so that we can map // set and get methods on this class to the set and get methods // on the individual configuration providers. _providers.Add(provider); return(this); }
/// <summary> /// Listen for changes in subfolders /// </summary> /// <param name="rootPath">Watching Root Path</param> /// <param name="onChange">Callback when change</param> private void SubfolderChangeWatch(string rootPath, Action <IEnumerable <string> > onChange) { FileProvider = new PhysicalFileProvider(rootPath); // 递归查询所有子文件 Files.AddRange(FileProvider.GetDirectoryDepthContents("").Where(f => !f.IsDirectory)); // 监听监听所有文件,当文件发生修改时反应为某个子文件夹的修改,在最后将修改的文件夹路径打印出来 ChangeToken.OnChange(() => FileProvider.Watch("*"), () => // filter Example: **/*.cs, *.*, subFolder/**/*.cshtml. { // 查询所有子文件 var files = FileProvider.GetDirectoryDepthContents("").Where(f => !f.IsDirectory); // 查询变化的文件 var modFiles = Files.Where(a => (!files.Any(b => b.PhysicalPath == a.PhysicalPath)) || files.FirstOrDefault(b => b.PhysicalPath == a.PhysicalPath)?.LastModified > a.LastModified) .Union(files.Where(a => !Files.Any(b => b.PhysicalPath == a.PhysicalPath))) .Select(f => f.PhysicalPath); // 查询根目录下的子文件夹 var subfolders = FileProvider.GetDirectoryContents(""); // 查询发生变化的文件夹 var modDirs = subfolders.Select(f => f.PhysicalPath).Where(a => modFiles.Any(b => b.Contains(a))); // 有文件夹修改则回调 if (modDirs.Any()) { onChange(modDirs); } // 刷新暂存文件列表 Files.Refresh(files); }); }
public SiteGoogleOptions( IOptionsFactory <GoogleOptions> factory, IEnumerable <IOptionsChangeTokenSource <GoogleOptions> > sources, IOptionsMonitorCache <GoogleOptions> cache, IOptions <MultiTenantOptions> multiTenantOptionsAccessor, IPostConfigureOptions <GoogleOptions> optionsInitializer, IDataProtectionProvider dataProtection, IHttpContextAccessor httpContextAccessor, ILogger <SiteGoogleOptions> logger ) { _multiTenantOptions = multiTenantOptionsAccessor.Value; _httpContextAccessor = httpContextAccessor; _log = logger; _optionsInitializer = optionsInitializer; _dp = dataProtection; _factory = factory; _sources = sources; _cache = cache; foreach (var source in _sources) { ChangeToken.OnChange <string>( () => source.GetChangeToken(), (name) => InvokeChanged(name), source.Name); } }
/// <inheritdoc /> /// <summary> /// Initializes a new instance with the specified source. /// </summary> /// <param name="source">The <see cref="IConfigurationSource"/> used to retrieve values from AWS Systems Manager Parameter Store</param> /// <param name="systemsManagerProcessor">The <see cref="ISystemsManagerProcessor"/> used to retrieve values from AWS Systems Manager Parameter Store</param> public SystemsManagerConfigurationProvider(SystemsManagerConfigurationSource source, ISystemsManagerProcessor systemsManagerProcessor) { Source = source ?? throw new ArgumentNullException(nameof(source)); SystemsManagerProcessor = systemsManagerProcessor ?? throw new ArgumentNullException(nameof(systemsManagerProcessor)); if (source.AwsOptions == null) { throw new ArgumentNullException(nameof(source.AwsOptions)); } if (source.Path == null) { throw new ArgumentNullException(nameof(source.Path)); } if (source.ReloadAfter != null) { ChangeToken.OnChange(() => { var cancellationTokenSource = new CancellationTokenSource(source.ReloadAfter.Value); var cancellationChangeToken = new CancellationChangeToken(cancellationTokenSource.Token); return(cancellationChangeToken); }, async() => { ReloadTaskEvent.Reset(); try { await LoadAsync(true).ConfigureAwait(false); } finally { ReloadTaskEvent.Set(); } }); } }
/// <summary> /// Constructor. /// </summary> /// <param name="factory">The factory to use to create options.</param> /// <param name="sources">The sources used to listen for changes to the options instance.</param> /// <param name="cache">The cache used to store options.</param> public OptionsMonitor(IOptionsFactory <TOptions> factory, IEnumerable <IOptionsChangeTokenSource <TOptions> > sources, IOptionsMonitorCache <TOptions> cache) { _factory = factory; _cache = cache; void RegisterSource(IOptionsChangeTokenSource <TOptions> source) { IDisposable registration = ChangeToken.OnChange( source.GetChangeToken, InvokeChanged, source.Name); _registrations.Add(registration); } // The default DI container uses arrays under the covers. Take advantage of this knowledge // by checking for an array and enumerate over that, so we don't need to allocate an enumerator. if (sources is IOptionsChangeTokenSource <TOptions>[] sourcesArray) { foreach (IOptionsChangeTokenSource <TOptions> source in sourcesArray) { RegisterSource(source); } } else { foreach (IOptionsChangeTokenSource <TOptions> source in sources) { RegisterSource(source); } } }
static void Main(string[] args) { IConfigurationBuilder builder = new ConfigurationBuilder(); builder.AddZookeeper(option => { option.ConnectionString = "localhost:2181"; option.ConnectionTimeout = 10000; option.RootPath = "/config"; option.SessionTimeout = 3000; }); var configuration = builder.Build(); ChangeToken.OnChange( () => configuration.GetReloadToken(), () => { foreach (var item in configuration.AsEnumerable()) { Console.WriteLine(item); } }); Console.ReadLine(); }
/// <summary> /// Enable model monitoring for the <see cref="IModelStorageProvider"/>. /// Overrides the default model storage provider. /// </summary> /// <typeparam name="TData"></typeparam> /// <typeparam name="TPrediction"></typeparam> /// <param name="builder"></param> /// <param name="storageName">The name of the ML model in the storage provider.</param> /// <param name="modelStorageProvider">The model storage provider. The default model storage provider is <see cref="InMemoryModelStorageProvider"/>.</param> /// <returns></returns> public static IModelPredictionEngineBuilder <TData, TPrediction> WithStorageProvider <TData, TPrediction>( this IModelPredictionEngineBuilder <TData, TPrediction> builder, string storageName, IModelStorageProvider modelStorageProvider = null) where TData : class where TPrediction : class, new() { builder.Services.Configure(builder.ModelName, (Action <ModelPredictionEngineOptions <TData, TPrediction> >)((mlOptions) => { mlOptions.CreateModel = (mlContext) => { if (modelStorageProvider == null) { modelStorageProvider = new InMemoryModelStorageProvider(); } ChangeToken.OnChange( () => modelStorageProvider.GetReloadToken(), () => mlOptions.Reload()); return(GetTransfomer(storageName, mlContext, modelStorageProvider)); }; })); return(builder); }
static void Main(string[] args) { var pluginDir = Path.Combine(AppContext.BaseDirectory, @"Plugins"); if (!Directory.Exists(pluginDir)) { Directory.CreateDirectory(pluginDir); } IFileProvider fileProvider = new PhysicalFileProvider(pluginDir); OldFiles.AddRange(fileProvider.GetDirectoryContents("")); ChangeToken.OnChange(() => fileProvider.Watch("*"), () => { var fileInfos = fileProvider.GetDirectoryContents(""); // 删除的文件 var delFiles = OldFiles.Where(a => !fileInfos.Any(b => b.PhysicalPath == a.PhysicalPath)); // 添加的文件 var addFiles = fileInfos.Where(a => !OldFiles.Any(b => b.PhysicalPath == a.PhysicalPath)); // 修改的文件 判断:新文件中有并且修改时间大于旧文件 var modFiles = OldFiles.Where(a => fileInfos.FirstOrDefault(b => b.PhysicalPath == a.PhysicalPath)?.LastModified > a.LastModified); var allFiles = delFiles.ToDictionary(a => a.Name, status => 3) .Union(addFiles.ToDictionary(a => a.Name, status => 1)) .Union(modFiles.ToDictionary(a => a.Name, status => 2)); Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss.FFFFFF")} {string.Join("\r\n", allFiles.Select(kv => $"{kv.Key} : {(kv.Value==1?"Add":(kv.Value==2?"Mod":"Del"))}"))}"); // 最后文件列表刷新 OldFiles.Clear(); OldFiles.AddRange(fileInfos); }); while (true) { Task.Delay(5 * 1000).Wait(); } }
public LogManager(ITypeLoader typeLoader, IParameterStore parameterStore) { _typeLoader = typeLoader; _parameterStore = parameterStore; _loggerFactory = CreateLoggerFactory(); _logger = _loggerFactory.CreateLogger <LogManager>(); try { ConfigurationBuilder configurationBuilder = new ConfigurationBuilder(); _config = configurationBuilder .SetBasePath(Utility.GetKinesisTapConfigPath()) .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) .Build(); } catch (Exception ex) { _logger.LogError($"Unable to load apsettings.json. {ex.ToMinimized()}"); throw; } ChangeToken.OnChange(() => _config.GetReloadToken(), OnConfigChanged); _updateTimer = new Timer(CheckUpdate, null, Timeout.Infinite, Timeout.Infinite); _configTimer = new Timer(CheckConfig, null, Timeout.Infinite, Timeout.Infinite); }
private static void DisplayChanges(ChangeCollection coll, ChangeToken ct) { if (coll.Count == 0) { Console.WriteLine(string.Format("No changes to {0} since {1} UTC.", listName, GetDateStringFromChangeToken(ct))); return; } Console.ForegroundColor = ConsoleColor.Green; foreach (ChangeItem itm in coll) { Console.WriteLine(); Console.WriteLine(string.Format("List {0} had a Change of type \"{1}\" on the item with Id {2}.", listName, itm.ChangeType.ToString(), itm.ItemId)); } Console.WriteLine(); Console.ResetColor(); }
private static String GetDateStringFromChangeToken(ChangeToken ct) { string ticks = ct.StringValue.Split(';')[3]; DateTime dt = new DateTime(Convert.ToInt64(ticks)); return string.Format("{0} {1}", dt.ToShortDateString(), dt.ToLongTimeString()); }