private CompilerCacheResult CreateCacheEntry( string normalizedPath, Func <RelativeFileInfo, CompilationResult> compile) { CompilerCacheResult cacheResult; var fileInfo = _fileProvider.GetFileInfo(normalizedPath); MemoryCacheEntryOptions cacheEntryOptions; CompilerCacheResult cacheResultToCache; if (!fileInfo.Exists) { cacheResultToCache = CompilerCacheResult.FileNotFound; cacheResult = CompilerCacheResult.FileNotFound; cacheEntryOptions = new MemoryCacheEntryOptions(); cacheEntryOptions.AddExpirationToken(_fileProvider.Watch(normalizedPath)); } else { var relativeFileInfo = new RelativeFileInfo(fileInfo, normalizedPath); var compilationResult = compile(relativeFileInfo).EnsureSuccessful(); cacheEntryOptions = GetMemoryCacheEntryOptions(normalizedPath); // By default the CompilationResult returned by IRoslynCompiler is an instance of // UncachedCompilationResult. This type has the generated code as a string property and do not want // to cache it. We'll instead cache the unwrapped result. cacheResultToCache = new CompilerCacheResult( CompilationResult.Successful(compilationResult.CompiledType)); cacheResult = new CompilerCacheResult(compilationResult); } _cache.Set(normalizedPath, cacheResultToCache, cacheEntryOptions); return(cacheResult); }
private void WhitelistChangedCallback(object state) { logger.LogInformation("Reloading whitelist."); SendServerCommand("whitelist reload"); whitelistWatcher = fileProvider.Watch("whitelist.json"); whitelistWatcher.RegisterChangeCallback(WhitelistChangedCallback, null); }
/// <summary> /// Adds version query parameter to the specified file path. /// </summary> /// <param name="path">The path of the file to which version should be added.</param> /// <returns>Path containing the version query string.</returns> /// <remarks> /// The version query string is appended with the key "v". /// </remarks> public string RetrieveBase64Data(string path) { if (path == null) { throw new ArgumentNullException(nameof(path)); } var resolvedPath = path; var queryStringOrFragmentStartIndex = path.IndexOfAny(QueryStringAndFragmentTokens); if (queryStringOrFragmentStartIndex != -1) { resolvedPath = path.Substring(0, queryStringOrFragmentStartIndex); } if (!_cache.TryGetValue(path, out string value)) { var cacheEntryOptions = new MemoryCacheEntryOptions(); cacheEntryOptions.AddExpirationToken(_fileProvider.Watch(resolvedPath)); var fileInfo = _fileProvider.GetFileInfo(resolvedPath); if (!fileInfo.Exists && _requestPathBase.HasValue && resolvedPath.StartsWith(_requestPathBase.Value, StringComparison.OrdinalIgnoreCase)) { var requestPathBaseRelativePath = resolvedPath.Substring(_requestPathBase.Value.Length); cacheEntryOptions.AddExpirationToken(_fileProvider.Watch(requestPathBaseRelativePath)); fileInfo = _fileProvider.GetFileInfo(requestPathBaseRelativePath); } if (fileInfo.Exists) { value = string.Format("{0}{1}", RetrieveBase64Prefix(fileInfo.Name), GetContentsForFile(fileInfo)); } else { // if the file is not in the current server. try to get from internet var bytes = TryRetrieveFileFromInternet(path, out bool existsFileOnInternet); if (existsFileOnInternet) { var image = Convert.ToBase64String(bytes); value = string.Format("{0}{1}", RetrieveBase64Prefix(path), image); } else { value = path; } } value = _cache.Set(path, value, cacheEntryOptions); } return(value); }
public string GetContentHash(string path) { if (path == null) { throw new ArgumentNullException(nameof(path)); } var resolvedPath = path; var queryStringOrFragmentStartIndex = path.IndexOfAny(QueryStringAndFragmentTokens); if (queryStringOrFragmentStartIndex != -1) { resolvedPath = path.Substring(0, queryStringOrFragmentStartIndex); } Uri uri; if (Uri.TryCreate(resolvedPath, UriKind.Absolute, out uri) && !uri.IsFile) { // Don't append version if the path is absolute. return(null); } string value; if (!cache.TryGetValue(path, out value)) { var cacheEntryOptions = new MemoryCacheEntryOptions(); cacheEntryOptions.AddExpirationToken(fileProvider.Watch(resolvedPath)); var fileInfo = fileProvider.GetFileInfo(resolvedPath); if (!fileInfo.Exists && requestPathBase.HasValue && resolvedPath.StartsWith(requestPathBase.Value, StringComparison.OrdinalIgnoreCase)) { var requestPathBaseRelativePath = resolvedPath.Substring(requestPathBase.Value.Length); cacheEntryOptions.AddExpirationToken(fileProvider.Watch(requestPathBaseRelativePath)); fileInfo = fileProvider.GetFileInfo(requestPathBaseRelativePath); } if (fileInfo.Exists) { value = GetHashForFile(fileInfo); } else { // if the file is not in the current server. value = null; } value = cache.Set <string>(path, value, cacheEntryOptions); } return(value); }
public void Test() { Assert.IsFalse(fp.GetDirectoryContents("/nonexisting").Exists); Assert.IsTrue(fp.GetDirectoryContents("/tmp").Exists); Assert.IsTrue(fp.GetDirectoryContents("/tmp/dir").Exists); Assert.IsTrue(fp.GetDirectoryContents("c:").Exists); Assert.IsFalse(fp.GetDirectoryContents("/tmp/helloworld.txt").Exists); Assert.IsTrue(fp.GetFileInfo("/tmp/helloworld.txt").Exists); Assert.IsFalse(fp.GetFileInfo("/tmp").Exists); // Read file using (Stream s = fp.GetFileInfo("/tmp/helloworld.txt").CreateReadStream()) { byte[] data = new byte[100]; int c = s.Read(data, 0, 100); Assert.AreEqual(c, HelloWorld.Length); for (int i = 0; i < c; i++) { Assert.AreEqual(data[i], HelloWorld[i]); } } // Observe IChangeToken token = fp.Watch("/tmp/**"); Semaphore semaphore = new Semaphore(0, int.MaxValue); IDisposable disposable = token.RegisterChangeCallback(o => semaphore.Release(), null); // Test, not activated Assert.IsFalse(semaphore.WaitOne(300)); Assert.IsFalse(token.HasChanged); // Test, not activated ram.CreateFile("/not-monited-path.txt"); Assert.IsFalse(semaphore.WaitOne(300)); Assert.IsFalse(token.HasChanged); // Test, not activated disposable.Dispose(); ram.CreateFile("/tmp/monited-path.txt"); Assert.IsFalse(semaphore.WaitOne(300)); Assert.IsTrue(token.HasChanged); // Observe again token = fp.Watch("/tmp/**"); semaphore = new Semaphore(0, int.MaxValue); disposable = token.RegisterChangeCallback(o => semaphore.Release(), null); ram.CreateFile("/tmp/monited-path-again.txt"); Assert.IsTrue(semaphore.WaitOne(300)); Assert.IsTrue(token.HasChanged); // Shouldn't activate any more ram.CreateFile("/tmp/monited-path-again-one-more-time.txt"); Assert.IsFalse(semaphore.WaitOne(300)); }
public IChangeToken GetChangeToken() { switch (_filters.Count) { case 0: return(NullChangeToken.Singleton); case 1: return(_provider.Watch(_filters[0])); default: return(new CompositeChangeToken(_filters.Select(f => _provider.Watch(f)).ToList())); } }
public virtual IChangeToken Watch(string filter) { if (!ExtraAllowedFolder(filter)) { return(_fileProvider.Watch(_rootPath + filter)); } return(new CompositeChangeToken( new [] { _fileProvider.Watch(_rootPath + filter), _fileProvider.Watch(filter) } )); }
public IChangeToken Watch(string filter) { // We check if the pattern starts with the base path, and remove it if necessary. // otherwise we just pass the pattern through unaltered. PathString newPath; if (TryMapSubPath(filter, out newPath)) { var result = _underlyingFileProvider.Watch(newPath); return(result); } return(_underlyingFileProvider.Watch(newPath)); // return NullChangeToken.Singleton; }
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 BodyEndViewModel BuildBodyEnd(WebsiteModel websiteModel, PageModel pageModel, CategoryModel categoryModel, ProductModel productModel) { string fileName = _memoryCache.Get("LitiumAppJs") as string; if (fileName == null) { lock (_lock) { fileName = _memoryCache.Get("LitiumAppJs") as string; if (fileName == null) { var file = _fileProvider.GetDirectoryContents("ui") .OfType <IFileInfo>() .FirstOrDefault(x => !x.IsDirectory && x.Name.StartsWith("app.", StringComparison.OrdinalIgnoreCase) && x.Name.EndsWith(".js", StringComparison.OrdinalIgnoreCase)); fileName = "/ui/" + file.Name; var changeToken = _fileProvider.Watch(fileName); _memoryCache.Set("LitiumAppJs", fileName, changeToken); } } } var viewModel = new BodyEndViewModel { FileName = fileName, TrackingScripts = _trackingScriptService.GetBodyEndScript(pageModel.Page) }; return(viewModel); }
/// <inheritdoc /> public ChunkTree GetOrAdd( string pagePath, Func <IFileInfo, ChunkTree> getChunkTree) { if (pagePath == null) { throw new ArgumentNullException(nameof(pagePath)); } if (getChunkTree == null) { throw new ArgumentNullException(nameof(getChunkTree)); } ChunkTree chunkTree; if (!_chunkTreeCache.TryGetValue(pagePath, out chunkTree)) { // GetOrAdd is invoked for each _ViewImport that might potentially exist in the path. // We can avoid performing file system lookups for files that do not exist by caching // negative results and adding a Watch for that file. var options = new MemoryCacheEntryOptions() .AddExpirationToken(_fileProvider.Watch(pagePath)) .SetSlidingExpiration(SlidingExpirationDuration); var file = _fileProvider.GetFileInfo(pagePath); chunkTree = file.Exists ? getChunkTree(file) : null; _chunkTreeCache.Set(pagePath, chunkTree, options); } return(chunkTree); }
public DynamicSource(IFileProvider sourceFileProvider) { _sourceFileProvider = sourceFileProvider; // we are providing a change token so that the framework can detect changes to the imported less file ChangeTokenFactory = () => _sourceFileProvider.Watch("/less/*.less"); }
/// <summary> /// Adds version query parameter to the specified file path. /// </summary> /// <param name="path">The path of the file to which version should be added.</param> /// <returns>Path containing the version query string.</returns> /// <remarks> /// The version query string is appended as with the key "v". /// </remarks> public string AddFileVersionToPath([NotNull] string path) { var resolvedPath = path; var fileInfo = _fileProvider.GetFileInfo(resolvedPath); if (!fileInfo.Exists) { if (_requestPathBase.HasValue && resolvedPath.StartsWith(_requestPathBase.Value, StringComparison.OrdinalIgnoreCase)) { resolvedPath = resolvedPath.Substring(_requestPathBase.Value.Length); fileInfo = _fileProvider.GetFileInfo(resolvedPath); } if (!fileInfo.Exists) { // if the file is not in the current server. return(path); } } string value; if (!_cache.TryGetValue(path, out value)) { value = QueryHelpers.AddQueryString(path, VersionKey, GetHashForFile(fileInfo)); _cache.Set( path, value, new MemoryCacheEntryOptions().AddExpirationTrigger(_fileProvider.Watch(resolvedPath))); } return(value); }
private PrecompilationCacheEntry OnCacheMiss(ICacheSetContext cacheSetContext) { var fileInfo = (RelativeFileInfo)cacheSetContext.State; var entry = GetCacheEntry(fileInfo); if (entry != null) { cacheSetContext.AddExpirationTrigger(_fileProvider.Watch(fileInfo.RelativePath)); foreach (var viewStartPath in ViewStartUtility.GetViewStartLocations(fileInfo.RelativePath)) { cacheSetContext.AddExpirationTrigger(_fileProvider.Watch(viewStartPath)); } } return(entry); }
/// <summary> /// Adds version query parameter to the specified file path. /// </summary> /// <param name="path">The path of the file to which version should be added.</param> /// <returns>Path containing the version query string.</returns> /// <remarks> /// The version query string is appended as with the key "v". /// </remarks> public string AddFileVersionToPath([NotNull] string path) { var resolvedPath = path; var fileInfo = _fileProvider.GetFileInfo(resolvedPath); if (!fileInfo.Exists) { if (_requestPathBase.HasValue && resolvedPath.StartsWith(_requestPathBase.Value, StringComparison.OrdinalIgnoreCase)) { resolvedPath = resolvedPath.Substring(_requestPathBase.Value.Length); fileInfo = _fileProvider.GetFileInfo(resolvedPath); } if (!fileInfo.Exists) { // if the file is not in the current server. return(path); } } return(_cache.GetOrSet(path, cacheGetOrSetContext => { var trigger = _fileProvider.Watch(resolvedPath); cacheGetOrSetContext.AddExpirationTrigger(trigger); return QueryHelpers.AddQueryString(path, VersionKey, GetHashForFile(fileInfo)); })); }
/// <summary> /// Registers a file to be watched with a callback for when it is modified /// </summary> /// <param name="webFile"></param> /// <param name="fileInfo"></param> /// <param name="bundleOptions"></param> /// <param name="fileModifiedCallback"></param> /// <returns> /// Returns true if a watcher was added, false if the file is already being watched /// </returns> public bool Watch(IWebFile webFile, IFileInfo fileInfo, BundleOptions bundleOptions, Action <WatchedFile> fileModifiedCallback) { var path = webFile.FilePath.TrimStart(new[] { '~' }).ToLowerInvariant(); //don't double watch if there's already a watcher for this file if (_fileWatchers.ContainsKey(path)) { return(false); } var watchedFile = new WatchedFile(webFile, fileInfo, bundleOptions); var changeToken = _fileProvider.Watch(path); _fileWatchers.TryAdd(path, changeToken.RegisterChangeCallback(o => { //try to remove the item from the dictionary so it can be added again IDisposable watcher; _fileWatchers.TryRemove(path, out watcher); //call the callback with the strongly typed object fileModifiedCallback((WatchedFile)o); }, watchedFile)); return(true); }
protected virtual 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(() => _fileProvider.Watch(_filePath.EnsureEndsWith('/') + "*.*"), () => { _dictionaries = null; }); _subscribedForChanges = true; } dictionaries = _dictionaries = CreateDictionaries(); } return(dictionaries); }
public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) { var path = Href; // Get the value from the cache, or compute the value and add it to the cache var fileContent = await Cache.GetOrCreateAsync("InlineStyleTagHelper-" + path, async entry => { IFileProvider fileProvider = HostingEnvironment.WebRootFileProvider; IChangeToken changeToken = fileProvider.Watch(path); entry.SetPriority(CacheItemPriority.NeverRemove); entry.AddExpirationToken(changeToken); IFileInfo file = fileProvider.GetFileInfo(path); if (file == null || !file.Exists) { return(null); } return(await ReadFileContent(file)); }); if (fileContent == null) { output.SuppressOutput(); return; } output.TagName = "style"; output.Attributes.RemoveAll("href"); output.Content.AppendHtml(fileContent); }
public Task AwaitChange(string filter, CancellationToken ct = default) { var tcs = new TaskCompletionSource <int>(); var token = _fileProvider.Watch(filter); token.RegisterChangeCallback(_ => tcs.TrySetResult(0), null); return(tcs.Task); }
public IChangeToken GetChangeToken() { var changeTokens = new IChangeToken[_additionalFilesToTrack.Length + _searchPatterns.Length]; for (var i = 0; i < _additionalFilesToTrack.Length; i++) { changeTokens[i] = _fileProvider.Watch(_additionalFilesToTrack[i]); } for (var i = 0; i < _searchPatterns.Length; i++) { var wildcardChangeToken = _fileProvider.Watch(_searchPatterns[i]); changeTokens[_additionalFilesToTrack.Length + i] = wildcardChangeToken; } return(new CompositeChangeToken(changeTokens)); }
private void WatchFile(IFileProvider fileProvider) { if (LoadFileAsync != null) { ChangeToken.OnChange(() => fileProvider.Watch(System.IO.Path.GetFileName(Path)), () => LoadFileAsync(fileProvider)); } }
private static void RegisterWatchCallback() { var packageFile = configuration.GetValue <string>("WatchedPackageFile"); var fileInfo = fileProvider.GetFileInfo(packageFile); var token = fileProvider.Watch(packageFile); changeToken = token.RegisterChangeCallback(OnPackageChange, fileInfo); }
public BodyEndViewModel BuildBodyEnd() { var pageModel = _requestModelAccessor.RequestModel.CurrentPageModel; string fileName = GetFileName("es6"); string fileNameEs5 = GetFileName("es5"); var viewModel = new BodyEndViewModel { FileName = fileName, FileNameEs5 = fileNameEs5, TrackingScripts = _trackingScriptService.GetBodyEndScript(pageModel.Page) }; return(viewModel); string GetFileName(string folder) { var cacheKey = "LitiumAppJs" + folder; string fileName = _memoryCache.Get(cacheKey) as string; if (fileName == null) { lock (_lock) { fileName = _memoryCache.Get(cacheKey) as string; if (fileName == null) { var fileInfos = _fileProvider.GetDirectoryContents(System.IO.Path.Combine("ui", folder)).OfType <IFileInfo>(); var file = fileInfos .FirstOrDefault(x => !x.IsDirectory && x.Name.StartsWith("app.", StringComparison.OrdinalIgnoreCase) && x.Name.EndsWith(".js", StringComparison.OrdinalIgnoreCase)); if (file == null) { throw new Exception("You need to compile the client library."); } fileName = $"/ui/{folder}/{file.Name}"; if (_hostingEnvironment.IsDevelopment()) { var changeToken = _fileProvider.Watch(fileName); _memoryCache.Set(cacheKey, fileName, changeToken); } else { _memoryCache.Set(cacheKey, fileName); } } } } return(fileName); } }
public void WatchThis(string path) { var token = _fileProvider.Watch(path); token.RegisterChangeCallback((_) => { System.Diagnostics.Debugger.Launch(); System.Diagnostics.Debugger.Break(); }, null); }
public IChangeToken GetChangeToken() { var wildcardChangeToken = _fileProvider.Watch(_searchPattern); if (_additionalFilesToTrack.Length == 0) { return(wildcardChangeToken); } var changeTokens = new IChangeToken[_additionalFilesToTrack.Length + 1]; for (var i = 0; i < _additionalFilesToTrack.Length; i++) { changeTokens[i] = _fileProvider.Watch(_additionalFilesToTrack[i]); } changeTokens[changeTokens.Length - 1] = wildcardChangeToken; return(new CompositeChangeToken(changeTokens)); }
public async Task WatchAsync(string path) { Console.WriteLine(await ReadAsync(path)); ChangeToken.OnChange(() => _fileProvider.Watch(path), async() => { Console.Clear(); Console.WriteLine(await ReadAsync(path)); }); }
/// <summary> /// 监视和检查Sql文件夹 /// </summary> private void WatchAndCheckSqlDir() { foreach (var subpath in _options.Path) { var dir = _fileProvider.GetDirectoryContents(subpath); if (!dir.Exists) { throw new DirectoryNotFoundException($"SQL文件目录不存在:{subpath}"); } var watchFileFilter = $"{subpath}/**/{_options.WatchFileFilter ?? "*.*"}"; Action <object> callback = null; callback = _ => { Clear(); _fileProvider.Watch(watchFileFilter).RegisterChangeCallback(callback, null); }; _fileProvider.Watch(watchFileFilter).RegisterChangeCallback(callback, null); } }
/// <summary> /// Create observer for one file. /// </summary> /// <param name="assetSource"></param> /// <param name="fileProvider"></param> /// <param name="observer"></param> /// <param name="filePath"></param> public FileProviderObserver(IAssetSource assetSource, IFileProvider fileProvider, IObserver <IAssetSourceEvent> observer, string filePath) { this.assetSource = assetSource ?? throw new ArgumentNullException(nameof(assetSource)); this.observer = observer ?? throw new ArgumentNullException(nameof(observer)); this.FilePath = filePath ?? throw new ArgumentNullException(nameof(filePath)); this.fileProvider = fileProvider ?? throw new ArgumentNullException(nameof(fileProvider)); existed = fileProvider.GetFileInfo(filePath).Exists ? 1 : 0; IChangeToken changeToken = fileProvider.Watch(filePath); watcher = changeToken.RegisterChangeCallback(OnEvent, this); }
/// <summary> /// Adds string value to memory cache. /// </summary> protected void AddToCache(string cacheKey, string value, IFileProvider fileProvider, params string[] files) { var cacheOptions = new MemoryCacheEntryOptions(); foreach (string file in files) { cacheOptions.AddExpirationToken(fileProvider.Watch(file)); } Cache.Set(cacheKey, value, cacheOptions); }
public static IConfigurationRoot ReloadOnChanged( this IConfigurationRoot config, IFileProvider fileProvider, string filename) { if (config == null) { throw new ArgumentNullException(nameof(config)); } if (fileProvider == null) { throw new ArgumentNullException(nameof(fileProvider)); } if (filename == null) { throw new ArgumentNullException(nameof(filename)); } Action<object> callback = null; callback = _ => { // The order here is important. We need to take the token and then apply our changes BEFORE // registering. This prevents us from possible having two change updates to process concurrently. // // If the file changes after we take the token, then we'll process the update immediately upon // registering the callback. var token = fileProvider.Watch(filename); config.Reload(); token.RegisterChangeCallback(callback, null); }; fileProvider.Watch(filename).RegisterChangeCallback(callback, null); return config; }