using System;
using System.Threading.Tasks;
namespace Config.Net.Core
{
///
/// Implements a lazy value i.e. that can expire in future
///
///
class LazyVar where T : class
{
private readonly Func>? _renewFuncAsync;
private readonly Func? _renewFunc;
private DateTime _lastRenewed = DateTime.MinValue;
private readonly TimeSpan _timeToLive;
private T? _value;
///
/// Creates an instance of a lazy variable with time-to-live value
///
/// Time to live. Setting to disables caching completely
///
public LazyVar(TimeSpan timeToLive, Func> renewFunc)
{
_timeToLive = timeToLive;
_renewFuncAsync = renewFunc ?? throw new ArgumentNullException(nameof(renewFunc));
_renewFunc = null;
}
///
/// Creates an instance of a lazy variable with time-to-live value
///
/// Time to live. Setting to disables caching completely
///
public LazyVar(TimeSpan timeToLive, Func renewFunc)
{
_timeToLive = timeToLive;
_renewFuncAsync = null;
_renewFunc = renewFunc ?? throw new ArgumentNullException(nameof(renewFunc));
}
///
/// Gets the values, renewing it if necessary
///
/// Value
public async Task GetValueAsync()
{
if (_renewFuncAsync == null)
{
throw new InvalidOperationException("cannot renew value, async delegate is not specified");
}
if (_timeToLive == TimeSpan.Zero)
{
return await _renewFuncAsync();
}
bool expired = (DateTime.UtcNow - _lastRenewed) > _timeToLive;
if (expired)
{
_value = await _renewFuncAsync();
_lastRenewed = DateTime.UtcNow;
}
return _value;
}
///
/// Gets the values, renewing it if necessary
///
/// Value
public T? GetValue()
{
if (_renewFunc == null)
{
throw new InvalidOperationException("cannot renew value, synchronous delegate is not specified");
}
if (_timeToLive == TimeSpan.Zero)
{
return _renewFunc();
}
bool expired = (DateTime.UtcNow - _lastRenewed) > _timeToLive;
if (expired)
{
_value = _renewFunc();
_lastRenewed = DateTime.UtcNow;
}
return _value;
}
}
}