Срок действия кэша на основе сохраненного значения - PullRequest
0 голосов
/ 18 февраля 2019

В моем приложении есть страница финансового обзора с довольно большим количеством запросов.Эта страница обновляется один раз в месяц после выполнения фонового задания, поэтому я добавил кеширование:

@iterated_hours = Rails.cache.fetch("productivity_data", expires_in: 24.hours) do
  FinancialsIterator.new.create_productivity_iterations(@company)
end

Срок действия кэша должен истечь после завершения фонового задания, поэтому я создал модель CacheExpiration:

class CacheExpiration < ApplicationRecord
  validates :cache_key, :expires_in, presence: true
end

Итак, в фоновом задании создается запись:

CacheExpiration.create(cache_key: "productivity_data", expires_in: DateTime.now)

И Rails.cache.fetch обновляется до:

  expires_in = get_cache_key_expiration("productivity_data")
  @iterated_hours = Rails.cache.fetch("productivity_data", expires_in: expires_in) do
    FinancialsIterator.new.create_productivity_iterations(@company)
  end

  private def get_cache_key_expiration(cache_key)
    cache_expiration = CacheExpiration.find_by_cache_key(cache_key)
    if cache_expiration.present?
      cache_expiration.expires_in
    else
      24.hours
    end
  end

Итак, срок действия установлен наDateTime, это правильно или это должно быть количество секунд?Это правильный подход, чтобы убедиться, что срок действия кэша истек только один раз, когда фоновое задание заканчивается?

1 Ответ

0 голосов
/ 18 февраля 2019

Явная установка значения expires_in очень ограничивает и подвержена ошибкам IMO.Вы не сможете изменить значение после того, как значение кеша было создано (хорошо, вы можете очистить кеш вручную), и если вы когда-нибудь захотите изменить фоновое задание, чтобы оно выполнялось более / менее часто, вы также должны не забыть обновитьexpires_in значение.Кроме того, время завершения фонового задания может отличаться от времени первого запроса к представлению.В худшем случае запрос выполняется за минуту до того, как фоновое задание обновляет информацию для представления.Вашим пользователям придется ждать целый день, чтобы получить текущую информацию.

Более гибкий подход - полагаться на updated_at или в их отсутствие created_at поля моделей ActiveRecord.

Для этого вы можете либо полагаться на модель CacheExpiration, которую вы уже создали (возможно, у нее уже есть соответствующие поля), либо использовать последнюю из «огромного количества записей», которые вы создали.Просто закажите их и возьмите последний SomeArModel.order(created_at: :desc).first

Преимущество этого подхода состоит в том, что всякий раз, когда создаваемая вами модель AR обновляется / создается, ваш кэш отключается, и создается новая.Больше нет связи между временем, когда пользователь вызвал конечную точку, и временем выполнения фонового задания.В случае, если запись создается любым способом, кроме фонового задания, она также будет просто обрабатываться.

Модели ActiveRecord являются гражданами первого класса, когда дело доходит до кэширования.Вы можете просто передать их как ключи кеша.Тогда ваш код изменится на:

Rails.cache.fetch(CacheExpiration.find_by_cache_key("productivity_data")) do
  FinancialsIterator.new.create_productivity_iterations(@company)
end

Но если это вообще возможно, попробуйте найти альтернативную модель, чтобы вам больше не приходилось обслуживать CacheExpiration.

В Rails также есть руководство по этой теме

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...