forked from ThreeMammals/Ocelot
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Made the file config poller use IHostedService, bit more generic, not… (
ThreeMammals#507) * Made the file config poller use IHostedService, bit more generic, not just need to provide the correct implementations of the repo services and it will poll anything..this means we can open up redis for ThreeMammals#458 * removed comments
- Loading branch information
1 parent
1817564
commit 0f2cf2d
Showing
8 changed files
with
798 additions
and
763 deletions.
There are no files selected for viewing
196 changes: 112 additions & 84 deletions
196
...pository/ConsulFileConfigurationPoller.cs → ...ion/Repository/FileConfigurationPoller.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,84 +1,112 @@ | ||
using System; | ||
using System.Linq; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using Newtonsoft.Json; | ||
using Ocelot.Configuration.File; | ||
using Ocelot.Configuration.Setter; | ||
using Ocelot.Logging; | ||
|
||
namespace Ocelot.Configuration.Repository | ||
{ | ||
public class ConsulFileConfigurationPoller : IDisposable | ||
{ | ||
private readonly IOcelotLogger _logger; | ||
private readonly IFileConfigurationRepository _repo; | ||
private readonly IFileConfigurationSetter _setter; | ||
private string _previousAsJson; | ||
private readonly Timer _timer; | ||
private bool _polling; | ||
private readonly IConsulPollerConfiguration _config; | ||
|
||
public ConsulFileConfigurationPoller( | ||
IOcelotLoggerFactory factory, | ||
IFileConfigurationRepository repo, | ||
IFileConfigurationSetter setter, | ||
IConsulPollerConfiguration config) | ||
{ | ||
_setter = setter; | ||
_config = config; | ||
_logger = factory.CreateLogger<ConsulFileConfigurationPoller>(); | ||
_repo = repo; | ||
_previousAsJson = ""; | ||
_timer = new Timer(async x => | ||
{ | ||
if(_polling) | ||
{ | ||
return; | ||
} | ||
|
||
_polling = true; | ||
await Poll(); | ||
_polling = false; | ||
}, null, _config.Delay, _config.Delay); | ||
} | ||
|
||
private async Task Poll() | ||
{ | ||
_logger.LogInformation("Started polling consul"); | ||
|
||
var fileConfig = await _repo.Get(); | ||
|
||
if(fileConfig.IsError) | ||
{ | ||
_logger.LogWarning($"error geting file config, errors are {string.Join(",", fileConfig.Errors.Select(x => x.Message))}"); | ||
return; | ||
} | ||
|
||
var asJson = ToJson(fileConfig.Data); | ||
|
||
if(!fileConfig.IsError && asJson != _previousAsJson) | ||
{ | ||
await _setter.Set(fileConfig.Data); | ||
_previousAsJson = asJson; | ||
} | ||
|
||
_logger.LogInformation("Finished polling consul"); | ||
} | ||
|
||
/// <summary> | ||
/// We could do object comparison here but performance isnt really a problem. This might be an issue one day! | ||
/// </summary> | ||
/// <returns>hash of the config</returns> | ||
private string ToJson(FileConfiguration config) | ||
{ | ||
var currentHash = JsonConvert.SerializeObject(config); | ||
return currentHash; | ||
} | ||
|
||
public void Dispose() | ||
{ | ||
_timer.Dispose(); | ||
} | ||
} | ||
} | ||
using System; | ||
using System.Linq; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using Microsoft.Extensions.Hosting; | ||
using Newtonsoft.Json; | ||
using Ocelot.Configuration.Creator; | ||
using Ocelot.Configuration.File; | ||
using Ocelot.Configuration.Setter; | ||
using Ocelot.Logging; | ||
|
||
namespace Ocelot.Configuration.Repository | ||
{ | ||
public class FileConfigurationPoller : IHostedService, IDisposable | ||
{ | ||
private readonly IOcelotLogger _logger; | ||
private readonly IFileConfigurationRepository _repo; | ||
private string _previousAsJson; | ||
private Timer _timer; | ||
private bool _polling; | ||
private readonly IFileConfigurationPollerOptions _options; | ||
private readonly IInternalConfigurationRepository _internalConfigRepo; | ||
private readonly IInternalConfigurationCreator _internalConfigCreator; | ||
|
||
public FileConfigurationPoller( | ||
IOcelotLoggerFactory factory, | ||
IFileConfigurationRepository repo, | ||
IFileConfigurationPollerOptions options, | ||
IInternalConfigurationRepository internalConfigRepo, | ||
IInternalConfigurationCreator internalConfigCreator) | ||
{ | ||
_internalConfigRepo = internalConfigRepo; | ||
_internalConfigCreator = internalConfigCreator; | ||
_options = options; | ||
_logger = factory.CreateLogger<FileConfigurationPoller>(); | ||
_repo = repo; | ||
_previousAsJson = ""; | ||
} | ||
|
||
public Task StartAsync(CancellationToken cancellationToken) | ||
{ | ||
_logger.LogInformation($"{nameof(FileConfigurationPoller)} is starting."); | ||
|
||
_timer = new Timer(async x => | ||
{ | ||
if(_polling) | ||
{ | ||
return; | ||
} | ||
|
||
_polling = true; | ||
await Poll(); | ||
_polling = false; | ||
}, null, _options.Delay, _options.Delay); | ||
|
||
return Task.CompletedTask; | ||
} | ||
|
||
public Task StopAsync(CancellationToken cancellationToken) | ||
{ | ||
_logger.LogInformation($"{nameof(FileConfigurationPoller)} is stopping."); | ||
|
||
_timer?.Change(Timeout.Infinite, 0); | ||
|
||
return Task.CompletedTask; | ||
} | ||
|
||
private async Task Poll() | ||
{ | ||
_logger.LogInformation("Started polling consul"); | ||
|
||
var fileConfig = await _repo.Get(); | ||
|
||
if(fileConfig.IsError) | ||
{ | ||
_logger.LogWarning($"error geting file config, errors are {string.Join(",", fileConfig.Errors.Select(x => x.Message))}"); | ||
return; | ||
} | ||
|
||
var asJson = ToJson(fileConfig.Data); | ||
|
||
if(!fileConfig.IsError && asJson != _previousAsJson) | ||
{ | ||
var config = await _internalConfigCreator.Create(fileConfig.Data); | ||
|
||
if(!config.IsError) | ||
{ | ||
_internalConfigRepo.AddOrReplace(config.Data); | ||
} | ||
|
||
_previousAsJson = asJson; | ||
} | ||
|
||
_logger.LogInformation("Finished polling consul"); | ||
} | ||
|
||
/// <summary> | ||
/// We could do object comparison here but performance isnt really a problem. This might be an issue one day! | ||
/// </summary> | ||
/// <returns>hash of the config</returns> | ||
private string ToJson(FileConfiguration config) | ||
{ | ||
var currentHash = JsonConvert.SerializeObject(config); | ||
return currentHash; | ||
} | ||
|
||
public void Dispose() | ||
{ | ||
_timer.Dispose(); | ||
} | ||
} | ||
} |
2 changes: 1 addition & 1 deletion
2
src/Ocelot/Configuration/Repository/IConsulPollerConfiguration.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...tory/InMemoryConsulPollerConfiguration.cs → ...InMemoryFileConfigurationPollerOptions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.