2008-09-20 3 views
3

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

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

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

ответ

7

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

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

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

, то вы можете упасть, что 20000 запросов до 12 с примерно одной строки кода

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

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

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

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

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

+0

В режиме разработки это не работает. Ваша глобальная переменная будет сброшена при каждом вызове контроллера. Наверное, из-за архитектуры rails memcached - единственный способ. :-( – TraderJoeChicago 2010-04-28 21:05:31

0

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

+0

Приходит ли sqlite с Rails? Похоже, что это отдельная установка здесь: http://wiki.rubyonrails.org/rails/pages/HowtoUseSQLite – 2008-09-20 22:16:01

0

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

1

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

0

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

APP_CONTEXT = Hash.new

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

Смежные вопросы