-
-
Notifications
You must be signed in to change notification settings - Fork 38
Expand file tree
/
Copy pathMongoDbCacheLayer.cs
More file actions
117 lines (99 loc) · 3.16 KB
/
Copy pathMongoDbCacheLayer.cs
File metadata and controls
117 lines (99 loc) · 3.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
using System.Linq;
using System.Threading.Tasks;
using CacheTower.Providers.Database.MongoDB.Commands;
using CacheTower.Providers.Database.MongoDB.Entities;
using MongoFramework;
using MongoFramework.Infrastructure;
using MongoFramework.Infrastructure.Indexing;
using MongoFramework.Infrastructure.Linq;
namespace CacheTower.Providers.Database.MongoDB
{
/// <remarks>
/// The <see cref="MongoDbCacheLayer"/> allows caching through a MongoDB server.
/// Cache entries are serialized to BSON using <see cref="global::MongoDB.Bson.Serialization.BsonSerializer"/>.
/// </remarks>
/// <inheritdoc cref="ICacheLayer"/>
public class MongoDbCacheLayer : ICacheLayer
{
private bool? IsDatabaseAvailable { get; set; }
private IMongoDbConnection Connection { get; }
private bool HasSetIndexes = false;
/// <summary>
/// Creates a new instance of <see cref="MongoDbCacheLayer"/> with the given <paramref name="connection"/>.
/// </summary>
/// <param name="connection">The connection to the MongoDB database.</param>
public MongoDbCacheLayer(IMongoDbConnection connection)
{
Connection = connection;
}
private async ValueTask TryConfigureIndexes()
{
if (!HasSetIndexes)
{
HasSetIndexes = true;
await EntityIndexWriter.ApplyIndexingAsync<DbCachedEntry>(Connection);
}
}
/// <inheritdoc/>
public async ValueTask CleanupAsync()
{
await TryConfigureIndexes();
await EntityCommandWriter.WriteAsync<DbCachedEntry>(Connection, new[] { new CleanupCommand() }, default);
}
/// <inheritdoc/>
public async ValueTask EvictAsync(string cacheKey)
{
await TryConfigureIndexes();
await EntityCommandWriter.WriteAsync<DbCachedEntry>(Connection, new[] { new EvictCommand(cacheKey) }, default);
}
public string Name => nameof(MongoDbCacheLayer);
/// <inheritdoc/>
public async ValueTask FlushAsync()
{
await EntityCommandWriter.WriteAsync<DbCachedEntry>(Connection, new[] { new FlushCommand() }, default);
}
/// <inheritdoc/>
public async ValueTask<CacheEntry<T>?> GetAsync<T>(string cacheKey)
{
await TryConfigureIndexes();
var provider = new MongoFrameworkQueryProvider<DbCachedEntry>(Connection);
var queryable = new MongoFrameworkQueryable<DbCachedEntry>(provider);
var dbEntry = queryable.Where(e => e.CacheKey == cacheKey).FirstOrDefault();
var cacheEntry = default(CacheEntry<T>);
if (dbEntry != default)
{
cacheEntry = new CacheEntry<T>((T)dbEntry.Value!, dbEntry.Expiry);
}
return cacheEntry;
}
/// <inheritdoc/>
public async ValueTask SetAsync<T>(string cacheKey, CacheEntry<T> cacheEntry)
{
await TryConfigureIndexes();
var command = new SetCommand(new DbCachedEntry
{
CacheKey = cacheKey,
Expiry = cacheEntry.Expiry,
Value = cacheEntry.Value!
});
await EntityCommandWriter.WriteAsync<DbCachedEntry>(Connection, new[] { command }, default);
}
/// <inheritdoc/>
public async ValueTask<bool> IsAvailableAsync(string cacheKey)
{
if (IsDatabaseAvailable == null)
{
try
{
await TryConfigureIndexes();
IsDatabaseAvailable = true;
}
catch
{
IsDatabaseAvailable = false;
}
}
return IsDatabaseAvailable.Value;
}
}
}