Рефакторинг
15.10.2010 технологии
Расскажу про свой опыт рефакторинга на примере эволюции PHP-функций чтения/записи для Daos.
- Сперва данные (в массиве) просто подвергались [де]сериализации и записывались/читались без всяких проверок. Выяснилось, что стоит попасть в данные одинарной кавычке, как всё рушится.
- Переписал на JSON, но это было совсем недолго. Оказывается, современные версии PHP далеко не у всех хостеров установлены. Кроме того, сериализация в JSON коряво работала для русских символов, они преобразовывались в абракадабру. В топку.
- Осенило! Почему бы не использовать var_export? Это очень удобно, и такой способ даёт возможность легко просматривать и редактировать файлы с данными. Замечательно. Замедление в сравнении с JSON и сериализацией если и есть, то ничтожное.
Однако, всё ещё не было никаких проверок на одновременный доступ. Я почему-то был уверен, что PHP де-факто исключает такие ситуации, контролирует их. Я ошибся. Но это не камень в огород PHP, я считаю, что он и не должен их отслеживать. - Узнаю про flock и делаю версию с блокировками. Вот теперь в огород PHP полетят камни. Увы, но flock на самом деле не гарантировал ничего…
- Особенно если его неправильно использовать :) Но переделанная функция всё равно допускала сбросы.
- Вместо flock я стал использовать переименование файла для записи и дополнительно записывал бэкапы. Почему-то без проверки целостности. Недостатки такого подхода: а) сбросы всё равно были! б) невозможно точно посчитать статистику при большой нагрузке.
- И вот теперь тестирую уже седьмой вариант, получается. Переписал всё с нуля, сейчас для чтения и записи проверяется маленький блокировочный файлик. Новые функции пока что показали себя с наилучшей стороны, ночное стресс-тестирование завершилось нулевым количеством сбросов. Предыдущий вариант при аналогичных условиях сбрасывал данные 25 раз.
Такие дела. Я теперь понимаю, почему в книге «Совершенный код»1 Стив Макконнелл рекомендует проектировать методы несколько раз вообще всегда. Потому что очень редко с первого раза учитываешь все варианты. Хотя, конечно, ценность этой рекомендации сильно зависит от опыта программиста — очевидно простые функции можно писать сразу.
Я за последние несколько дней набрал месячную норму багажа знаний, причём не только в программировании, я теперь лучше понимаю UNIX, что вообще кайфово, настоящее удовольствие получаю от этого. А за последние два месяца знаний прибавилось, пожалуй, больше, чем за год ранее. Классно.
В следующей заметке я расскажу о тестировании различных вариантов функций чтения/записи. С цифрами, таблицами, может даже картинками :) Кроме меня этой задачей заинтересовались ещё несколько человек, спасибо им большое. В исследовании будут рассматриваться четыре варианта реализации:
- мои старые функции,
- мои новые тестовые,
- функции Jungle
- и класс от Akek$.
Уже появилось продолжение. Пишите отзывы!
1 Читайте мой отзыв о книге «Совершенный код».
Комментарии
Комментирование этой статьи закрыто.
« Vimperator недостаточно хорош Кто помнит или знает про Sentinel? »
Все-таки ты Тормоз =))). Ну кто для финансовой системы во главу ставит удобство установки, а не надежность??? Используй уже хоть какую-то базу»
про кавычку совсем не понял
про json тем более
раз они «преобразовуются» значит так нужно, ты не находишь?
Это не финансовая система. И я уже с файлами пришёл к достаточно совершенному решению, на кой чёрт здесь база? + Уже раз 20 говорил, что в этом коде уже не буду переделывать всё, это просто глупо. В Daos 2.0, возможно, будет БД, здесь — нет. И точка.
Миша, ссылки же есть. Почитай. Не нахожу, что так нужно в UTF-8.
Надеюсь маленький блокировочный файлик со случайным содержимым известным только создавшей его функции?
Да, и неплохо бы писать в отдельный файл лог заказов, просто через >>. На случай восстановления из крэша
К чёрту базы! Продолжаем в том же духе =)
Тормоз, есть еще такая конструкция в пыхе: declare() и к ней register_shutdown_function() (не уверен в точности написания последней, пробовал только в процессе обучения, уже не помню, погугли).
Короче алгоритм оставляем такой же, но после выполнения скрипта запустится неявно вызываемая функция, которая с нормальным принудительным flock сверит бекап и обновление. Если где найдется косяк – восстановит и перепроверит. Это уже что называется «забетонировать» дыру.
ЗЫ: Насчёт регулярок ты неправ. Отпишусь к твоему комменту у меня чуть позже.
Йопрст…
Только сейчас «грепнул по сорцам»…
А почему ты не используешь flush()??? Это же как раз нужное тебе – принудительный сброс буфера записи на диск до всяких анлоков и фклоузов =)
Привет. Вот еще по поводу блокировки файлов:
1. forum.dklab.ru/viewt…
2. forum.dklab.ru/viewt…
3. www.forum.dklab.ru/v…
4. cubicspot.blogspot.c…
пока ваш зенд будет парсить параметры по паттерну из строки, другой скрипт заблокирует файл
от записи и перезаписи с каждым реквестом, винчестер очень быстро скажет вам спасибо, попомните мое слово
Миша, то верно подмечено. Только вот «спасибо» будет говориться хостинг-провайдеру, поэтому особо опасаться нечему.
Хотя, база данных это те же кучки файлов, при записи в базу точно также перезаписываемые. Так что пофиг в принципе.
Зачем блокировочному файлу содержимое вообще?
Она тут не к месту совсем. Но declare я использовал для оптимизации, удобно отслеживать время выполнения отдельных частей скрипта. И flush() тоже совсем для других целей предназначен.
P.S. Сегодня ночью оставлял на тест вариант с сессиями, предложенный асоциальным программистом, правда, сделал его по-своему. И вот эта штука показала себя весьма неплохо. Так что рефакторинг продолжается :)
содержимое для проверки, но в твоем случае оно реально никчему
@Бутылкус еще как есть чему, думаешь долго провайдер будет такой скрипт у себя терпеть?
база данных это далеко не просто кучи файлов, начнем с того что это один файл, в основном, и закончим тем что работа с ним абсолютно по другому организованна
я надеюсь, по крайней мере :)
в современных так уж точно
Ну тут уж смотря какой хостер, наверно. У них разве нет каких-нибудь кэшиков прямо в оперативной памяти? У меня в /tmp tmpFS, я пробовал туда Daos ставить — работает.
Много ли людей его в tmpfs поставят, как думаешь? Если они настолько тупы что субд настроить не могут (из твоих же соображений)?
Ты нифига не понял. Я имел в виду, что нельзя быть увереным на 100%, что хостер не оберегает свои диски с помощью каких-либо технологий. В конце-концов это именно его диски и его проблемы.