Skip to content

Commit

Permalink
Changed the way cache is initialized
Browse files Browse the repository at this point in the history
  • Loading branch information
kubagdynia committed Dec 4, 2023
1 parent 9589bd7 commit 1548bae
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 34 deletions.
8 changes: 0 additions & 8 deletions CacheDrive.Tests/CachingObjectsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@ public async Task ObjectShouldBeProperlyCachedAndRestoredFromTheMemory()

ICacheService cacheService = serviceProvider.GetRequiredService<ICacheService>();

await cacheService.InitializeAsync();

// Act
await cacheService.SetAsync(_testClass.Id.ToString(), _testClass);

Expand All @@ -62,8 +60,6 @@ public async Task ObjectShoulBeProperlyCachedInMemoryAndPersistedToTheFile()

ICacheService cacheService = serviceProvider.GetRequiredService<ICacheService>();

await cacheService.InitializeAsync();

// Act
await cacheService.SetAsync(_testClass.Id.ToString(), _testClass);

Expand All @@ -88,8 +84,6 @@ public async Task CacheShouldBeProperlyLoadedFromTheFile_Then_ObjectShouldBeProp

ICacheService cacheService = serviceProvider.GetRequiredService<ICacheService>();

await cacheService.InitializeAsync();

// Act
var cachedTestClass = await cacheService.GetAsync<TestClass>(_testClass.Id.ToString());

Expand All @@ -111,8 +105,6 @@ public async Task CacheShouldExpiredDuringLoadedFromTheFile_Then_ObjectShouldNot
cacheType: CacheType.MemoryAndFile);

ICacheService cacheService = serviceProvider.GetRequiredService<ICacheService>();

await cacheService.InitializeAsync();

// Act
var cachedTestClass = await cacheService.GetAsync<TestClass>(_testClass.Id.ToString());
Expand Down
6 changes: 0 additions & 6 deletions CacheDrive.Tests/CachingSimpleTypesTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ public async Task SimpleTypesShouldBeProperlyCachedAndRestoredFromTheMemory()

ICacheService cacheService = serviceProvider.GetRequiredService<ICacheService>();

await cacheService.InitializeAsync();

// Act
(string key, int value) intItem = ("int_test", 10);
await cacheService.SetAsync(intItem.key, intItem.value);
Expand All @@ -45,8 +43,6 @@ public async Task SimpleTypesShouldBeProperlyCachedAndRestoredFromTheMemory()
double cachedDoubleItem = await cacheService.GetAsync<double>(doubleItem.key);
bool cachedBoolItem = await cacheService.GetAsync<bool>(boolItem.key);

await cacheService.FlushAsync();

// Assert
cachedIntItem.Should().Be(intItem.value);
cachedCharItem.Should().Be(charItem.value);
Expand All @@ -68,8 +64,6 @@ public async Task SimpleTypesShouldBeProperlyDeletedFromTheMemoryCache()

ICacheService cacheService = serviceProvider.GetRequiredService<ICacheService>();

await cacheService.InitializeAsync();

// Act

// Add 50 items
Expand Down
8 changes: 3 additions & 5 deletions CacheDrive.Tests/MemoryAndFileTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ public async Task CacheShouldBeSavedCorrectly()
ServiceProvider serviceProvider = TestHelper.CreateServiceProvider(DateTime.Now);

ICacheService cacheService = serviceProvider.GetRequiredService<ICacheService>();

await cacheService.InitializeAsync();

// Act
string key = "name";
Expand All @@ -26,13 +24,15 @@ public async Task CacheShouldBeSavedCorrectly()
if (cacheService.TryGetValue(key, out string cachedValue))
{
cachedValue.Should().Be("John");
await cacheService.FlushAsync();
await cacheService.FlushAsync();
}
else
{
await cacheService.FlushAsync();
Assert.Fail();
}

await cacheService.FlushAsync();
}

[Test, Order(2)]
Expand All @@ -42,7 +42,6 @@ public async Task CacheShouldBeLoadCorrectly()
ServiceProvider serviceProvider = TestHelper.CreateServiceProvider(DateTime.Now);

ICacheService cacheService = serviceProvider.GetRequiredService<ICacheService>();
await cacheService.InitializeAsync();

string key = "name";

Expand All @@ -66,7 +65,6 @@ public async Task CacheShouldExpired()
ServiceProvider serviceProvider = TestHelper.CreateServiceProvider(DateTime.Now.AddHours(3));

ICacheService cacheService = serviceProvider.GetRequiredService<ICacheService>();
await cacheService.InitializeAsync();

string key = "name";

Expand Down
11 changes: 6 additions & 5 deletions CacheDrive.Tests/MemoryTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,20 @@ public class MemoryTests
public async Task StringShouldBeCorrectlySavedAndReadFromTheCacheInMemory(string key, string text)
{
// Arrange
ServiceProvider serviceProvider = TestHelper.CreateServiceProvider(DateTime.Now, true, CacheExpirationType.Hours, 2, CacheType.Memory);
ServiceProvider serviceProvider = TestHelper.CreateServiceProvider(
DateTime.Now,
cacheEnabled: true,
cacheExpirationType: CacheExpirationType.Hours,
cacheExpiration: 2,
cacheType: CacheType.Memory);

ICacheService cacheService = serviceProvider.GetRequiredService<ICacheService>();

await cacheService.InitializeAsync();

// Act
await cacheService.SetAsync(key, text);

string resultValue = await cacheService.GetAsync<string>(key);

await cacheService.FlushAsync();

// Assert
resultValue.Should().Be(text);
}
Expand Down
2 changes: 1 addition & 1 deletion CacheDrive/Services/ICacheService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public interface ICacheService
/// Can be used many times, each time adding or overwriting data if they have the same keys.
/// </summary>
Task InitializeAsync();

/// <summary>
/// Dumps cached data into files, database, and so on.
/// Usually it should be run before the application terminates.
Expand Down
68 changes: 61 additions & 7 deletions CacheDrive/Services/MemoryCacheFileStorageService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ public MemoryCacheFileStorageService(IOptions<CacheSettings> settings, IDateServ
: base(settings, dateService)
{
CreateCacheDirectory();
Initialize();
}

~MemoryCacheFileStorageService()
{
Flush();
}

public override async Task FlushAsync()
Expand All @@ -26,25 +32,39 @@ public override async Task FlushAsync()

string cachedItem = JsonSerializer.Serialize(item, JsonSettings.JsonOptions);

string safeFilename = SafeFilenameRegex().Replace(input: key, replacement: string.Empty);

string path = CachePath(fileName: $"{safeFilename}.json");
string path = GetFilePath(key);

await using StreamWriter sw = File.CreateText(path);
await sw.WriteLineAsync(cachedItem);
item.Dirty = false;
}
}

private void Flush()
{
foreach ((string key, CachedItem item) in Storage)
{
if (!item.Dirty || item.Expired(DateService))
continue;

string cachedItem = JsonSerializer.Serialize(item, JsonSettings.JsonOptions);

string path = GetFilePath(key);

using StreamWriter sw = File.CreateText(path);
sw.WriteLineAsync(cachedItem);
item.Dirty = false;
}
}

public override async Task InitializeAsync()
{
string[] dirs = Directory.GetFiles(path: GetCacheDirectory(), searchPattern: "*.json");
string[] files = GetCacheFiles();

foreach (string file in dirs)
foreach (string file in files)
{
string jsonString = await File.ReadAllTextAsync(file);

CachedItem cachedItem = JsonSerializer.Deserialize<CachedItem>(jsonString, JsonSettings.JsonOptions);
CachedItem cachedItem = DeserializeCachedItem(jsonString);

if (cachedItem is null) return;

Expand All @@ -57,6 +77,27 @@ public override async Task InitializeAsync()
await SetAsync(cachedItem);
}
}

private void Initialize()
{
string[] files = GetCacheFiles();

foreach (string file in files)
{
string jsonString = File.ReadAllText(file);
CachedItem cachedItem = DeserializeCachedItem(jsonString);

if (cachedItem is null) return;

if (cachedItem.Expired(DateService))
{
File.Delete(file);
continue;
}

Set(cachedItem);
}
}

private Regex _safeFilenameRegex;

Expand All @@ -71,11 +112,24 @@ private Regex SafeFilenameRegex()
return _safeFilenameRegex;
}

private string GetFilePath(string key)
{
string safeFilename = SafeFilenameRegex().Replace(input: key, replacement: string.Empty);
string path = CachePath(fileName: $"{safeFilename}.json");
return path;
}

private string[] GetCacheFiles()
=> Directory.GetFiles(path: GetCacheDirectory(), searchPattern: "*.json");

private string CachePath(string fileName)
=> Path.Combine(Environment.CurrentDirectory, CacheSettings.CacheFolderName, fileName);

private string GetCacheDirectory()
=> Path.Combine(Environment.CurrentDirectory, CacheSettings.CacheFolderName);

private CachedItem DeserializeCachedItem(string jsonString)
=> JsonSerializer.Deserialize<CachedItem>(jsonString, JsonSettings.JsonOptions);

private void CreateCacheDirectory()
{
Expand Down
4 changes: 2 additions & 2 deletions CacheDrive/Services/MemoryCacheService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public MemoryCacheService(IOptions<CacheSettings> settings, IDateService dateSer
}

protected IDateService DateService => _dateService;

public virtual Task InitializeAsync()
=> Task.CompletedTask;

Expand Down Expand Up @@ -156,7 +156,7 @@ public Task SetAsync<T>(string key, T value, int expirySeconds = 0)
return SetAsync(cachedItem);
}

private void Set(CachedItem cachedItem)
internal void Set(CachedItem cachedItem)
{
Storage.AddOrUpdate(cachedItem.Key, _ => cachedItem, (_, _) => cachedItem);
}
Expand Down

0 comments on commit 1548bae

Please sign in to comment.