Cache tweets

This commit is contained in:
Miss Pasture 2021-05-24 13:24:27 -04:00
parent a5730e37cb
commit 1930ea97c2
5 changed files with 70 additions and 1 deletions

View file

@ -0,0 +1,63 @@
using System;
using BirdsiteLive.Twitter.Models;
using Microsoft.Extensions.Caching.Memory;
namespace BirdsiteLive.Twitter
{
public interface ICachedTwitterTweetsService : ITwitterTweetsService
{
void PurgeTweet(long statusId);
}
public class CachedTwitterTweetsService : ICachedTwitterTweetsService
{
private readonly ITwitterTweetsService _twitterService;
private MemoryCache _tweetCache = new MemoryCache(new MemoryCacheOptions()
{
SizeLimit = 5000
});
private MemoryCacheEntryOptions _cacheEntryOptions = new MemoryCacheEntryOptions()
.SetSize(1)//Size amount
//Priority on removing when reaching size limit (memory pressure)
.SetPriority(CacheItemPriority.High)
// Keep in cache for this time, reset time if accessed.
// We set this lower than a user's in case they delete this Tweet for some reason; we don't need that cached.
.SetSlidingExpiration(TimeSpan.FromHours(2))
// Remove from cache after this time, regardless of sliding expiration
.SetAbsoluteExpiration(TimeSpan.FromDays(7));
#region Ctor
public CachedTwitterTweetsService(ITwitterTweetsService twitterService)
{
_twitterService = twitterService;
}
public ExtractedTweet[] GetTimeline(string username, int nberTweets, long fromTweetId = -1)
{
// This sounds like it'd be silly to cache; pass this directly to TwitterService.
// Theoretically this shouldn't be called more than once every 15 min anyway?
return _twitterService.GetTimeline(username, nberTweets, fromTweetId);
}
public ExtractedTweet GetTweet(long statusId)
{
if(!_tweetCache.TryGetValue(statusId, out ExtractedTweet tweet))
{
tweet = _twitterService.GetTweet(statusId);
// Unlike with the user cache, save the null value anyway to prevent (quicker) API exhaustion.
// It's incredibly unlikely that a tweet with this ID is going to magickally appear within 2 hours.
_tweetCache.Set(statusId, tweet, _cacheEntryOptions);
}
return tweet;
}
#endregion
public void PurgeTweet(long statusId)
{
_tweetCache.Remove(statusId);
}
}
}

View file

@ -11,6 +11,7 @@
<PackageReference Include="Lamar.Microsoft.DependencyInjection" Version="5.0.0" />
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.16.0" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.10.8" />
<PackageReference Include="Microsoft.VisualStudio.Web.BrowserLink" Version="2.2.0" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="3.1.3" />
</ItemGroup>

View file

@ -143,6 +143,7 @@ namespace BirdsiteLive.Controllers
{
var succeeded = await _userService.FollowRequestedAsync(signature, r.Method, r.Path,
r.QueryString.ToString(), RequestHeaders(r.Headers), activity as ActivityFollow, body);
if (succeeded) return Accepted();
else return Unauthorized();
}

View file

@ -91,6 +91,9 @@ namespace BirdsiteLive
services.For<ITwitterUserService>().DecorateAllWith<CachedTwitterUserService>();
services.For<ITwitterUserService>().Use<TwitterUserService>().Singleton();
services.For<ITwitterTweetsService>().DecorateAllWith<CachedTwitterTweetsService>();
services.For<ITwitterTweetsService>().Use<TwitterTweetsService>().Singleton();
services.For<ITwitterAuthenticationInitializer>().Use<TwitterAuthenticationInitializer>().Singleton();
services.Scan(_ =>
@ -117,7 +120,8 @@ namespace BirdsiteLive
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDeveloperExceptionPage();
app.UseBrowserLink();
}
else
{