Контекст приложения в Rails - PullRequest
3 голосов
/ 20 сентября 2008

Rails поставляется с удобным хеш-сессией, в которую мы можем втиснуть материал до глубины души. Я хотел бы, однако, что-то вроде контекста приложения ASP, который вместо совместного использования данных только в течение одного сеанса будет делиться им со всеми сеансами в одном приложении. Я пишу простое приложение для панели инструментов и хотел бы получать данные каждые 5 минут, а не каждые 5 минут для каждой сессии.

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

Итак, есть ли способ получить (или смоделировать) подобные вещи? Если нет способа сделать это без базы данных, есть ли какой-нибудь «фальшивый» механизм базы данных, который поставляется с Rails, работает в памяти, но не беспокоит сохранение данных между перезапусками?

Ответы [ 7 ]

8 голосов
/ 23 сентября 2008

Правильный ответ : memcached. Быстро, чисто, поддерживает несколько процессов, в наши дни очень аккуратно интегрируется с Rails. Даже не так плохо, чтобы установить, но это еще одна вещь, чтобы продолжать работать.

90% Ответ : Возможно, существует несколько процессов Rails, например, по одному для каждого монгрела. В зависимости от специфики ваших потребностей в кешировании, вполне возможно, что наличие одного кеша на монгрела не самая плохая вещь в мире. Например, предположим, что вы кэшировали результаты длительного запроса, который

  • получает свежие данные каждые 8 ​​часов
  • используется при каждой загрузке страницы, 20 000 раз в день
  • должен быть доступен в 4 процессах (Mongrels)

тогда вы можете отбросить эти 20 000 запросов до 12 с помощью одной строки кода

@@arbitrary_name ||= Model.find_by_stupidly_long_query(param)

Двойная метка at, символ Ruby, с которым вы, возможно, не знакомы, является глобальной переменной. || = - это обычно используемая идиома Ruby для выполнения присваивания тогда и только тогда, когда переменная в настоящий момент равна nil или иначе оценивается как false. Это будет хорошо, пока вы явно не очистите его ИЛИ до тех пор, пока процесс не прекратится, по любой причине - перезапуск сервера, явное уничтожение, что у вас.

И после того, как вы перейдете от 20 тыс. Вычислений в день к 12 примерно за 15 секунд (ОК, две минуты - вам нужно обернуть его в тривиальный блок if, в котором хранится время обновления кэша в другом глобале), вы можете обнаружите, что нет необходимости тратить дополнительные инженерные средства на его снижение до 4 в день.

На самом деле я использую это на одном из своих рабочих сайтов, чтобы кэшировать несколько дорогих запросов, которые буквально нужно оценивать только один раз в течение жизненного цикла процесса (т. Е. Они меняются только во время развертывания - я полагаю, я мог бы рассчитать результаты и записать их на диск или в БД, но зачем это делать, когда SQL может сделать работу за меня).

Вы не получаете никакого магического синтаксиса истечения, надежность довольно мала, и его нельзя разделить между процессами - но это 90% от того, что вам нужно в строке кода.

3 голосов
/ 20 сентября 2008

Вы должны взглянуть на memcached: http://wiki.rubyonrails.org/rails/pages/MemCached

2 голосов
/ 20 сентября 2008

Есть полезное Railscast на Rails 2.1 кешировании . Это очень полезно, если вы планируете использовать memcached с Rails.

1 голос
/ 20 сентября 2008

Использование стокового кеша Rails примерно эквивалентно этому.

0 голосов
/ 29 апреля 2010

Rails.cache замораживает объекты, которые он хранит. Этот вид имеет смысл для кеша, но НЕ для контекста приложения. Я полагаю, вместо того, чтобы совершить эту простую задачу в обратном направлении до Луны, все, что вам нужно сделать, это создать константу внутри config / environment.rb

APP_CONTEXT = Hash.new

Довольно просто, а?

0 голосов
/ 20 сентября 2008

Итак, то, что вы спрашиваете, в Rails совершенно невозможно из-за способа его разработки. То, что вы спрашиваете, является общим объектом, а Rails является строго однопоточным. Memcached или аналогичный инструмент для обмена данными между распределенными процессами - единственный путь.

0 голосов
/ 20 сентября 2008

@ p3t0r - верно, MemCached, вероятно, лучший вариант, но вы также можете использовать базу данных sqlite, которая поставляется с Rails. Это не будет работать на нескольких машинах, хотя, где MemCached будет. Кроме того, sqlite будет сохраняться на диске, хотя я думаю, что вы можете установить его не так, как хотите. Сам Rails не имеет хранилища в области приложения, поскольку он запускается как обработчик по одному процессу на запрос, поэтому у него нет общего пространства памяти, как у ASP.NET или Java-сервера.

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