/*
* Copyright (c) 2022 Vaughn Nugent
*
* Library: VNLib
* Package: VNLib.Data.Caching.Global
* File: GlobalDataCache.cs
*
* GlobalDataCache.cs is part of VNLib.Data.Caching.Global which is part of the larger
* VNLib collection of libraries and utilities.
*
* VNLib.Data.Caching.Global is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation, either version 2 of the License,
* or (at your option) any later version.
*
* VNLib.Data.Caching.Global is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with VNLib.Data.Caching.Global. If not, see http://www.gnu.org/licenses/.
*/
using VNLib.Data.Caching.Global.Exceptions;
namespace VNLib.Data.Caching.Global
{
///
/// A static library for caching data in-process or a remote data
/// cache
///
public static class GlobalDataCache
{
private static IGlobalCacheProvider? CacheProvider;
private static CancellationTokenRegistration _reg;
private static readonly object CacheLock = new();
private static readonly Dictionary> LocalCache = new();
///
/// Gets a value that indicates if global cache is available
///
public static bool IsAvailable => CacheProvider != null && CacheProvider.IsConnected;
///
/// Sets the backing cache provider for the process-wide global cache
///
/// The cache provider instance
/// A token that represents the store's validity
public static void SetProvider(IGlobalCacheProvider cacheProvider, CancellationToken statusToken)
{
CacheProvider = cacheProvider ?? throw new ArgumentNullException(nameof(cacheProvider));
//Remove cache provider when cache provider is no longer valid
_reg = statusToken.Register(Cleanup);
}
private static void Cleanup()
{
CacheProvider = null;
//Clear local cache
lock (CacheLock)
{
LocalCache.Clear();
}
_reg.Dispose();
}
///
/// Asynchronously gets a value from the global cache provider
///
///
/// The key identifying the object to recover from cache
/// The value if found, or null if it does not exist in the store
///
///
public static async Task GetAsync(string key) where T: class
{
//Check local cache first
lock (CacheLock)
{
if (LocalCache.TryGetValue(key, out WeakReference