// Copyright (c) Microsoft. All rights reserved. using System.Text.Json; using System.Text.Json.Serialization.Metadata; using System.Threading; using System.Threading.Tasks; using Microsoft.Agents.AI.Purview.Serialization; using Microsoft.Extensions.Caching.Distributed; namespace Microsoft.Agents.AI.Purview; /// /// Manages caching of values. /// internal sealed class CacheProvider : ICacheProvider { private readonly IDistributedCache _cache; private readonly PurviewSettings _purviewSettings; /// /// Create a new instance of the class. /// /// The cache where the data is stored. /// The purview integration settings. public CacheProvider(IDistributedCache cache, PurviewSettings purviewSettings) { this._cache = cache; this._purviewSettings = purviewSettings; } /// /// Get a value from the cache. /// /// The type of the key in the cache. Used for serialization. /// The type of the value in the cache. Used for serialization. /// The key to look up in the cache. /// A cancellation token for the async operation. /// The value in the cache. Null or default if no value is present. public async Task GetAsync(TKey key, CancellationToken cancellationToken) { JsonTypeInfo keyTypeInfo = (JsonTypeInfo)PurviewSerializationUtils.SerializationSettings.GetTypeInfo(typeof(TKey)); string serializedKey = JsonSerializer.Serialize(key, keyTypeInfo); byte[]? data = await this._cache.GetAsync(serializedKey, cancellationToken).ConfigureAwait(false); if (data == null) { return default; } JsonTypeInfo valueTypeInfo = (JsonTypeInfo)PurviewSerializationUtils.SerializationSettings.GetTypeInfo(typeof(TValue)); return JsonSerializer.Deserialize(data, valueTypeInfo); } /// /// Set a value in the cache. /// /// The type of the key in the cache. Used for serialization. /// The type of the value in the cache. Used for serialization. /// The key to identify the cache entry. /// The value to cache. /// A cancellation token for the async operation. /// A task for the async operation. public Task SetAsync(TKey key, TValue value, CancellationToken cancellationToken) { JsonTypeInfo keyTypeInfo = (JsonTypeInfo)PurviewSerializationUtils.SerializationSettings.GetTypeInfo(typeof(TKey)); string serializedKey = JsonSerializer.Serialize(key, keyTypeInfo); JsonTypeInfo valueTypeInfo = (JsonTypeInfo)PurviewSerializationUtils.SerializationSettings.GetTypeInfo(typeof(TValue)); byte[] serializedValue = JsonSerializer.SerializeToUtf8Bytes(value, valueTypeInfo); DistributedCacheEntryOptions cacheOptions = new() { AbsoluteExpirationRelativeToNow = this._purviewSettings.CacheTTL }; return this._cache.SetAsync(serializedKey, serializedValue, cacheOptions, cancellationToken); } /// /// Removes a value from the cache. /// /// The type of the key. /// The key to identify the cache entry. /// The cancellation token for the async operation. /// A task for the async operation. public Task RemoveAsync(TKey key, CancellationToken cancellationToken) { JsonTypeInfo keyTypeInfo = (JsonTypeInfo)PurviewSerializationUtils.SerializationSettings.GetTypeInfo(typeof(TKey)); string serializedKey = JsonSerializer.Serialize(key, keyTypeInfo); return this._cache.RemoveAsync(serializedKey, cancellationToken); } }