Skip to content

Commit 67ae6ff

Browse files
committed
Fixing some cache bugs with custom fields
1 parent cb9cfe1 commit 67ae6ff

File tree

1 file changed

+24
-18
lines changed

1 file changed

+24
-18
lines changed

src/Foundatio.Repositories.Elasticsearch/CustomFields/CustomFieldDefinitionRepository.cs

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ public CustomFieldDefinitionRepository(CustomFieldDefinitionIndex index, ILockPr
3636
DefaultConsistency = Consistency.Immediate;
3737

3838
AddPropertyRequiredForRemove(d => d.EntityType, d => d.TenantKey, d => d.IndexType, d => d.IndexSlot);
39-
40-
DocumentsChanging.AddHandler(OnDocumentsChanging);
39+
40+
DocumentsChanged.AddHandler(OnDocumentsChanged);
4141
}
4242

4343
public async Task<IDictionary<string, CustomFieldDefinition>> GetFieldMappingAsync(string entityType, string tenantKey) {
@@ -117,8 +117,9 @@ public override async Task AddAsync(IEnumerable<CustomFieldDefinition> documents
117117
.FieldEquals(cf => cf.TenantKey, fieldScope.Key.TenantKey)
118118
.FieldEquals(cf => cf.IndexType, fieldScope.Key.IndexType)
119119
.Include(cf => cf.IndexSlot)
120-
.Include(cf => cf.Name),
121-
o => o.IncludeSoftDeletes().PageLimit(1000));
120+
.Include(cf => cf.Name)
121+
.Include(cf => cf.IsDeleted),
122+
o => o.IncludeSoftDeletes().PageLimit(1000).QueryLogLevel(Microsoft.Extensions.Logging.LogLevel.Information));
122123

123124
do {
124125
usedSlots.AddRange(existingFields.Documents.Select(d => d.IndexSlot));
@@ -135,8 +136,8 @@ public override async Task AddAsync(IEnumerable<CustomFieldDefinition> documents
135136
}
136137

137138
_logger.LogTrace("Found {FieldCount} fields with {SlotCount} used slots for {FieldScope}", existingFields.Total, usedSlots.Count, slotFieldScopeKey);
138-
await _cache.ListAddAsync(slotFieldScopeKey, availableSlots.ToArray(), TimeSpan.FromMinutes(15));
139-
await _cache.ListAddAsync(namesFieldScopeKey, usedNames.ToArray(), TimeSpan.FromMinutes(15));
139+
await _cache.ListAddAsync(slotFieldScopeKey, availableSlots.ToArray(), TimeSpan.FromMinutes(5));
140+
await _cache.ListAddAsync(namesFieldScopeKey, usedNames.ToArray(), TimeSpan.FromMinutes(5));
140141
}
141142

142143
foreach (var doc in fieldScope) {
@@ -149,8 +150,8 @@ public override async Task AddAsync(IEnumerable<CustomFieldDefinition> documents
149150
int availableSlot = availableSlots.Dequeue();
150151
doc.IndexSlot = availableSlot;
151152

152-
await _cache.ListRemoveAsync(slotFieldScopeKey, new[] { availableSlot }, TimeSpan.FromMinutes(15));
153-
await _cache.ListAddAsync(namesFieldScopeKey, new[] { doc.Name }, TimeSpan.FromMinutes(15));
153+
await _cache.ListRemoveAsync(slotFieldScopeKey, new[] { availableSlot });
154+
await _cache.ListAddAsync(namesFieldScopeKey, new[] { doc.Name });
154155
_logger.LogTrace("New field {FieldName} using slot {IndexSlot} for {FieldScope}", doc.Name, doc.IndexSlot, slotFieldScopeKey);
155156
}
156157
}
@@ -174,7 +175,7 @@ protected override Task ValidateAndThrowAsync(CustomFieldDefinition document) {
174175
return Task.CompletedTask;
175176
}
176177

177-
private async Task OnDocumentsChanging(object source, DocumentsChangeEventArgs<CustomFieldDefinition> args) {
178+
private async Task OnDocumentsChanged(object source, DocumentsChangeEventArgs<CustomFieldDefinition> args) {
178179
if (args.ChangeType == ChangeType.Saved) {
179180
foreach (var doc in args.Documents) {
180181
if (doc.Original.EntityType != doc.Value.EntityType)
@@ -186,15 +187,15 @@ private async Task OnDocumentsChanging(object source, DocumentsChangeEventArgs<C
186187

187188
if (doc.Value.IsDeleted) {
188189
string namesFieldScopeKey = GetNamesFieldScopeCacheKey(doc.Value.EntityType, doc.Value.TenantKey, doc.Value.IndexType);
189-
await _cache.ListRemoveAsync(namesFieldScopeKey, new[] { doc.Value.Name }, TimeSpan.FromMinutes(15));
190+
await _cache.ListRemoveAsync(namesFieldScopeKey, new[] { doc.Value.Name });
190191
}
191192
}
192193
} else if (args.ChangeType == ChangeType.Removed) {
193194
foreach (var doc in args.Documents) {
194195
string slotFieldScopeKey = GetSlotFieldScopeCacheKey(doc.Value.EntityType, doc.Value.TenantKey, doc.Value.IndexType);
195196
string namesFieldScopeKey = GetNamesFieldScopeCacheKey(doc.Value.EntityType, doc.Value.TenantKey, doc.Value.IndexType);
196-
await _cache.ListAddAsync(slotFieldScopeKey, new[] { doc.Value.IndexSlot }, TimeSpan.FromMinutes(15));
197-
await _cache.ListRemoveAsync(namesFieldScopeKey, new[] { doc.Value.Name }, TimeSpan.FromMinutes(15));
197+
await _cache.ListAddAsync(slotFieldScopeKey, new[] { doc.Value.IndexSlot });
198+
await _cache.ListRemoveAsync(namesFieldScopeKey, new[] { doc.Value.Name });
198199
}
199200
}
200201
}
@@ -204,15 +205,15 @@ private string GetLockName(string entityType, string tenantKey, string indexType
204205
}
205206

206207
private string GetMappingCacheKey(string entityType, string tenantKey) {
207-
return $"{entityType}:{tenantKey}";
208+
return $"customfield:{entityType}:{tenantKey}";
208209
}
209210

210211
private string GetSlotFieldScopeCacheKey(string entityType, string tenantKey, string indexType) {
211-
return $"{entityType}:{tenantKey}:{indexType}:slots";
212+
return $"customfield:{entityType}:{tenantKey}:{indexType}:slots";
212213
}
213214

214215
private string GetNamesFieldScopeCacheKey(string entityType, string tenantKey, string indexType) {
215-
return $"{entityType}:{tenantKey}:{indexType}:names";
216+
return $"customfield:{entityType}:{tenantKey}:{indexType}:names";
216217
}
217218

218219
protected override async Task InvalidateCacheByQueryAsync(IRepositoryQuery<CustomFieldDefinition> query) {
@@ -228,10 +229,15 @@ protected override async Task InvalidateCacheByQueryAsync(IRepositoryQuery<Custo
228229

229230
protected override async Task InvalidateCacheAsync(IReadOnlyCollection<ModifiedDocument<CustomFieldDefinition>> documents, ChangeType? changeType = null) {
230231
await base.InvalidateCacheAsync(documents, changeType);
231-
// TODO: How to handle empty documents list being a batch of documents were updated?
232+
233+
if (documents.Count == 0) {
234+
await _cache.RemoveByPrefixAsync("customfield");
235+
_logger.LogInformation("Cleared all custom field mappings from cache due to change {ChangeType}.", changeType);
236+
}
237+
232238
var cacheKeys = documents.Select(d => GetMappingCacheKey(d.Value.EntityType, d.Value.TenantKey)).Distinct().ToList();
233-
if (cacheKeys.Count > 0)
234-
await _cache.RemoveAllAsync(cacheKeys);
239+
foreach (var cacheKey in cacheKeys)
240+
await _cache.RemoveByPrefixAsync(cacheKey);
235241
}
236242
}
237243

0 commit comments

Comments
 (0)