Я пытаюсь создать что-то (в конечном счете драгоценный камень, но на данный момент приложение), который работает следующим образом.
Предположим, например, что записи DB являются породами собаки. Существует родительский класс Собаки и дочерний класс для каждой породы. Фактические породы не известны до времени выполнения.
Когда сервер начнется, он загрузит записи из DB и инстанцирует экземпляров классов на основе записей, например, у Меня может быть две гончие и пудель. Когда кто-то приезжает в сервер, они могут хотеть получить доступ к одному из тех экземпляров собаки.
Почему не только создают экземпляр на лету? В моем случае "собаки" являются в основном классами, которые содержат алгоритм и данные. Алгоритм не изменяется, данные редко изменяются (на порядке дней), но к осуществлению самого алгоритма, который использует и данные и некоторые динамические данные, переданные в таком как метка времени, получат доступ многократно в секунду.
Было бы глупо должным быть воссоздать экземпляр объекта и загрузить данные каждый раз только, чтобы сделать запрос только, чтобы сделать это снова по следующему запросу (запросы не изменяют состояние объекта). Я создал бы и уничтожил бы несколько объектов в секунду, когда я мог просто снова использовать тот же объект.
не имеет смысла сохранять его на сессии, начиная с кого-то желающего пуделя не должен должен быть иметь информацию о гончих в ее объекте сессии; это не важно (и не масштабируется).
Как я сохраняю эти объекты в памяти? Я в основном хочу, чтобы справочная таблица содержала экземпляры. В Java я создал бы одиночный элемент с некоторым типом hashmap или массива, который находится в памяти. В направляющих я попробовал это путем создания singleton-класса в папке lib. Я думаю - я не могу понимать это право - что экземпляр (то, что это - одиночный элемент, спорно) теряется, когда сессия исчезает.
Самым близким ответом, который я нашел, был http://www.ruby-forum.com/topic/129372, который в основном помещает все в поля класса и методы. Так или иначе это не кажется правильным.
TIA!
Дополнение: Я происхожу из Java. В Java я просто создал бы объект, который находится на "куче" или возможно в дереве JNDI и поскольку Запросы HTTP вошли, они будут обработаны сервлет или EJB или некоторый объект на запрос, который мог затем получить доступ к постоянному объекту. Я, может казаться, не нахожу эквивалент в направляющих.
Возможно, ваш пример сбивает с толку своей простотой. Я предполагаю, что ваши объекты довольно сложны, и ваш бенчмаркинг показывает, что их создание неразумно для каждого запроса.
В производственном режиме классы не выгружаются между запросами, но экземпляры этих классов выгружаются. Поэтому использование членов класса для меня звучит как выход. Просто используйте его для хранения ваших экземпляров.
class ObjectCache
@@objects = {:beagle => Beagle.new, :poodle => Poodle.new}
def lookup key
@@objects[key.to_sym]
end
end
Я бы не стал слишком беспокоиться о загрузке и удалении объектов, если вы не можете предложить тест, который докажет, что это проблема. Каждый запрос, естественно, создает необычайное количество промежуточных объектов, которые обычно создаются и уничтожаются за несколько миллисекунд.
Обычно лучше сосредоточиться на загрузке только того, что требуется, денормализации базы данных для перемещения часто используемых данных или методов в удобное место или сохранении результатов сложных вычислений в поле кэша.
Сначала выполните тест, оптимизируйте только при необходимости.
Сохранение экземпляров моделей в кэше классов может работать, но это только вариант в производственной среде, где классы моделей не перезагружаются с каждым запросом. Это также может привести к ошибкам, вызванным устаревшими данными.
Если у вас есть проблема масштабирования, которую невозможно решить с помощью этих методов, вы можете исследовать создание постоянного сервера для части вашей функциональности, используя комбинацию Rack и EventMachine. Существует несколько способов создания фонового процесса, который может выполнять сложные вычисления с использованием предварительно загруженного набора данных, но конкретный подход будет зависеть от нескольких вещей, таких как тип данных, с которыми вы работаете, и частота он будет доступен.
В производственной среде контроллеры и классы моделей не перезагружаются между запросами. , поэтому у вас есть несколько вариантов:
Да, можно запретить выгрузку классов и в режиме разработки. Это не только для производственного режима. Хотя это происходит по умолчанию в производственном режиме, где вы должны вручную установить его в режиме разработки.