Мне нужно избавиться от ситуации, когда с коротким промежутком времени прилетело сразу несколько запросов к БД.
Если запрос уже был выполнен, то нужно отдать его из кэша.
Я реализовал следующую логику:
class QueryResultCache {
List<RequestCacheStruct> requestsCacheList = [];
// Если один и тот же запрос отправлен два раза подряд, то второй точно такой же выполнять нет смысла
Map<int, Future<PostgreSQLResult>> pendingFutures = {};
Future<void> addResultToCache(sqlQuery) async {
if(!pendingFutures.containsKey(sqlQuery.hashCode)) {
pendingFutures.addAll({sqlQuery.hashCode: connection.query(sqlQuery, timeoutInSeconds: 3600)});
print('Query was added to Cache');
}
else {
print('This query is already running');
}
var queryResult = await pendingFutures[sqlQuery.hashCode]; // выполняем отложенную Future
await pendingFutures.remove(sqlQuery.hashCode); // удаляем обработанную Future из списка
var queryObj = RequestCacheStruct(sqlQuery.hashCode, DateTime.now(), queryResult! );
requestsCacheList.add(queryObj);
}
}
Проблема в том, что мне кажется, что получается не совсем верная логика (поправьте если ошибаюсь):
- 1й вызов запускает запрос и ждёт.
- 2й вызов просто начинает ждать.
- запрос завершается.
- 1й вызов "просыпается" и начинает чистить pendingFutures и добавлять результат в кэш.
- 2й вызов "просыпается" и начинает чистить pendingFutures и добавлять результат в кэш.
Верно? Если да, то как это исправить?