Проклятая старая CRM

    Весь прошлый год наши ребята допиливали CRM 2.0 с BPMS Camunda и всего десятью процессами вместо сотен статусов, а затем старались раскатать ее на пользователей и сервисы, ничего не уронив. Надеюсь, окончательно выпилив первую црм-ку (старейшую часть всего Skyeng) из нашей экосистемы, они поделятся граблями и находками здесь.



    А пока, заинтересовавшись темой, я нашел похожий случай — и решил расспросить Дмитрия Косова из Финама про их опыт отказа от наследия ранних 2010-х.

    Привет, я тот самый “Сережа из Брянска”, который решил прокачивать знания разработки, ведя блог и скринкасты по теме PHP. В этом году я хочу добавить к своим активностям подкаст: приглашать в него коллег по отрасли. В первом эпизоде — рассказ о переезде с первого Zend на Symfony. Если захотите больше технических подробностей, также посмотрите доклад Димы на Youtube. Ну в нашем обсуждении после доклада вы узнаете:

    • как не терять и находить мотивацию, если понимаешь, что до запуска твоего кода на продакшне — еще целый год,

    • почему любая документация если не врет, то привирает,

    • и как организован процесс двухлетнего рефакторинга без остановки производства фич на примере реального проекта и команды.

    Приятного прочтения или прослушивания.



    Между какими фреймворками выбирали в 2011-м году. И как выбирали новый в 2016-м


    Дима, Финам: Я специально посмотрел, готовясь к выпуску: у нас ровно 4600 файлов в папочке, где именно наш код — не vendor, не всякие js’ки. Весит эта папочка 16 метров. А первый коммит у нас бы сделан аж в декабре 2011 года, — его автор до сих пор работает, это наш тимлид.

    Изначально стек был выбран правильно. И даже в 2012-м году он было вполне современным — первый Zend был вполне актуален. Я тогда работал на другой работе, но помню, что мы как раз в 12-м где-то в конце весны выбирали стек для нового проекта. Мы смотрели на:

    • Zend — как раз вышел второй, но был слишком молод, по нему не было комьюнити,

    • первый Yii — но нам не понравилась концепция ActiveRecord,

    • Phalcon,

    • и что-то еще из экзотики.

    И тоже выбрали первый Zend. В тот момент это был хороший, актуальный выбор. Но язык ушел вперед. А ведь хочется использовать нормальные неймспейсы, а не именование классов через нижнее подчеркивание. Хочется подключать какие-то готовые библиотеки из open source, которых, понятное дело, под первый Zend больше никто не пишет. Хочется привлекать сотрудников в команду — пару раз, когда мы искали новых людей, у некоторых прямо на лице было написано: “Я за это не возьмусь”.

    В конечном итоге у первого Zend просто прекратилась поддержка. Например, на 7.0 они еще выпустили патч обновления безопасности, а 7.2 и 7.3 мы патчили уже сами.

    Мы немножко тянули с началом процесса переезда.


    Какого-то глобального рисеча не было — мы просто посмотрели, что есть современного, актуального. Сравнили с тем, что на других проектах: мы не единственная PHP-команда в компании. Поняли, что Symfony всем устраивает — выглядит как проект, который будет жить еще некоторое количество лет, имеет обширное комьюнити, массу готовых библиотек, новых утилит и так далее.

    Начинал это дело я — впиливал первые моменты именно для переезда, по движению в сторону Symfony. Когда я пришел, меня погружали в разные части проекта, чтобы я познакомился с ним максимально широко — и к моменту начала масштабного рефакторинга я знал его достаточно хорошо. И еще один товарищ пришел после того, как мы начали. Мы погружали его в процессе — но старались не сильно пугать. По крайней мере, по началу)

    Ок. Мы выбрали фреймворк. Что дальше?


    Сережа, Skyeng: Есть два пути — можно переписать всё и сразу. Можно попытаться потихоньку перетаскивать. С чего вы начали?

    Дима, Финам: Мы начали с холивара, каким путем идти. Опыта переписывания такого объема не было ни у кого. Например, у меня с предыдущего места работы был опыт переписывания небольшого автономного сервиса — там мы просто на месяц заморозили разработку, все переписали и поехали дальше. Здесь нам не хватило бы и года. Может быть, процентов 80 мы бы и успели сделать за за год, но, знаешь…

    Есть принцип: первые 80% работы занимают 80% времени. Оставшиеся 20% работы займут еще 80% времени.


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

    А вот почему так. У нас больше 250 таблиц в базе данных, и если отмести какие-то служебные таблички, это порядка 200 сущностей. Они довольно сильно друг с другом связаны и за счет этого количества связей очень сложно побить код на какие-то автономные логические куски. Как не разбивай, все равно из этого куска будет торчать связь: например, звонки и телефония связаны с менеджерами и клиентами. Поэтому мы поняли: если развернуть новое приложение, начать писать новые фичи для него, а старые потихоньку переносить — это выльется в двойную работу. Ведь код, который мы перенесем в новое приложение, нельзя полностью выпилить из старого. И нам придется поддерживать его в двух местах.

    Потом мы вспомнили другой опыт, который уже был у нашей команды.


    Это опыт переписывания слоя к доступу данных. Потому что когда-то давно вместе с первым Zend’ом в качестве основной базы данных была выбрана Mongo. Но практика показала, что выбор это не очень правильный.

    Сережа, Skyeng: Да, у вас реляционные связи все, а вы документо-ориентированную базу выбрали.

    Дима, Финам: Да, и когда я пришел, ребята как раз были в процессе переписывания с Mongo на PostgreSQL… И нам пришла в голову идея, что у нас есть слой доступа к данным. И раз мы уже умеем переписывать слои к доступу данных, может быть, мы возьмем от него чуть-чуть шире и захватим сразу слой ORM.

    Если представить приложение как такой пирог, будет 5 слоев: ORM, доступ к данным, бизнес-логика, контроллер, вьюхи. И мы можем затронуть 2,5 слоя — полностью поменять ORM и доступ к данным, плюс частично — бизнес-логику. Не сами алгоритмы, а те классы и объекты, с которыми эти алгоритмы работают. Я четко знал, что тут можно впилить отдельно доктрину, ну и сделал это.

    Так что я влез в наш bootstrap, инициализировал там доктрину, прописал все необходимые настройки — и отдал ребятам на код-ревью со словами: “Ну, кто-то должен был это начать”.


    Начало пути может выглядеть примерно так. А дальше мы применили принцип, что мамонта нужно есть по частям. Иногда куски на поверку оказывались больше, чем мы думали, но базово в двухнедельный спринт бралась одна задача по переезду — и мы следили, чтобы не было фичевых задач в той же области.

    Я ловил баги, откатывал, выкатывал


    Сережа, Skyeng: Все-таки рефакторинг ответственная штука, как вы себя подстраховывали?

    Дима, Финам: У нас есть некоторое количество юнит-тестов — ключевые моменты они покрывают. Есть какое-то количество функциональных тестов, автоматизированных нашим тестировщиком. Основная работа CRM — это работа с данными. И тестировать без данных, одними юнит-тестами не всегда получится: проще отправить пакет, проверить, что он нормально обработается, что по нему создалась сущность с нужными параметрами.

    Естественно, мы проверяли много руками: особенно какие-то ключевые и важные вещи, вроде тех же клиентов и звонков.


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

    Сережа, Skyeng: Пройдя не весь, но вот уже наверняка больше половины пути, чтобы ты себе посоветовал тогдашнему?

    Дима, Финам: Я бы, наверное, посоветовал немножко раньше развернуть то самое Symfony приложение поверх нашего. Чтобы убедиться, что то, что мы пишем, то, что мы делаем, оно действительно заработает. Я помню, как мы его развернули, запустили сначала из консоли, потом из контроллера, постучались к нашему слою бизнес-логики — и убедились, что приложение его видит, может обратиться ко всем сервисам, дернуть все методы, выгрузить результаты.

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

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

    p.s.


    Спасибо, что читали и слушали. Больше подкастов по теме PHP можно найти здесь.

    А если хочется больше интересных докладов и разговоров вокруг них, «приходите» на третий виртуальный PHP-митап 30 мая.
    Skyeng
    Крупнейшая онлайн-школа Европы. Удаленная работа

    Комментарии 3

      +2
      Есть принцип: первые 80% работы занимают 8020% времени. Оставшиеся 20% работы займут еще 80% времени.


      Поправка: первые 80% работы занимают 20% времени а оставшиеся 20% работы займут over 200% времени. © Городские легенды
        0

        Надо различать, что есть 100% — план или факт :) По плану обычно равномер распределено :(

        0
        Интересно было бы услышать и ответ на вопрос — почему выбрали РНР?

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

        Самое читаемое