blob: 189a4b6b60304345b046769a6312b46c2e5537ca [file] [log] [blame]
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Casbin.Model;
namespace Casbin.Caching
{
public class EnforceCache : IEnforceCache
{
private readonly ReaderWriterLockSlim _lockSlim = new();
private Dictionary<string, bool> _memoryCache = new();
public EnforceCache(EnforceCacheOptions options)
{
if (options is not null)
{
CacheOptions = options;
}
}
public EnforceCacheOptions CacheOptions { get; } = new();
public bool TryGetResult<TRequest>(in TRequest requestValues, out bool result)
where TRequest : IRequestValues
{
if (requestValues is null)
{
throw new ArgumentNullException(nameof(requestValues));
}
if (Request.TryGetStringKey(requestValues, out string key) is false)
{
result = false;
return false;
}
if (_lockSlim.TryEnterReadLock(CacheOptions.WaitTimeOut) is false)
{
result = false;
return false;
}
try
{
return _memoryCache.TryGetValue(key, out result);
}
finally
{
_lockSlim.ExitReadLock();
}
}
public Task<bool?> TryGetResultAsync<TRequest>(in TRequest requestValues)
where TRequest : IRequestValues
{
return TryGetResult(requestValues, out bool result)
? Task.FromResult((bool?) result) : Task.FromResult((bool?) null);
}
public bool TrySetResult<TRequest>(in TRequest requestValues, bool result)
where TRequest : IRequestValues
{
if (requestValues is null)
{
throw new ArgumentNullException(nameof(requestValues));
}
if (Request.TryGetStringKey(requestValues, out string key) is false)
{
return false;
}
if (_lockSlim.TryEnterWriteLock(CacheOptions.WaitTimeOut) is false)
{
return false;
}
try
{
_memoryCache[key] = result;
return true;
}
finally
{
_lockSlim.ExitWriteLock();
}
}
public Task<bool> TrySetResultAsync<TRequest>(in TRequest requestValues, bool result)
where TRequest : IRequestValues
{
return Task.FromResult(TrySetResult(requestValues, result));
}
public void Clear()
{
_memoryCache = new Dictionary<string, bool>();
}
#if !NET452
public Task ClearAsync()
{
Clear();
return Task.CompletedTask;
}
#else
public Task ClearAsync()
{
Clear();
return Task.FromResult(false);
}
#endif
}
}