### Дизайн кэша для клиента kakoisegodnyaprazdnik.ru.

Мы исходим из следующих предпосылок:
1. Необходимо делать минимальное количество запросов, чтобы нас не забанили.
2. На каждый запрос мы меняем строку user-agent. Делаем выборку из списка в зависимости от номера дня в месяце.
3. Кэш актуален до ~ 0:01 следующего дня

В идеале в сутки делается всего один запрос в ихнее "api" (там на самом деле парсинг странцы, что какбэ не айс, но
ничего не поделать - api как таковое у них отсутствует).

### Техническая часть
Вроде как [pebble db](github.com/cockroachdb/pebble) показала себя как впорлне рабочее решение для хранения данных типа
key-value. Так что задействуем её.

Из минусов этого решения - в этой базе экспайринг ключей не предусмотрен в принципе. То есть именно сам экспайринг надо
проводить самостоятельно.

Технически это делать несложно. Берём базу cache и в неё складываем 2 k-v записи: prazdnikisegodhyaru_timestamp->date
и prazdnikisegodhyaru_value->value.

Далее, при любом обращении к клиенту, мы извлекаем prazdnikisegodhyaru_timestamp->date и сравниваем с датой
предполагаемого экспайра кэша, если извлечённая дата больше предполагаемая, достаём данные из кэша, если извлечённая
дата меньше или равна извлечённой, то делаем запрос в "api", складываем api в prazdnikisegodhyaru_value->value,
обновляем timestamp в prazdnikisegodhyaru_timestamp->date, а данные возвращаем в качестве ответа наверх, по цепочке.

## Дизайн кэша для клиента openweathermap

Здесь предпосылки другие:

1. Согласно показаниям openweathermap данные для "погоды в текущий момент времени" обновляются раз в три часа.
2. Делать много запросов и их api тоже нежелательно - они в ведут учёт запросов и там есть верхнее ограничение, которое
   сбрасывается раз в месяц.
3. Точных моментов времени, когда происходит обновление данных они не приводят.

### Техническая часть

Таже самая pebbledb, заводить новую смысла особого нету. Название базы тоже cache.

Кэшировать имеет смысл не более, чем на 3 часа. Слишком большой ttl кэша приведёт к "неправдаподобности", особенно в
ситуациях, когда мы запросили данные в когда они "скоро протухнут" на источнике. Слишком малое значение ttl снижает
эффективность кэша. В перловой реализации мы брали 3 часа, выглядит, как отличной вариант для начала.

Далее, реализация. Важным моментом является ключ. Ключ должен содержать в себе данные, уникальные для типа запроса.
То есть, собственно имя города. В нашем случае имя города, после "нормализации". Собственно, ключ будет содержать имя
города + тип значения, от кторого взята sha256, например, sha256(London+timestamp) или sha256(Tokyo+value) (sha256 на
себя берёт враппер бд - функции GetValue и saveKeyWithValue).

(В идеале, было бы неплохо составить табличку с названиями городов на разных языках, которые мапятся либо в одно
название, либо в geo координаты, тогда эффективность кэша будем максимальной, но для этого нужна либо периодическая
джоба, которая обновляет соответсвующий кэш, либо обновлять его on-request, по мере протухания).

N.B. вероятность коллизий sha256 сравнительно минимальна, но она есть, поэтому timestamp необходимо проверять на
валидность формата. Тоже касается и прогнозов погоды. Проверки по длине вполне хватает.

### Механика взаимодействия с кэшом

На поступивший запрос мы

1. извлекаем из базы timestamp
   1. если timestamp валиден
      1. если он не просрочен, извлекаем из базы значение, если
         1. оно валидно, отправляем его в качестве ответа
         2. если оно не валидно, делаем запрос в api, обновляем кэш
      2. если timestamp просрочен делаем запрос в api, обновляем кэш
   2. если timestamp не валиден, делаем запрос в api, обновляем кэш
2. если извлеклась пустая строка, делаем запрос в api, обновляем кэш

Обновление кэша подразумевает вычисление timestamp, когда он должен просрочиться (текущее время + ttl), обновление
2-х ключей в кэше: city+timestamp и city+value.
