разработка под mod_perl
Oct. 19th, 2012 10:46 am Итак, уже наваяно три основных раздела в черновом варианте. Накопленный опыт писания под mod_perl позволил уже сделать некоторые выводы:
Наиболее пОлно идеологии mod_perl соответствует парадигма функционального программирования.
ООП тоже хорошо, но в несколько других условиях, чем есть те, в которых нахожусь я. ТЗ по сути нет, ибо состоит из нескольких пунктов (а) разработать и внедрить передачу статфайлов с хоста А на хост Б (сделано), (б) разработать и внедрить обработку (архивацию/резервное копирование, первичную обработку) файлов и загрузку данных в БД (сделано), (в) разработать и внедрить отображение инфы через веб-интерфейс (в процессе). Более подробное и тщательно проработанное ТЗ составить нет возможности, да и необходимости. По большому счёту оно, как и результат реализации проекта никому не нужен. Это позже, когда всё будет и народ станет этим пользоваться, кто-то может и задумается как же они раньше без этого обходились. Нет, на самом-то деле хорошее ТЗ не помешало бы, но "хто-ж йому дасть"© столько времени? Самое грустное, что для этого нужно не просто сколько-то времени, а сколько-то суммарного времени, фрагментами не менее такой-то длительностью. Мало кто понимает, что в отношении рабочего времени далеко не всегда работает коммутативный закон. То есть два куска по часу не эквивалентны по результату одному куску в 2 часа. Это же, кстати, относится и ко сну. :)
Вот собственно поэтому и приходится применять alige-подобный подход на всех этапах. :)
Первые два пункта получились быстро, так как особых настроек под разные типы данных не потребовалось. Почти.
Полтора десятка типов файлов передаются унифицированным способом. Впрочем, технология сия работает уже много лет. В последнюю пару лет была несколько доработана и добавлена фича: возможность передавать файлы в архивированном виде: существенно экономит время на передачу, а архивирование и так происходило на исходном хосте. Собирался было, правда, вместо ftp задействовать scp, но не придумал как быстро и красиво сделать контроль передачи, который в старой схеме используется во всю. В общем, поскольку процессы всё-равно протекают во внутреннем, отгороженном от всех технологическом фрагменте сети, то решено было пожертвовать секюрити в пользу надёжности и адаптивности процесса.
Обработка и загрузка тоже не заняла слишком много времени. Впрочем часть файлов просто бекапятся, а нас сейчас интересует всего с пол десятка. Зато ими передаются два десятка типов объектов. Очень здорово, что хотя в каждом типе объекта разное количество параметров, но все они передаются унифицированным способом. Спасибо Эрикссону. Это позволило для всех файлов написать один обработчик. А вот таблица для каждого объекта - своя. Не обошлось без казуса: сначала некоторые объекты решил нормализовать, выведя идентификатор объекта (varchar(16) а по сути пара varchar(7) один из которых может быть nullable) в отдельную таблицу. А потом поразмыслил и решил "ну его нафиг" и сделал денормализацию. Потеря скорости не ощущается, зато гораздо, гораздо удобнее. Скорее этот тот случай, когда нормализация неуместна.
И вот теперь пошёл процесс долгой и нудной разработки интерфейса отображения информации для каждой таблицы отдельно. Ну или комплексно для идеологически связанных данных.
В первую очередь была построена структура скрипта, чтобы не возвращаться каждый раз и не дорабатывать одно и то же. В принципе получилось что-то вроде ООП-ориентированного меню, но на функциональной основе.
Почему.
Выделение кода в модули в процессе написания очень неудобно для тестирования, так как требует регулярной перезагрузки сервера. Увы, но мне видится необходимость иметь к мод-перлу некоторый интерфейс, который позволял бы отдавать ему, сидящему в апаче, команду на перезагрузку определённого модуля без перезагрузки сервера. Кстати, конечный скрипт он же постоянно перезагружает, не смотря на то, что оформляет его модулем (превращая в хендлер). Впрочем, может быть это заслуга ModPerl::PerlRun. Но натуральные модули перезагружать каждый раз не собирается.
Почему функицональная парадигма.
Потому что (а) глобальные переменные являются таковыми только в контектсе конкретной нитки апача, (б) высока вероятность потерять доступ к определённой переменной из-за интерференции областей видимости и т.п. Пробовал - намаялся. Поэтому проще и надёжнее не надеятся на области видимости, а явно передавать нужные параметры. Это может быть неудобно, если учесть что процедуре на втором десятке вложения потребуется переменная, которая имеется у самой верхней процедуре, но никогда не требовалась тем, что между ними. На эту задачу есть простое решение: делаем хеш, в котором складываем все используемые параметры (ну или почти все) и передаём всегд на него ссылку. Кому что нужно сам из него достанет. Нужно модифицировать - пусть модифицирует.
Со строкой параметром (которые в uri request) тоже получилась интересная история. Сначал пытался передавать их хешем. Но работать с ним не очень удобно, а передавать тем более, если только не по ссылке. В какой-то момент попытался передавать прямо саму строку параметров в оригинальном виде. Добавил пару функций (get_param, set_param) - понравилось. Алгоритмически - очень прозрачно. Научил удалять неиспользуемые параметры. Вчера ещё научил устанавливать несколько параметров на одном вызове (чтобы не делать многократные рекурскии(\). Красота! :) В todo записал необходимость наваять фильтр, чтобы не передавались лишние параметры, накопленные в других режимах отображения.
Как-то так. :)
Наиболее пОлно идеологии mod_perl соответствует парадигма функционального программирования.
ООП тоже хорошо, но в несколько других условиях, чем есть те, в которых нахожусь я. ТЗ по сути нет, ибо состоит из нескольких пунктов (а) разработать и внедрить передачу статфайлов с хоста А на хост Б (сделано), (б) разработать и внедрить обработку (архивацию/резервное копирование, первичную обработку) файлов и загрузку данных в БД (сделано), (в) разработать и внедрить отображение инфы через веб-интерфейс (в процессе). Более подробное и тщательно проработанное ТЗ составить нет возможности, да и необходимости. По большому счёту оно, как и результат реализации проекта никому не нужен. Это позже, когда всё будет и народ станет этим пользоваться, кто-то может и задумается как же они раньше без этого обходились. Нет, на самом-то деле хорошее ТЗ не помешало бы, но "хто-ж йому дасть"© столько времени? Самое грустное, что для этого нужно не просто сколько-то времени, а сколько-то суммарного времени, фрагментами не менее такой-то длительностью. Мало кто понимает, что в отношении рабочего времени далеко не всегда работает коммутативный закон. То есть два куска по часу не эквивалентны по результату одному куску в 2 часа. Это же, кстати, относится и ко сну. :)
Вот собственно поэтому и приходится применять alige-подобный подход на всех этапах. :)
Первые два пункта получились быстро, так как особых настроек под разные типы данных не потребовалось. Почти.
Полтора десятка типов файлов передаются унифицированным способом. Впрочем, технология сия работает уже много лет. В последнюю пару лет была несколько доработана и добавлена фича: возможность передавать файлы в архивированном виде: существенно экономит время на передачу, а архивирование и так происходило на исходном хосте. Собирался было, правда, вместо ftp задействовать scp, но не придумал как быстро и красиво сделать контроль передачи, который в старой схеме используется во всю. В общем, поскольку процессы всё-равно протекают во внутреннем, отгороженном от всех технологическом фрагменте сети, то решено было пожертвовать секюрити в пользу надёжности и адаптивности процесса.
Обработка и загрузка тоже не заняла слишком много времени. Впрочем часть файлов просто бекапятся, а нас сейчас интересует всего с пол десятка. Зато ими передаются два десятка типов объектов. Очень здорово, что хотя в каждом типе объекта разное количество параметров, но все они передаются унифицированным способом. Спасибо Эрикссону. Это позволило для всех файлов написать один обработчик. А вот таблица для каждого объекта - своя. Не обошлось без казуса: сначала некоторые объекты решил нормализовать, выведя идентификатор объекта (varchar(16) а по сути пара varchar(7) один из которых может быть nullable) в отдельную таблицу. А потом поразмыслил и решил "ну его нафиг" и сделал денормализацию. Потеря скорости не ощущается, зато гораздо, гораздо удобнее. Скорее этот тот случай, когда нормализация неуместна.
И вот теперь пошёл процесс долгой и нудной разработки интерфейса отображения информации для каждой таблицы отдельно. Ну или комплексно для идеологически связанных данных.
В первую очередь была построена структура скрипта, чтобы не возвращаться каждый раз и не дорабатывать одно и то же. В принципе получилось что-то вроде ООП-ориентированного меню, но на функциональной основе.
Почему.
Выделение кода в модули в процессе написания очень неудобно для тестирования, так как требует регулярной перезагрузки сервера. Увы, но мне видится необходимость иметь к мод-перлу некоторый интерфейс, который позволял бы отдавать ему, сидящему в апаче, команду на перезагрузку определённого модуля без перезагрузки сервера. Кстати, конечный скрипт он же постоянно перезагружает, не смотря на то, что оформляет его модулем (превращая в хендлер). Впрочем, может быть это заслуга ModPerl::PerlRun. Но натуральные модули перезагружать каждый раз не собирается.
Почему функицональная парадигма.
Потому что (а) глобальные переменные являются таковыми только в контектсе конкретной нитки апача, (б) высока вероятность потерять доступ к определённой переменной из-за интерференции областей видимости и т.п. Пробовал - намаялся. Поэтому проще и надёжнее не надеятся на области видимости, а явно передавать нужные параметры. Это может быть неудобно, если учесть что процедуре на втором десятке вложения потребуется переменная, которая имеется у самой верхней процедуре, но никогда не требовалась тем, что между ними. На эту задачу есть простое решение: делаем хеш, в котором складываем все используемые параметры (ну или почти все) и передаём всегд на него ссылку. Кому что нужно сам из него достанет. Нужно модифицировать - пусть модифицирует.
Со строкой параметром (которые в uri request) тоже получилась интересная история. Сначал пытался передавать их хешем. Но работать с ним не очень удобно, а передавать тем более, если только не по ссылке. В какой-то момент попытался передавать прямо саму строку параметров в оригинальном виде. Добавил пару функций (get_param, set_param) - понравилось. Алгоритмически - очень прозрачно. Научил удалять неиспользуемые параметры. Вчера ещё научил устанавливать несколько параметров на одном вызове (чтобы не делать многократные рекурскии(\). Красота! :) В todo записал необходимость наваять фильтр, чтобы не передавались лишние параметры, накопленные в других режимах отображения.
Как-то так. :)