-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Activate ChangeToken when Ocelot's configuration changes #1037
* Add configuration change token (#1036) * Add IOptionsMonitor<IInternalConfiguration> * Activate change token from *ConfigurationRepository instead of FileAndInternalConfigurationSetter; add acceptance & integration tests * Update documentation * Use IWebHostEnvironment as IHostingEnvironment deprecated Co-authored-by: Chris Swinchatt <[email protected]>
- Loading branch information
1 parent
473d50f
commit 86e8d66
Showing
17 changed files
with
1,546 additions
and
1,111 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
14 changes: 14 additions & 0 deletions
14
src/Ocelot/Configuration/ChangeTracking/IOcelotConfigurationChangeTokenSource.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 |
---|---|---|
@@ -0,0 +1,14 @@ | ||
namespace Ocelot.Configuration.ChangeTracking | ||
{ | ||
using Microsoft.Extensions.Primitives; | ||
|
||
/// <summary> | ||
/// <see cref="IChangeToken" /> source which is activated when Ocelot's configuration is changed. | ||
/// </summary> | ||
public interface IOcelotConfigurationChangeTokenSource | ||
{ | ||
IChangeToken ChangeToken { get; } | ||
|
||
void Activate(); | ||
} | ||
} |
74 changes: 74 additions & 0 deletions
74
src/Ocelot/Configuration/ChangeTracking/OcelotConfigurationChangeToken.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 |
---|---|---|
@@ -0,0 +1,74 @@ | ||
namespace Ocelot.Configuration.ChangeTracking | ||
{ | ||
using System; | ||
using System.Collections.Generic; | ||
using Microsoft.Extensions.Primitives; | ||
|
||
public class OcelotConfigurationChangeToken : IChangeToken | ||
{ | ||
public const double PollingIntervalSeconds = 1; | ||
|
||
private readonly ICollection<CallbackWrapper> _callbacks = new List<CallbackWrapper>(); | ||
private readonly object _lock = new object(); | ||
private DateTime? _timeChanged; | ||
|
||
public IDisposable RegisterChangeCallback(Action<object> callback, object state) | ||
{ | ||
lock (_lock) | ||
{ | ||
var wrapper = new CallbackWrapper(callback, state, _callbacks, _lock); | ||
_callbacks.Add(wrapper); | ||
return wrapper; | ||
} | ||
} | ||
|
||
public void Activate() | ||
{ | ||
lock (_lock) | ||
{ | ||
_timeChanged = DateTime.UtcNow; | ||
foreach (var wrapper in _callbacks) | ||
{ | ||
wrapper.Invoke(); | ||
} | ||
} | ||
} | ||
|
||
// Token stays active for PollingIntervalSeconds after a change (could be parameterised) - otherwise HasChanged would be true forever. | ||
// Taking suggestions for better ways to reset HasChanged back to false. | ||
public bool HasChanged => _timeChanged.HasValue && (DateTime.UtcNow - _timeChanged.Value).TotalSeconds < PollingIntervalSeconds; | ||
|
||
public bool ActiveChangeCallbacks => true; | ||
|
||
private class CallbackWrapper : IDisposable | ||
{ | ||
private readonly ICollection<CallbackWrapper> _callbacks; | ||
private readonly object _lock; | ||
|
||
public CallbackWrapper(Action<object> callback, object state, ICollection<CallbackWrapper> callbacks, object @lock) | ||
{ | ||
_callbacks = callbacks; | ||
_lock = @lock; | ||
Callback = callback; | ||
State = state; | ||
} | ||
|
||
public void Invoke() | ||
{ | ||
Callback.Invoke(State); | ||
} | ||
|
||
public void Dispose() | ||
{ | ||
lock (_lock) | ||
{ | ||
_callbacks.Remove(this); | ||
} | ||
} | ||
|
||
public Action<object> Callback { get; } | ||
|
||
public object State { get; } | ||
} | ||
} | ||
} |
16 changes: 16 additions & 0 deletions
16
src/Ocelot/Configuration/ChangeTracking/OcelotConfigurationChangeTokenSource.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 |
---|---|---|
@@ -0,0 +1,16 @@ | ||
namespace Ocelot.Configuration.ChangeTracking | ||
{ | ||
using Microsoft.Extensions.Primitives; | ||
|
||
public class OcelotConfigurationChangeTokenSource : IOcelotConfigurationChangeTokenSource | ||
{ | ||
private readonly OcelotConfigurationChangeToken _changeToken = new OcelotConfigurationChangeToken(); | ||
|
||
public IChangeToken ChangeToken => _changeToken; | ||
|
||
public void Activate() | ||
{ | ||
_changeToken.Activate(); | ||
} | ||
} | ||
} |
30 changes: 30 additions & 0 deletions
30
src/Ocelot/Configuration/ChangeTracking/OcelotConfigurationMonitor.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 |
---|---|---|
@@ -0,0 +1,30 @@ | ||
namespace Ocelot.Configuration.ChangeTracking | ||
{ | ||
using System; | ||
using Microsoft.Extensions.Options; | ||
using Ocelot.Configuration.Repository; | ||
|
||
public class OcelotConfigurationMonitor : IOptionsMonitor<IInternalConfiguration> | ||
{ | ||
private readonly IOcelotConfigurationChangeTokenSource _changeTokenSource; | ||
private readonly IInternalConfigurationRepository _repo; | ||
|
||
public OcelotConfigurationMonitor(IInternalConfigurationRepository repo, IOcelotConfigurationChangeTokenSource changeTokenSource) | ||
{ | ||
_changeTokenSource = changeTokenSource; | ||
_repo = repo; | ||
} | ||
|
||
public IInternalConfiguration Get(string name) | ||
{ | ||
return _repo.Get().Data; | ||
} | ||
|
||
public IDisposable OnChange(Action<IInternalConfiguration, string> listener) | ||
{ | ||
return _changeTokenSource.ChangeToken.RegisterChangeCallback(_ => listener(CurrentValue, ""), null); | ||
} | ||
|
||
public IInternalConfiguration CurrentValue => _repo.Get().Data; | ||
} | ||
} |
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
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.