Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce MemoryCacheProvider #74

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,10 @@ var isValid = domainParser.IsValidDomain("sub.test.co.uk");
// after -> var builder = WebApplication.CreateBuilder(args);

builder.Services.AddHttpClient(); //Required for CachedHttpRuleProvider
// You can use LocalFileSystemCacheProvider to store the cache in your as a local file - improves memory usage
builder.Services.AddSingleton<ICacheProvider, LocalFileSystemCacheProvider>();
// Or you can use with is recommended for Azure functions or application where you don't have files access permission
// builder.Services.AddSingleton<ICacheProvider, MemoryCacheProvider>();
builder.Services.AddSingleton<IRuleProvider, CachedHttpRuleProvider>();
builder.Services.AddSingleton<IDomainParser, DomainParser>();

Expand Down
32 changes: 29 additions & 3 deletions src/Nager.PublicSuffix.TestConsole/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@
using Nager.PublicSuffix;
using Nager.PublicSuffix.RuleProviders;

Console.WriteLine("Run - DemoCachedHttpRuleProviderAsync");
await DemoCachedHttpRuleProviderAsync();
Console.WriteLine("Run - DemoLocalFileCachedHttpRuleProviderAsync");
await DemoLocalFileCachedHttpRuleProviderAsync();
Console.WriteLine("Run - DemoMemoryCachedHttpRuleProviderAsync");
await DemoMemoryCachedHttpRuleProviderAsync();
Console.WriteLine("Run - DemoSimpleHttpRuleProviderAsync");
await DemoSimpleHttpRuleProviderAsync();
Console.WriteLine("Run - DemoLocalFileRuleProviderAsync");
await DemoLocalFileRuleProviderAsync();

async Task DemoCachedHttpRuleProviderAsync()
async Task DemoLocalFileCachedHttpRuleProviderAsync()
{
using var loggerFactory = LoggerFactory.Create(builder =>
{
Expand All @@ -34,6 +36,30 @@ async Task DemoCachedHttpRuleProviderAsync()
await CheckAsync(ruleProvider);
}

async Task DemoMemoryCachedHttpRuleProviderAsync()
{
using var loggerFactory = LoggerFactory.Create(builder =>
{
builder.AddConsole();
});

var ruleProviderLogger = loggerFactory.CreateLogger<CachedHttpRuleProvider>();

IConfiguration configuration = new ConfigurationBuilder()
.AddInMemoryCollection(new List<KeyValuePair<string, string?>>
{
new("Nager:PublicSuffix:DataUrl", "https://publicsuffix.org/list/public_suffix_list.dat")
})
.Build();

using var httpClient = new HttpClient();
var cacheProvider = new Nager.PublicSuffix.RuleProviders.CacheProviders.MemoryCacheProvider();

var ruleProvider = new CachedHttpRuleProvider(ruleProviderLogger, configuration, cacheProvider, httpClient);

await CheckAsync(ruleProvider);
}

async Task DemoSimpleHttpRuleProviderAsync()
{
using var ruleProvider = new SimpleHttpRuleProvider();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using System;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Nager.PublicSuffix.RuleProviders.CacheProviders;

namespace Nager.PublicSuffix.UnitTest.CacheProviders;

[TestClass]
public class MemoryCacheProviderTest
{
private MemoryCacheProvider _target;

[TestInitialize]
public void Initialize()
{
_target = new MemoryCacheProvider();
}

[TestMethod]
public async Task No_Data_Set()
{
Assert.IsFalse(_target.IsCacheValid());
Assert.IsNull(await _target.GetAsync()!);
}

[TestMethod]
public async Task Valid_Data_Set()
{
await _target.SetAsync("d");
Assert.IsTrue(_target.IsCacheValid());
Assert.AreEqual("d", await _target.GetAsync()!);
}

[TestMethod]
public async Task Expired_Data_Set()
{
_target = new MemoryCacheProvider(TimeSpan.FromMilliseconds(500));
await _target.SetAsync("d");
await Task.Delay(1000);
Assert.IsFalse(_target.IsCacheValid());
Assert.IsNull(await _target.GetAsync()!);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using System;
using System.Threading.Tasks;

namespace Nager.PublicSuffix.RuleProviders.CacheProviders
{
/// <summary>
/// MemoryCacheProvider, uses memory to cache the data, mostly used for testing Azure functions
/// </summary>
public class MemoryCacheProvider : ICacheProvider
{
private readonly TimeSpan _timeToLive;
private DateTime _lastWriteTimeUtc;
private string? _data;

/// <summary>
/// MemoryCacheProvider
/// </summary>
/// <param name="cacheTimeToLive"></param>
public MemoryCacheProvider(TimeSpan? cacheTimeToLive = null)
{
_timeToLive = cacheTimeToLive ?? TimeSpan.FromDays(1);
}

/// <inheritdoc/>
public bool IsCacheValid()
{
return _lastWriteTimeUtc > DateTime.UtcNow.Subtract(_timeToLive);
}

/// <inheritdoc/>
public Task<string?> GetAsync()
{
return Task.FromResult(IsCacheValid() ? _data : null);
}

/// <inheritdoc/>
public Task SetAsync(string data)
{
_data = data;
_lastWriteTimeUtc = DateTime.UtcNow;
return Task.CompletedTask;
}
}
}