Сохранить значение в памяти между запросами и пользователями в контроллере Rails?Использовать переменную класса? - PullRequest
3 голосов
/ 15 марта 2012

Мы на Rails 3.0.6.

Мы поддерживаем список номеров, который меняется только раз в месяц, но почти каждый запрос страницы требует доступа к этому списку.

Мы хранимсписок в базе данных.

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

Если мысохранить список в каждом пользовательском сеансе, нам все еще нужно обращаться к базе данных для каждого сеанса.

Существует ли способ выполнить одноразовое обращение к базе данных и позволить значениям сохраняться в памяти для всех пользователей и всех сеансов?Нам нужен доступ к списку из контроллера.Должны ли мы определить переменную класса в контроллере?

Спасибо!

Ответы [ 2 ]

6 голосов
/ 15 марта 2012

Я думаю, Rails.cache ответ на вашу проблему здесь.Это простой интерфейс с несколькими бэкэндами, по умолчанию кеш хранится в памяти, но если вы уже используете Memcached, Redis или подобное в своем приложении, вы можете вместо этого подключить его к ним.это в вашем ApplicationController

def list_of_numbers
  @list_of_numbers ||= Rails.cache.fetch(:list_of_numbers, :expires_in => 24.hours) do
    # Read from database
  end
end

Он будет пытаться читать из кеша, но если он не найдет его, сделает интенсивную работу и сохранит ее для следующего раза

3 голосов
/ 15 марта 2012

Шаблон, который вы ищете, известен как одноэлементный, который представляет собой простой способ кэширования данных, которые не меняются со временем, например, вы часто будете видеть что-то подобное в application_controller.rb - вашем кодевсегда вызывает метод

def current_user(user_id)
  @current_user ||= User.find user_id
end

Когда он это делает, он проверяет переменную экземпляра @current_user и возвращает ее, если не nil, в противном случае он выполняет поиск в базе данных и присваивает результат переменной экземпляра, которую он возвращает.

Ваша проблема похожа, но шире, поскольку она применима ко всем экземплярам.

Одно решение - с помощью переменной класса, которая описана здесь http://www.ruby -doc.org /docs / ProgrammingRuby / html / tut_classes.html # S3 - здесь применимо решение, подобное приведенному выше.

Это может быть хорошим решением в вашем случае, но имеет некоторые проблемы.В частности (в предположении, что это веб-приложение), в зависимости от вашей конфигурации, у вас может быть несколько экземпляров Rails, загруженных в разные процессы, и переменные класса применяются только к их конкретному экземпляру.Популярный модуль Passenger (для Apache и Nginx) можно настроить так, чтобы переменные класса были доступны для всех его экземпляров ... что прекрасно работает, если у вас только один сервер.

Но когда у вас несколько сервероввсе становится немного сложнее.Конечно, вы можете использовать переменную класса и согласиться с тем, что вам придется сделать одно попадание в базу данных для каждого сервера.Это прекрасно работает, за исключением случаев, когда переменная ... меняется!Вам понадобится какой-то способ аннулирования переменной на всех серверах.В зависимости от того, насколько это критично, это может создать очень грубые и трудные для отслеживания ошибки (я научился трудному пути: -).

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

Установка чрезвычайно проста, и Rails почти предполагает, что вы будете использовать ее для своих различных потребностей в кэшировании, а гем Rails просто делает это так же просто, какpie.

Если предположить, что будут другие возможности для кэширования содержимого, которое может быть не таким простым, как значение, которое вы можете сохранить в переменной класса, это, вероятно, первое место для начала.

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