From 767962f535053b36049e7b863236cd53ba15a144 Mon Sep 17 00:00:00 2001 From: Peter Csajtai Date: Wed, 6 Apr 2022 00:08:17 +0200 Subject: [PATCH] Sync read the file in the data source's constructor, fix GH actions trigger --- .github/workflows/linux-macOS-CI.yml | 1 + .github/workflows/sonar-analysis.yml | 1 + src/ConfigCat.Client.Tests/OverrideTests.cs | 4 +- .../Override/LocalFileDataSource.cs | 94 ++++++------------- 4 files changed, 35 insertions(+), 65 deletions(-) diff --git a/.github/workflows/linux-macOS-CI.yml b/.github/workflows/linux-macOS-CI.yml index acc5eb72..6dbd7d80 100644 --- a/.github/workflows/linux-macOS-CI.yml +++ b/.github/workflows/linux-macOS-CI.yml @@ -1,6 +1,7 @@ name: Build on Linux and macOS on: push: + branches: [ master ] paths-ignore: - '**.md' - 'appveyor*' diff --git a/.github/workflows/sonar-analysis.yml b/.github/workflows/sonar-analysis.yml index 6400fe0c..5b9f2387 100644 --- a/.github/workflows/sonar-analysis.yml +++ b/.github/workflows/sonar-analysis.yml @@ -1,6 +1,7 @@ name: SonarCloud Analysis on: push: + branches: [ master ] paths-ignore: - '**.md' - 'appveyor*' diff --git a/src/ConfigCat.Client.Tests/OverrideTests.cs b/src/ConfigCat.Client.Tests/OverrideTests.cs index 646e9d9b..a22ee16c 100644 --- a/src/ConfigCat.Client.Tests/OverrideTests.cs +++ b/src/ConfigCat.Client.Tests/OverrideTests.cs @@ -362,7 +362,7 @@ public async Task LocalFile_Watcher_Reload() Assert.AreEqual("initial", await client.GetValueAsync("fakeKey", string.Empty)); await WriteContent(SampleFileToCreate, "modified"); - await Task.Delay(1500); + await Task.Delay(2000); Assert.AreEqual("modified", await client.GetValueAsync("fakeKey", string.Empty)); @@ -384,7 +384,7 @@ public async Task LocalFile_Watcher_Reload_Sync() Assert.AreEqual("initial", client.GetValue("fakeKey", string.Empty)); await WriteContent(SampleFileToCreate, "modified"); - await Task.Delay(1500); + await Task.Delay(2000); Assert.AreEqual("modified", client.GetValue("fakeKey", string.Empty)); diff --git a/src/ConfigCatClient/Override/LocalFileDataSource.cs b/src/ConfigCatClient/Override/LocalFileDataSource.cs index d2a6ad37..81d1920e 100644 --- a/src/ConfigCatClient/Override/LocalFileDataSource.cs +++ b/src/ConfigCatClient/Override/LocalFileDataSource.cs @@ -19,7 +19,7 @@ internal sealed class LocalFileDataSource : IOverrideDataSource private readonly ILogger logger; private readonly TaskCompletionSource asyncInit = new(); private readonly ManualResetEvent syncInit = new(false); - private readonly CancellationTokenSource pollerCancellationTokenSource = new(); + private readonly CancellationTokenSource cancellationTokenSource = new(); private volatile IDictionary overrideValues; @@ -28,80 +28,58 @@ public LocalFileDataSource(string filePath, bool autoReload, ILogger logger) if (!File.Exists(filePath)) { logger.Error($"File {filePath} does not exist."); - this.SetInitialized(); return; } this.fullPath = Path.GetFullPath(filePath); this.logger = logger; - this.StartFileReading(autoReload); - } + this.ReloadFile(); - public IDictionary GetOverrides() - { - if (this.overrideValues != null) return this.overrideValues; - this.syncInit.WaitOne(); - return this.overrideValues ?? new Dictionary(); + if (autoReload) + { + this.StartWatch(); + } } - public async Task> GetOverridesAsync() - { - if (this.overrideValues != null) return this.overrideValues; - await this.asyncInit.Task.ConfigureAwait(false); - return this.overrideValues ?? new Dictionary(); - } + public IDictionary GetOverrides() => this.overrideValues ?? new Dictionary(); - private void StartFileReading(bool autoReload) - { - Task.Run(async () => - { - try - { - await ReadFileAsync(); + public Task> GetOverridesAsync() => Task.FromResult(this.overrideValues ?? new Dictionary()); - if (autoReload) - { - await this.StartWatchAsync(); - } - } - finally - { - this.SetInitialized(); - } - }); - } - private async Task StartWatchAsync() + private void StartWatch() { - this.logger.Information($"Watching {this.fullPath} for changes."); - while (!this.pollerCancellationTokenSource.IsCancellationRequested) + Task.Run(async () => { - try + this.logger.Information($"Watching {this.fullPath} for changes."); + while (!this.cancellationTokenSource.IsCancellationRequested) { try { - var lastWriteTime = File.GetLastWriteTimeUtc(this.fullPath); - if (lastWriteTime > this.fileLastWriteTime) + try { - this.logger.Information($"Reload file {this.fullPath}."); - await ReadFileAsync(); + var lastWriteTime = File.GetLastWriteTimeUtc(this.fullPath); + if (lastWriteTime > this.fileLastWriteTime) + { + this.logger.Information($"Reload file {this.fullPath}."); + this.ReloadFile(); + } } - } - finally + finally + { + await Task.Delay(FILE_POLL_INTERVAL, this.cancellationTokenSource.Token); + } + } + catch (OperationCanceledException) { - await Task.Delay(FILE_POLL_INTERVAL, this.pollerCancellationTokenSource.Token); + // ignore exceptions from cancellation. } } - catch (OperationCanceledException) - { - // ignore exceptions from cancellation. - } - } + }); } - private async Task ReadFileAsync() + private void ReloadFile() { try { @@ -109,9 +87,7 @@ private async Task ReadFileAsync() { try { - using var stream = new FileStream(this.fullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); - using var reader = new StreamReader(stream); - var content = await reader.ReadToEndAsync(); + var content = File.ReadAllText(this.fullPath); var simplified = content.DeserializeOrDefault(); if (simplified?.Entries != null) { @@ -130,7 +106,7 @@ private async Task ReadFileAsync() if (i >= MAX_WAIT_ITERATIONS) throw; - await Task.Delay(WAIT_TIME_FOR_UNLOCK); + Thread.Sleep(WAIT_TIME_FOR_UNLOCK); } } } @@ -141,20 +117,12 @@ private async Task ReadFileAsync() finally { this.fileLastWriteTime = File.GetLastWriteTimeUtc(this.fullPath); - this.SetInitialized(); } } - private void SetInitialized() - { - this.syncInit.Set(); - this.asyncInit.TrySetResult(true); - } - public void Dispose() { - this.pollerCancellationTokenSource.Cancel(); - this.syncInit.Dispose(); + this.cancellationTokenSource.Cancel(); } private sealed class SimplifiedConfig