using System; using System.Text.Json; using System.Threading.Tasks; using BirdsiteLive.Common.Settings; using BirdsiteLive.Twitter.Models; using Microsoft.Extensions.Caching.Memory; namespace BirdsiteLive.Twitter { public interface ICachedTwitterTweetsService : ITwitterTweetsService { void SetTweet(long id, ExtractedTweet tweet); } public class CachedTwitterTweetsService : ICachedTwitterTweetsService { private readonly ITwitterTweetsService _twitterService; private readonly MemoryCache _tweetCache; private readonly MemoryCacheEntryOptions _cacheEntryOptions; #region Ctor public CachedTwitterTweetsService(ITwitterTweetsService twitterService, InstanceSettings settings) { _twitterService = twitterService; _tweetCache = new MemoryCache(new MemoryCacheOptions() { SizeLimit = settings.TweetCacheCapacity, }); _cacheEntryOptions = new MemoryCacheEntryOptions() .SetSize(1) //Priority on removing when reaching size limit (memory pressure) .SetPriority(CacheItemPriority.Low) // Keep in cache for this time, reset time if accessed. .SetSlidingExpiration(TimeSpan.FromMinutes(60)) // Remove from cache after this time, regardless of sliding expiration .SetAbsoluteExpiration(TimeSpan.FromDays(1)); } #endregion public async Task GetTimelineAsync(string username, long id) { var res = await _twitterService.GetTimelineAsync(username, id); return res; } public async Task GetTweetAsync(long id) { if (!_tweetCache.TryGetValue(id, out Task tweet)) { tweet = _twitterService.GetTweetAsync(id); await _tweetCache.Set(id, tweet, _cacheEntryOptions); } return await tweet; } public void SetTweet(long id, ExtractedTweet tweet) { _tweetCache.Set(id, tweet, _cacheEntryOptions); } } }