Skip to content

Commit

Permalink
changed code converting senses to avoid a cache stampede
Browse files Browse the repository at this point in the history
  • Loading branch information
hahn-kev committed Jan 15, 2025
1 parent f761055 commit e65013c
Showing 1 changed file with 16 additions and 12 deletions.
28 changes: 16 additions & 12 deletions backend/LfClassicData/LfClassicMiniLcmApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ public async IAsyncEnumerable<PartOfSpeech> GetPartsOfSpeech()
return _partsOfSpeechCacheByGuid.GetValueOrDefault(id);
}

public async Task<PartOfSpeech?> GetPartOfSpeech(string key)
public async ValueTask<PartOfSpeech?> GetPartOfSpeech(string key)
{
if (_partsOfSpeechCacheByStringKey is null)
{
Expand Down Expand Up @@ -246,18 +246,20 @@ private async IAsyncEnumerable<Entry> Query(QueryOptions? options = null, string
})));
}

private async Task<Entry> ToEntry(Entities.Entry entry)
private async ValueTask<Entry> ToEntry(Entities.Entry entry)
{
Sense[] senses;
if (entry.Senses is null)
List<Sense> senses = new(entry.Senses?.Count ?? 0);
if (entry.Senses is not (null or []))
{
senses = [];
}
else
{
var senseTasks = entry.Senses.OfType<Entities.Sense>().Select(sense => ToSense(entry.Guid, sense));
senses = await Task.WhenAll(senseTasks);
foreach (var sense in entry.Senses)
{
if (sense is null) continue;
//explicitly doing this sequentially
//to avoid concurrency issues as ToSense calls GetPartOfSpeech which is cached
senses.Add(await ToSense(entry.Guid, sense));
}
}

return new Entry
{
Id = entry.Guid,
Expand All @@ -269,15 +271,17 @@ private async Task<Entry> ToEntry(Entities.Entry entry)
};
}

private async Task<Sense> ToSense(Guid entryId, Entities.Sense sense)
private async ValueTask<Sense> ToSense(Guid entryId, Entities.Sense sense)
{
var partOfSpeech = sense.PartOfSpeech is null ? null : await GetPartOfSpeech(sense.PartOfSpeech.Value);
return new Sense
{
Id = sense.Guid,
EntryId = entryId,
Gloss = ToMultiString(sense.Gloss),
Definition = ToMultiString(sense.Definition),
PartOfSpeech = sense.PartOfSpeech is null ? null : await GetPartOfSpeech(sense.PartOfSpeech.Value),
PartOfSpeech = partOfSpeech,
PartOfSpeechId = partOfSpeech?.Id,
SemanticDomains = (sense.SemanticDomain?.Values ?? [])
.Select(sd => new SemanticDomain { Id = Guid.Empty, Code = sd, Name = new MultiString { { "en", sd } } })
.ToList(),
Expand Down

0 comments on commit e65013c

Please sign in to comment.