Хранение данных между перезапусками веб-приложения
Метод Kernel#at_exit
Метод Kernel#at_exit
позволяет зарегистрировать блок кода, который будет вызван при выключении приложения. Причём данный метод может быть вызван несколько раз и для каждого вызова будет зарегистрирован свой обработчик.
Документация
Задачи на использование метода at_exit
Первое приложение
Создайте консольное приложение, которое добавляет один обработчик с помощью at_exit
. Данный обработчик должен выводить информацию о том, что он выполнился на стандартный поток вывода. Например оно может печатать Выполнилось в обработчике
.
Само приложение должно печатать строку Выполнилось в коде приложения
.
Запустите приложение и проверьте работу приложения.
Второе приложение
Создайте консольное приложение.
Объявите переменную my_core_data
. Инициализируйте её со значением Изначальное значение
.
Добавьте первый обработчик завершения приложения. В обработчике выведите содержимое данной переменной и запишите в неё значение Значение из первого обработчика
.
Добавьте второй обработчик завершения приложения. Во втором обработчике выведите содержимое переменной my_core_data
и запишите в неё значение Второй обработчик был тут
.
После объявления обработчиков выведите строку: Значение переменой в коде приложения
. Затем выведите содержимое данной переменной.
Третье приложение
Создайте консольное приложение, которое будет добавлять несколько обработчиков на окончание приложения.
Создайте переменную console_read_data
и инициализируйте её пустой строкой.
Добейтесь такого поведения, чтобы один обработчик окончания работы приложения записывал данные с консоли в переменную console_read_data
. А второй обработчик должен показывать содержимое данной переменной на стандартном потоке вывода.
Хранилище PStore
Мы ранее рассматривали текстовые файлы в формате CSV и YAML для сохранения данных приложения между запусками. Их использование требует от вас написать собственные преобразования из текста в свои структуры данных. Хранилище PStore позволяет сохранить Ruby-объект в файле, а затем считать информацию из него. Базовым элементом хранилища является хеш-объект, а данными могут выступать любые объекты.
Для сохранения объектов применяется механизм, предоставляемый модулем Marshal
. Данный модуль преобразует объекты Ruby в набор байт и обратно. Если ваш объект «плохо» преобразуется в набор байт, то вы можете определить специальные методы-помошники, которые будут преобразовывать ваш объект в стандартную структуру и обратно из неё.
Документация
Задача, четвёртое приложение
Разработайте простое консольное приложение, которое позволит пользователю оперировать набором оценок. Каждая оценка описывается тремя параметрами: курс, задание, оценка. Первые два являются строками, а последняя - вещественное число от 0 до 5.
Приложение должно показывать пользователю текущий список оценок, позволять добавлять новую оценку в конец списка и выходить из приложения.
- Создайте класс, описывающий одну оценку.
- Создайте класс, описывающий дневник, содержащий все оценки. Данный класс должен иметь методы для добавления новой оценки, получения списка оценок и итератор для обхода данного списка.
- Приложение должно хранить информацию об оценках в PStore. При запуске приложения данные из хранилища должны считываться, а при выходе записываться в хранилище. Рекомендуется создать отдельные методы, которые смогут успешно считывать и записывать информацию об оценках в хранилище.
Надёжное хранение данных в Sinatra-приложениях
Ввиду того, что при создании приложений на Sinatra у вас нет возможности отследить время окончания работы самого приложения напрямую, необходимо использовать обработчик окончания приложения at_exit
. Однако, если вы поместите его не в правильное место, то он не будет корректно работать.
Причиной этого поведения является собственный обработчик at_exit
, который Sinatra
использует для запуска приложения. Данный обработчик расположен в файле sinatra
, который мы подключаем в самом начале наших приложений. Если вы разместите обработчик at_exit
после подключения данного файла, то он отработает до старта Sinatra-приложения, что не позволит выполнить код во время выключения основного приложения.
В результате для успешной обработки данного сигнала необходимо:
- Создать переменную, в которой будет храниться ссылка на хранилище данных.
- Создать собственный обработчик сигнала
at_exit
в самом начале файла, где вы разрабатываете приложение. В обработчик поместить сохранение данных, которые сейчас находятся в хранилище. - Подключить
sinatra
к приложению. - Добавить ссылку на хранилище в конфигурацию
Sinatra
. Данное хранилище следует использовать во время работы приложения. Нельзя использовать первоначальную переменную для общения с данными.
Задача
Переработайте предыдущее приложение в веб-приложение на основе Sinatra. Приложение должно содержать 2 страницы: отображение текущего списка оценок и добавление новой оценки. После завершения работы приложения из консоли (с помощью комбинации клавиш Ctrl+C) приложение должно сохранять данные в хранилище PStore. То есть после перезапуска данные должны успешно сохраняться.
Приложение не должно сохранять данные в хранилище при каждом изменении состояния приложения. Это скорее приведёт к потере данных, нежели к их сохранению.
Дополнительно. Добейтесь того, чтобы приложение было полностью функционально при запуске как консольное и как веб-приложение. Для решения этой задачи вам потребуется создать 2 независимых стартовых Ruby-скрипта. Первый скрипт будет запускать веб-приложение, а второй - консольное.