-
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
18 changed files
with
343 additions
and
149 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
14 changes: 14 additions & 0 deletions
14
src/Shiny.Mediator.Caching/Infrastructure/FlushCacheEventHandler.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
using Microsoft.Extensions.Caching.Memory; | ||
using Shiny.Mediator.Middleware; | ||
|
||
namespace Shiny.Mediator.Caching.Infrastructure; | ||
|
||
|
||
public class FlushCacheEventHandler(IMemoryCache cache) : IEventHandler<FlushAllStoresEvent> | ||
{ | ||
public Task Handle(FlushAllStoresEvent @event, CancellationToken cancellationToken) | ||
{ | ||
cache.Clear(); | ||
return Task.CompletedTask; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
namespace Shiny.Mediator.Infrastructure; | ||
|
||
public interface IStorageManager | ||
{ | ||
void Store(object request, object result, bool isPeristent); | ||
|
||
TResult? Get<TResult>(object request, bool isPeristent); | ||
|
||
void ClearAll(); | ||
// TODO: remove(request) & clearall, clearbyrequesttype | ||
} |
143 changes: 143 additions & 0 deletions
143
src/Shiny.Mediator.Maui/Infrastructure/Impl/StorageManager.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
using System.Text.Json; | ||
|
||
namespace Shiny.Mediator.Infrastructure.Impl; | ||
|
||
|
||
// TODO: can the request keys get "dirty" - chances are yes | ||
public class StorageManager(IFileSystem fileSystem) : IStorageManager | ||
{ | ||
readonly Dictionary<string, object> memCache = new(); | ||
Dictionary<string, string> keys = null!; | ||
|
||
|
||
public virtual void Store(object request, object result, bool isPersistent) | ||
{ | ||
if (isPersistent) | ||
{ | ||
var path = this.GetFilePath(request, true); | ||
var json = JsonSerializer.Serialize(result); | ||
File.WriteAllText(path, json); | ||
} | ||
else | ||
{ | ||
var key = this.GetStoreKeyFromRequest(request); | ||
lock (this.memCache) | ||
this.memCache[key] = result!; | ||
} | ||
} | ||
|
||
|
||
public virtual TResult? Get<TResult>(object request, bool isPersistent) | ||
{ | ||
TResult? returnValue = default; | ||
|
||
if (isPersistent) | ||
{ | ||
var path = this.GetFilePath(request, false); | ||
if (File.Exists(path)) | ||
{ | ||
var json = File.ReadAllText(path); | ||
var obj = JsonSerializer.Deserialize<TResult>(json)!; | ||
returnValue = obj; | ||
} | ||
} | ||
else | ||
{ | ||
var key = this.GetStoreKeyFromRequest(request); | ||
lock (this.memCache) | ||
{ | ||
if (this.memCache.ContainsKey(key)) | ||
{ | ||
var item = this.memCache[key]; | ||
returnValue = (TResult)item; | ||
} | ||
} | ||
} | ||
return returnValue; | ||
} | ||
|
||
|
||
// TODO: clear by category (cache/replay/offline) | ||
public virtual void ClearAll() | ||
{ | ||
lock (this.memCache) | ||
this.memCache.Clear(); | ||
|
||
lock (this.keys) | ||
this.keys.Clear(); | ||
|
||
Directory.GetFiles(fileSystem.CacheDirectory, "*.mediator").ToList().ForEach(File.Delete); | ||
Directory.GetFiles(fileSystem.AppDataDirectory, "*.mediator").ToList().ForEach(File.Delete); | ||
} | ||
|
||
|
||
protected virtual string GetStoreKeyFromRequest(object request) | ||
{ | ||
if (request is IRequestKey keyProvider) | ||
return keyProvider.GetKey(); | ||
|
||
var t = request.GetType(); | ||
var key = $"{t.Namespace}_{t.Name}"; | ||
|
||
return key; | ||
} | ||
|
||
|
||
protected virtual string GetPersistentStoreKey(object request, bool createIfNotExists) | ||
{ | ||
var key = this.GetStoreKeyFromRequest(request); | ||
this.EnsureKeyLoad(); | ||
if (this.keys.ContainsKey(key)) | ||
{ | ||
key = this.keys[key]; | ||
} | ||
else if (createIfNotExists) | ||
{ | ||
var newKey = Guid.NewGuid().ToString(); | ||
this.keys.Add(key, newKey); | ||
key = newKey; | ||
|
||
this.PersistKeyStore(); | ||
} | ||
|
||
return key; | ||
} | ||
|
||
|
||
protected virtual string GetFilePath(object request, bool createIfNotExists) | ||
{ | ||
var key = this.GetPersistentStoreKey(request, createIfNotExists); | ||
var path = Path.Combine(fileSystem.CacheDirectory, $"{key}.mediator"); | ||
return path; | ||
} | ||
|
||
|
||
bool initialized = false; | ||
protected void EnsureKeyLoad() | ||
{ | ||
if (this.initialized) | ||
return; | ||
|
||
var storePath = this.KeyStorePath; | ||
if (File.Exists(storePath)) | ||
{ | ||
var json = File.ReadAllText(storePath); | ||
this.keys = JsonSerializer.Deserialize<Dictionary<string, string>>(json)!; | ||
} | ||
else | ||
{ | ||
this.keys = new(); | ||
} | ||
this.initialized = true; | ||
} | ||
|
||
|
||
protected void PersistKeyStore() | ||
{ | ||
var json = JsonSerializer.Serialize(this.keys); | ||
File.WriteAllText(this.KeyStorePath, json); | ||
} | ||
|
||
|
||
protected string KeyStorePath => Path.Combine(fileSystem.AppDataDirectory, "keys.mediator"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
13 changes: 13 additions & 0 deletions
13
src/Shiny.Mediator.Maui/Middleware/FlushAllCacheEventHandler.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
using Shiny.Mediator.Infrastructure; | ||
|
||
namespace Shiny.Mediator.Middleware; | ||
|
||
|
||
public class FlushAllCacheEventHandler(IStorageManager storage) : IEventHandler<FlushAllStoresEvent> | ||
{ | ||
public Task Handle(FlushAllStoresEvent @event, CancellationToken cancellationToken) | ||
{ | ||
storage.ClearAll(); | ||
return Task.CompletedTask; | ||
} | ||
} |
Oops, something went wrong.