В Ruby on Rails, как я могу сохранить объекты в памяти между сессиями

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

Предположим, например, что записи DB являются породами собаки. Существует родительский класс Собаки и дочерний класс для каждой породы. Фактические породы не известны до времени выполнения.

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

Почему не только создают экземпляр на лету? В моем случае "собаки" являются в основном классами, которые содержат алгоритм и данные. Алгоритм не изменяется, данные редко изменяются (на порядке дней), но к осуществлению самого алгоритма, который использует и данные и некоторые динамические данные, переданные в таком как метка времени, получат доступ многократно в секунду.

Было бы глупо должным быть воссоздать экземпляр объекта и загрузить данные каждый раз только, чтобы сделать запрос только, чтобы сделать это снова по следующему запросу (запросы не изменяют состояние объекта). Я создал бы и уничтожил бы несколько объектов в секунду, когда я мог просто снова использовать тот же объект.

не имеет смысла сохранять его на сессии, начиная с кого-то желающего пуделя не должен должен быть иметь информацию о гончих в ее объекте сессии; это не важно (и не масштабируется).

Как я сохраняю эти объекты в памяти? Я в основном хочу, чтобы справочная таблица содержала экземпляры. В Java я создал бы одиночный элемент с некоторым типом hashmap или массива, который находится в памяти. В направляющих я попробовал это путем создания singleton-класса в папке lib. Я думаю - я не могу понимать это право - что экземпляр (то, что это - одиночный элемент, спорно) теряется, когда сессия исчезает.

Самым близким ответом, который я нашел, был http://www.ruby-forum.com/topic/129372, который в основном помещает все в поля класса и методы. Так или иначе это не кажется правильным.

TIA!

Дополнение: Я происхожу из Java. В Java я просто создал бы объект, который находится на "куче" или возможно в дереве JNDI и поскольку Запросы HTTP вошли, они будут обработаны сервлет или EJB или некоторый объект на запрос, который мог затем получить доступ к постоянному объекту. Я, может казаться, не нахожу эквивалент в направляющих.

16
задан hershey 28 July 2010 в 19:46
поделиться

4 ответа

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

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

class ObjectCache
  @@objects = {:beagle => Beagle.new, :poodle => Poodle.new}

  def lookup key
    @@objects[key.to_sym]
  end
end
10
ответ дан 30 November 2019 в 22:43
поделиться

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

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

Сначала выполните тест, оптимизируйте только при необходимости.

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

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

6
ответ дан 30 November 2019 в 22:43
поделиться

В производственной среде контроллеры и классы моделей не перезагружаются между запросами. , поэтому у вас есть несколько вариантов:

  • установить объекты как переменные класса в вашем application_controller
  • создать одноэлементные методы в самих классах модели, которые возвращают значения
0
ответ дан 30 November 2019 в 22:43
поделиться

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

0
ответ дан 30 November 2019 в 22:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: