Прежде всего, я не смог сделать название более объяснительным, я постараюсь изложить проблему, а затем предоставлю свое решение для нее
Я реализую бэкэнд в ядре asp для нашей игры,у нас есть несколько запросов, которые несколько велики, как, например, запрос товаров, которые мы предоставляем в магазине, каждый пользователь запускает игру, загружает информацию о магазине, которая совершает поездку по базе данных, чтобы получить всю информацию о магазине, которая, как правило, изменяется - не чаще одного раза в месяц.поэтому мы совершаем тысячи поездок в базу данных, которые не нужны.
Кроме того, мы возвращаем метки времени, когда в последний раз изображение элемента менялось, изображения сохраняются в BLOB-объекте, что заставляет менязапросить в блобе дату изменения, что делает запрос более дорогим
, поэтому для решения всего этого я реализовал небольшой класс для кэширования запроса до тех пор, пока нам не потребуется его обновить, для этого запроса и некоторых других, ноЯ не уверен, правильно ли я смотрю на это
вот базовый абстрактный класс:
public abstract class CachedModel<T>
{
protected T Model { get; set; }
private readonly SemaphoreSlim semaphore = new SemaphoreSlim(1,1);
protected abstract Task ThreadSafeUpdateAsync();
protected abstract bool NeedsUpdate();
public async Task<T> GetModel()
{
if (NeedsUpdate())
{
try
{
await semaphore.WaitAsync();
if(NeedsUpdate()) // not sure if this is needed, can other threads enter here after the first one already updated the object?
await ThreadSafeUpdateAsync();
}
finally
{
semaphore.Release();
}
}
return Model;
}
}
и тогда яДополнить этот класс для каждого запроса следующим образом:
public class CachedStoreInfo : CachedModel<DesiredModel>
{
protected override async Task ThreadSafeUpdateAsync()
{
// make the trip to db and Blob service
Model = some result
}
protected override bool NeedsUpdate()
{
return someLogicToDecideIfNeedsUpdate;
}
}
наконец, в контроллере asp все, что мне нужно сделать, это:
[HttpGet]
public async Task<DesiredModel> GetStoreInfo()
{
return await cachedStoreInfo.GetModel();
}
Это правильная реализация?и это даже необходимо, или есть более разумный способ достичь этого?получение меток времени из BLOB-объекта было основной причиной, по которой я думал о кешировании результата