что такое pet project
Pet-проекты: прихоть, инструмент самосовершенствования или попытка отвлечься?
Привет, Хабр! Меня зовут Кирилл Кошаев, я Java-разработчик в «Газпром информ» и преподаватель профессии Java-разработчик PRO на образовательной платформе Skillbox. Сегодня хотел бы поговорить о такой интересной теме, как pet-проекты. Здесь, на Хабре, они есть у многих, у меня, кстати, тоже. И я хотел бы обсудить важность pet-проектов для представителей IT-отрасли.
Личный кейс
Сперва расскажу о собственном опыте ведения pet-проектов. Как и говорилось выше, у меня их много. Но я не веду все их одновременно: большинство идет в «долгий ящик», какие-то забрасываются и забываются, а некоторые становятся серьезными проектами, которые не стыдно и в портфолио показать.
После долгих месяцев работы над проектами “в стол”: приложения для подсчета фруктов в корзине, вывода фигур в консоль при помощи ASCII и кучи тестовых стендов для понимания работы библиотек выбранного мной языка, ко мне пришло осознание определенного застоя на одном месте.
Размышления на эту тему привели меня к следующему решению: необходимо собрать все, что я изучил в одну большую кучу и запилить уже что-то более серьезное, что-то, что будет не просто очередным tutorial example, а самодостаточным приложением, которое воплотит в себе конкретный функционал и будет решать определенные задачи. Появилась амбиция разработать что-то полезное, что можно было бы скачать/загрузить/установить и использовать на своем устройстве всем, кто того пожелает. Осталась сущая малость — придумать идею.
Генерация идеи — камень, на который находит коса всякого начинающего программиста, приступающего к своему первому pet-проекту. В первую очередь, я столкнулся с тем, что куда бы я ни посмотрел и что бы ни придумал, в 90% случаев аналогичное приложение уже существовало на рынке и даже не в единственном воплощении, а оставшиеся 10% занимали идеи, на реализацию которых уже требовалась команда и, соответственно, все необходимые для командной разработки инструменты и технологии, а ведь я только-только разделался с ядром выбранного мной языка программирования.
Как раз здесь обычно и наступает переломный момент, поскольку нечто вроде «Hello, World» и простых задачек писать уже не хочется, а для хорошего pet-проекта нет достойной идеи. У новичков здесь обычно звучит фраза в стиле: “Ну… я не знаю, что делать дальше, все дико сложно и я не очень понимаю, что еще можно написать на этом языке X, кроме всех тех helloworld-ов, которые я уже написал”. Далее программирование либо оказывается заброшенным вообще, либо проходит смену изучаемого языка/технологии/библиотеки/фреймворка (нужное подчеркнуть), и все начинается с самого начала, пока человек снова не придет к этой переломной точке.
Выходом из этой ситуации для меня стало решение воплотить в первом pet-проекте игру. Мне показалось это идеальным форматом по соотношению трудоемкости, интереса и сложности применяемых технологий. Я немедленно приступил к делу и начал раскапывать различную информацию о том, как, с помощью каких технологий и в рамках изучаемого мной языка, я смогу разработать и выкатить в одиночку небольшую инди-игру, пройдя все сопутствующие этапы самостоятельно.
Почему именно игра:
Сколько их будет, pet-проектов?
Я уверен, что pet-проекты были, есть и будут время от времени возникать в практике практически любого программиста. Почему? Я считаю, что, когда заканчивается эра Hello World программ, начинается эра pet-проектов. Иными словами, когда вы, как начинающий программист, упираетесь в потолок практической ценности от написания простейших программ типа “вывод в консоль звездочками елочек”, “greetings app”, и тому подобных, для дальнейшего роста вам придется переходить к написанию более сложных программ, то есть pet-проектов.
В работе над pet-проектом вы по-прежнему будете писать код, но теперь вам потребуется некая комплексная идея. Еще недавно вы ликовали, запуская MySimpleWhishListApp у себя на localhost, и тут внезапно оказывается, что это только предгорья, а новые вершины лишь слегка видны за скрывающим их туманом технологий, библиотек и инструментов, которые понадобится освоить, чтобы туда добраться.
И так будет происходить еще не раз до тех пор, пока вы не достигните Олимпа всей этой ИТ-тусовки и не станете senior-архитектором в уважаемой корпорации, владельцем собственного стартапа или осядете где-то на подступах, предпочтя расти по горизонтали, а не вертикали.
А времени сколько на это уходит?
Моя личная практика, показывает, что время, уделяемое pet-проекту, не является константой. Я не подчиняю работу над pet-проектом фиксированному графику, а работаю в свое удовольствие и в меру возможностей.
Вы должны понимать, что это именно pet-проект, и изначально в большинстве случаев он представляет ценность исключительно для вас, если только выбранная идея не окажется настолько удачной, что pet-проект перерастет уже в production-grade. На начальных этапах, пока вы полны энтузиазма и еще не столкнулись с первыми сложными проблемами реализации, pet-проекту может уделяться довольно много времени, вплоть до полного рабочего дня.
Еще один важный нюанс — судьба таких проектов. На мой взгляд, предопределить ее нельзя. Внезапно вас может озарить, кажущаяся на первый взгляд совершенно гениальной идея. Вы на голом энтузиазме напишете пару тысяч строк кода, а потом внезапно поймете, что запал прошел и изначальная идея уже не кажется такой гениальной, как раньше. В другой раз вы проведете за развитием очередного pet-проекта пару месяцев, доведете дело до версии 1.0, выполните релиз, но дальше версии 1.0 уже не пойдете, предпочитая переключиться на что-то другое. И конечно, есть все шансы, что вы попадете в яблочко, и ваш pet-проект начнет стремительный взлет к высотам production-grade проектов.
Польза pet-проекта для начинающего программиста
Новичку работа над pet-проектами позволяет перейти от экспериментов с возможностями изучаемого языка к реальными командным проектам, за работу над которыми платят деньги. Для продвинутых программистов работа над pet-проектами — возможность исследовать и пробовать в деле различные технологии, например с помощью pet-проекта подробно изучить процесс создания REST-сервисов. Наконец, pet-проекты можно создавать и ради фана. Например, я иногда люблю воспроизводить в различных вариациях game of life, чтобы в качестве разрядки отвлечься от работы и предотвратить выгорание.
Начинать свой первый pet-проект следует в интересной для себя области. Моим первым языком программирования был VisualBasic, но хоть сколько-нибудь значимые программы я начал писать только после 1.5 лет программирования на Java. В этом языке, на мой взгляд, есть в целом два больших направления: enterprise и мобильная разработка. И поскольку к enterprise-разработке я впервые подошел только спустя еще год, на момент создания первого pet-проекта мой выбор был очевиден. Именно поэтому первый мой проект — небольшая 2D игра для смартфона. C тем же успехом это могло бы быть все, что угодно, например, какие-нибудь Arduino/RaspberryPI проекты в том случае, если бы я увлекался электротехникой. Или, скажем, какая-нибудь новая js-библиотека, если бы моим основным языком был JavaScript, а не Java.
В качестве вывода
Pet-проект — нечто среднее между простейшими программами, на которых вы учитесь работать с выбранным языком, и production-grade проектами, на которых вы зарабатываете деньги. Зачем они нужны? Pet-проекты, в первую очередь, учат разработке. Не простейших программ, а именно проектов, из которых позднее и при благоприятном стечении обстоятельств могут вырасти production-grade проекты.
Pet-проекты — это личный гараж-мастерская, где программист или даже небольшая команда разработчиков, комбинируя различные технологии, идеи и подходы к их реализации, может в итоге получить то, что называется MVP — минимально жизнеспособный продукт. Вместе с тем, pet-проекты позволяют вам не только экспериментировать и весело проводить время. Как было сказано выше, они учат создавать целостные проекты, ориентироваться в огромном мире библиотек, фреймворков и прочих инструментов. Pet-проекты заставляют нас двигаться дальше, осваивать новые технологии, расширять свой инструментарий, работать в команде, выйти за пределы HelloWorld и MyFirstGreetingsApp программ.
Pet-проекты: зачем они нужны, и стоит ли тратить на это время
Личные проекты для разработчиков и инженеров – важная и интересная тема. В интернете есть множество упоминаний того, как такие проекты приводят к масштабным достижениям – так было в случае нобелевских лауреатов по физике Андрея Гейма и Константина Новоселова, чей эксперимент первоначально состоялся вечером в пятницу, когда ученые по традиции тестировали различные безумные на первый взгляд идеи.
Многие компании также пытаются стимулировать такую активность работников – в Google было правило 20%, которое привело к рождению Gmail, AdSense и Google News, а в Twitter инженеры получали неделю свободную от обычных обязанностей для экспериментов. Да что далеко ходить – мы делали вебинар с Android-разработчиком Дмитрием Рязанцевым (вот его статья про работу на Toptal) – запущенную им игру Draw and Ride скачали 250,000 раз, а начиналась она именно как pet-проект.
Звучит вдохновляюще, но насколько подход pet-проектов актуален в 2021 году? Считают ли до сих пор инженеры наличие таких проектов важным для себя и профессионального развития? С какими проблемами сталкиваются те, кто ими занимается? В новой статьей мы решили найти ответы на эти вопросы.
Есть целый ряд аргументов, которые всегда приводят сторонники личных хобби-проектов. Вот главные и них.
Разработчик из Лондона Чанна Джайамуни (Channa Jayamuni) в своей статье на LinkedIn так описывает пользу pet-проектов:
Разработка софта – отнюдь не самая увлекательная профессия до тех пор, пока вам не дали поработать над любимыми задачами.
Если вы не работаете в Google или в похожей продвинутой компании с интересными проектами и низким уровнем стресса, то вряд ли ваша работа сплошь состоит из таких задач.
В большинстве случаев разработчик может ожидать получить смесь из унылой рутины и относительно неплохих задач. Далеко не всем везет работать с новейшими технологиями в профессиональных средах, чтобы оставаться на острие развития отрасли просто выполняя рабочие обязанности.
По мнению инженера, решить эти проблемы наилучшим образом помогает именно развитие собственных проектов в свободное время.
Многие руководители прямо заявляют о том, что наличие портфолио собственных проектов у инженера – один из ключевых пунктов при найме.
Так директор компании-разработчика открытой NoSQL базы данных ravendb Айенде Райен (Ayende Rahien) говорит о том, что при поисках разработчиков смотрит на наличе страсти к работе. По мнению топ-менеджера, у специалистов, которые не могут найти время на развитие собственных проектов, такой страсти нет, они не собираются выходить за рамки рабочих обязанностей. Нанимать таких разработчиков в небольшую команду может быть не лучшей идеей.
Майк Миллер (Michael Miller) работает на позиции Engineering Manager в Bloomberg LP и считает, что компании должны официально позволять ведущим специалистам развивать свои проекты в рабочее время, и что такой подход может быть отдельной HR-плюшкой для талантливых работников:
Ваша задача – делать таких ведущих работников максимально счастливыми. Никогда не знаешь, что произойдет, если позволить талантливому специалисту развивать свою страсть.
Вполне вероятно, это позволит открыть новую супер-звезду. Понятно, что возможность официально развивать свои проекты нужно заслужить.
Если ты едва справляешься с непосредственными обязанностями, то о каких pet-проектах может идти речь?
Несмотря на очевидные плюсы, существует и целый ряд трудностей при работе над дополнительными проектами вне работы. Кто-то называет эти трудности мифами, как инженер Twitter Аннель Де Джагер (Annelle De Jager). Тем не менее, вот как выглядит этот список:
Написание кода – творческая работа, которая требует значительного количества сил. Инженерам просто необходимо отдыхать, плюс никто не отменял домашние дела, общение с друзьями и родственниками. В таких условиях найти время еще и на pet-проекты довольно трудно.
Пункт частично вытекает из предыдущего. Если у человека есть семья и друзья, а он в какие-то моменты делает выбор не в их пользу, а в пользу написания кода – помимо работы! – но за который ему даже с высокой вероятностью не заплатят – это может выглядеть странно и даже вызывать обиды.
Мы решили прояснить отношение разработчиков к ведению pet-проектов в текущих условиях удаленки и глобальной пандемии. Поэтому мы опросили знакомых инженеров из таких компаний как Gett, «Лаборатория Касперского», Uber, Smartcat и др. и задали им вопросы о том, развивают ли они pet-проекты и с какими трудностями сталкиваются при этом. Вот главные выводы по итогам опроса:
Если вы ведете свои pet-проекты, укажите в боте @g_jobbot информацию о своих проектах, чтобы получать вакансии с учетом использованных в них технологий. Новая работа – отличный способ «монетизации» хобби!
Ведете ли pet-проекты вы? Если да, то зачем?
Почему мы должны перестать заниматься пет-проектами
Я проработал над своим проектом три года. Причем этот был далеко не первый, у меня скопилось целое кладбище незаконченных проектов. Но ведь на основной работе я вполне успешно справляюсь со своими задачами. Нет проблем ни с оценкой сроков, ни с исполнением.
Конечно, такая ситуация не должна никого удивлять: работа — это работа, а домашний проект должен приносить удовольствие, можно делать самое вкусненькое, а не заниматься однообразной шлифовкой мелких деталей, которые необходимы для релиза.
Все это так, но удовольствие видеть, как твоим продуктом пользуется кто-нибудь еще, видеть, что он решает чьи-то проблемы — несравнимо выше. Так что я решил во что бы это ни стало довести хотя бы один проект до релиза.
Нужно было всего лишь разобраться, что мне мешало сделать это раньше.
Самое начало: что такое пет-проект?
Давайте перестанем заниматься пет проектами, это что-то слишком неопределенное, слишком непонятное, давайте фокусироваться на том, что приведет нас к логическому завершению.
Проект. Просто проект
Каждый знает как работать над проектом. Мы занимаемся этим изо дня в день на основной работе. Вы, наверное, представляете себе все эти таблицы, диаграммы, тайм-трэкеры и думаете, что проект — это скучно. Не стоит переживать. Свой собственный проект — это очень увлекательно. Прежде всего подумайте о перспективе: наблюдать за развитием своего проекта очень приятно. И потом — нужно просто увидеть, как этим пользуется кто-нибудь еще. В любом случае, опыт работы над проектом в качестве и заказчика, и исполнителя, и менеджера никогда не будет лишним.
Терпение безусловно понадобится, но результат стоит этого.
Мне часто приходится повторять себе:
Какова моя цель? Для чего я это делаю?
На пути много разных интересных блестяшек, которые постоянно отвлекают от основной цели. Ответ на этот вопрос поможет правильно расставить приоритеты.
Время
Тайм-менеджмент — это огромная проблема. Написано масса литературы, существует множество лекций и пр., но, конечно, же универсального алгоритма не существует.
Я могу просто дать несколько советов, которые в моем случае работают. Начинайте с планирования. Нет ничего лучше, чем старые добрые диаграммы Ганта. Разбейте свой проект на задачи, сделайте временную оценку каждой задачи, выпишите их. Убедитесь, что для завершения всех задач потребуется больше одной жизни, перенесите некоторые задачи в бэклог «на потом». Повторите все сначала. Опять же, четкое понимание цели поможет расставить приоритеты для каждой задачи.
Кстати, при оценке задачи учтите, что дни — это уже не те самые восьмичасовые рабочие дни. Засекайте время, которые вы потратили на выполнение каждой задачи. Во-первых, это сделает временную оценку более аккуратной. Во-вторых, тайм-трекинг будет хорошей подсказкой, что вы движетесь в правильном направлении (или наоборот — в неправильном). Очень важный момент — таймтрекинг поможет не терять мотивацию в те моменты, когда кажется, что усилия не приносят никаких результатов.
Ресурсы
Изначально может казаться, что у персональных проектов нет ресурсов, которыми нужно управлять, но это не так. Для начала подумайте о своем личном времени. Можете разделить вашу зарплату на количество рабочих часов и получить (очень грубо) вашу стоимость как специалиста в час. Теперь подумайте о деньгах: что дешевле — починить кран на кухне самостоятельно, или заплатить кому-нибудь за эту работу и сэкономить свое время? Если вы собираетесь зарабатывать деньги своим проектом, то почему бы не начать раньше? Вы можете нанять человека для создания сайта, SEO статьи, или проведения маркетингового исследования.
Самый ценный ресурс вашего проекта, его жизненная сила — это ваша мотивация. Не ждите вдохновения, управляйте своей мотивацией как и любым другим ресурсом.
Опять же — никаких серебренных пуль, только советы:
Держите под рукой список задач. Всегда есть что делать, даже если вы не в настроении делать что-то одно, можно заняться и другим. Просто убедитесь, что вы не тратите время на ненужные задачи.
Не дописывайте до точки, оставляйте работу на завтра. У меня есть только 2-3 часа после работы на свой проект. Намного проще продолжить вчерашнюю задачу, чем начинать вникать в новую. А еще это избавляет от «раскачки» (всего 2-3 часа, на фейсбук, любимые блоги и комиксы просто не остается времени).
Сейчас вы прочитали про управление проектом и, возможно, думаете: «А в чем же собственно фан?» Я могу поспорить, что ваш домашний проект очень инновационный. По крайней мере для вас это что-то новенькое (иначе зачем это?).
Хм. Управление инновационным проектом, в условиях полной неопределенности, постоянный поиск. Погодите, разве это не…
Стартап
Стартапы — это очень весело и увлекательно. Спросите кого угодно. Более того, сейчас вы можете найти тонны литературы, видеоуроков, блогов, лекций, курсов о том, как управлять стартапом. Еще лучше: стандартные стартап-техники можно брать и использовать в своем проекте уже прямо сейчас.
Минимально жизнеспособный продукт — MVP
Minimum viable product, или MVP — это общепринятый термин (МЖП звучало бы странно). Стартапы используют MVP чтобы подтвердить (или опровергнуть) гипотезы о продукте. Изначально — «этим будут пользоваться», «это будут покупать», и пр.
MVP в домашнем проекте — не совсем тоже самое, что и в стартапе. Что-то минимально жизнеспособное нужно сделать как можно раньше, с минимальными затратами, но его основная задача — поддерживать вашу мотивацию. Если работать над чем-то, что нельзя «пощупать», это очень быстро надоест.
Например, если мне предстоит написать массу кода перед тем, как я смогу что-нибудь запустить, я делаю юнит тесты. Возможность запустить юнит тесты помогает двигаться дальше, не говоря уже о пользе раннего тестирования.
Что-то рабочее нужно иметь под рукой постоянно. И это не только мотивирует, но и дисциплинирует. Например, заставляет сфокусироваться только на одном изменении, вместо внесения множества изменений за раз, чтобы ничего не сломать, если говорить о коде.
Аудитория
Основная проблема стартапа — поиск своей аудитории. Это тоже можно взять на заметку (есть масса литературы и уроков). Вы не одни, есть еще люди, которые потенциально заинтересованы в вашем проекте также, как и вы сами. Найдите их, расскажите о своей идее. Вы можете найти единомышленников, наслушаться хороших советов и замечаний. В любом случае, отзывы живых людей мотивируют лучше тысячи видео с котиками.
Можно использовать множество других идей из мира стартапов, все зависит от того, чего вы хотите добиться своим проектом.
Продуктивность требует жертв
Времени постоянно не хватает, не только на личные проекты, а вообще. Мы не можем увеличить количество часов в сутках, но мы можем быть более продуктивными.
Режим. Плохие новости, да. Люди наиболее продуктивны, когда живут согласно цикличному графику.
Если сегодня я лягу в 4 утра, завтра я не успею выполнить все задачи на основной работе, прийдется овертаймить, и на персональный проект не останется времени, и т.д. Лучше придерживаться графика.
Спорт. Как ни крути, а тушку нужно поддерживать в хорошем состоянии, иначе — последствия будут печальными. Занятия спортом трудно начать, но зато уже через пару недель тело начнет просить следующую порцию физической нагрузки, да и состояние, когда хочется просто бежать вперед, потому что можешь, словами не описать.
Баланс. Все как всегда, но при наличии персонального проекта ситуация становится более критичной. Я и сам много читал про важность уметь балансировать, но при этом умудрялся загнать себя в burnout. Burnout — это состояние физического и эмоционально истощения. Даже понимая свое состояние, уже не остается сил на то, чтобы переключиться, поехать куда-нибудь, просто отдохнуть. И ты действуешь по привычке, как белка в колесе, не в состоянии вырваться из этого круга.
Вот и все. Я надеюсь, что эта статья поможет вам закончить ваш домашний проект, а с ним Мир станет пусть чуточку, но лучше.
Как завести pet project и не получить выгоды
Статья описывает использование pet project как способ поддержания и улучшения навыков. Автор создал PHP библиотеку для установки ФИАС из XML файлов.
Я редко меняю места работы, поэтому, учитывая естественное стремление каждой организации к фиксированным процессам, любая задача превращается в рутину. С одной стороны для бизнеса выгодно поддерживать такое состояние, с другой для меня это означает либо полную потерю, либо устаревание навыков. PHP развивается стремительными темпами, а, следовательно, и потенциальное отставание тоже растёт стремительно. Наконец, все мы знаем, что сегодня программисту сложно найти хорошую работу без знания Elasticsearch, RabbitMQ, Kafka и других технологий, которые в моей повседневной работе появляются не часто.
После запуска очередного типового сайта, я решил, что пора что-то менять. Работу менять не хотелось, зато я вспомнил как на одной из конференций докладчик рекомендовал использовать собственный факультативный проект, так называемый pet project, для обучения. Метод показался подходящим и я решил попробовать.
Выбор задачи
Выбор задачи оказался самой сложной частью затеи. В голову ничего особенного не приходило: какие-то сервисы, вроде парсера вакансий, которые легко можно реализовать на привычном стеке. Я забросил мысль о проекте на несколько месяцев, пока случайно не увидел новость о хакатоне министерства финансов. В нем предлагалось использовать один из списка источников открытых данных для создания сервиса. Среди прочих была указана и федеральная информационная адресная система (ФИАС). К сожалению, хакатон к тому времени уже закончился.
О ФИАС я узнал впервые, но задача показалась интересной. Судите сами: около 30 Гб XML файлов, порядка 60 миллионов строк в базе данных и, более того, библиотека потом могла оказаться полезной в работе. На Github нашлось несколько готовых решений, но это меня не остановило. Наоборот, на основании их анализа я составил дополнительные требования, которые выгодно выделили бы мою реализацию.
Забегая вперёд, отмечу, что встретил значительно меньше трудностей, чем ожидал.
Формулировка задачи
90% успеха — это правильная постановка задачи. После нескольких лет шаблонной работы было довольно сложно заставить себя чётко сформулировать задачу. Хотелось просто начать работать, а уже в процессе всё само собой бы прояснилось. Спустя час борьбы с прокрастинацией я, наконец, записал: создать библиотеку на PHP для импорта данных ФИАС.
Позже, войдя во вкус, я добавил несколько дополнительных требований:
У ФИАС есть официальный сайт, который даёт нам определение и цель создания системы
Федеральная информационная адресная система (ФИАС) — федеральная государственная информационная система, обеспечивающая формирование, ведение и использование государственного адресного реестра.
Целью создания ФИАС является формирование единого федерального ресурса, содержащего достоверную, единообразную, общедоступную, структурированную адресную информацию. Благодаря внедрению ФИАС эту информацию можно бесплатно получить через Интернет на официально зарегистрированном портале ФИАС.
Материалов с описанием вполне достаточно как на сайте ФИАС, так и на Хабре, поэтому не буду заострять на этом внимание.
Вкратце. ФИАС поставляется в двух форматах: ФИАС и КЛАДР. Второй устарел и выводится из использования. Информация хранится либо в DBF, либо в XML. Каждое изменение в составе ФИАС помечается новой версией. Можно запросить либо пакет с полными данными, актуальными на текущий момент, либо, содержащий только изменения между двумя версиями. Ссылки предоставляет SOAP сервис. Пакет представляет из себя RAR архив, содержащий файлы со специально сформированными названиями. Они состоят из префикса, имени набора данных и даты формирования. Есть два типа префиксов: AS_ для файлов, данные из которых нужно добавить в базу, и ASDEL для файлов, данные из которых следует удалить из базы.
ФИАС содержит следующие данные:
Структура данных описана в документе, который можно найти в разделе обновлений.
В конечном итоге мы имеем довольно простой и линейный алгоритм установки ФИАС:
И не менее простой алгоритм обновления:
ФИАС оставляет противоречивые впечатления. С одной стороны: полная автоматизация всего процесса, открытые форматы, хорошая документация. С другой: странное решение использовать проприетарный RAR для открытых данных; отличия документации от реальности (в основном это касается обязательности атрибутов), которые доставляют много небольших, но неприятных проблем; изредка приходят архивы, которые не удаётся распаковать в Linux; некоторые дельты между версиями занимают по 4-5 Гб.
Архитектура
В основе каждой библиотеки должна лежать базовая идея, стержень, вокруг которого будет наращиваться остальной функционал. Паттерн «цепочка обязанностей» показался мне лучшим выбором на роль такой идеи. Во-первых, он идеально подходит: несколько последовательных операций, которые сделал бы человек, если бы захотел установить ФИАС вручную, очевидны для разработчика и хорошо ложатся на небольшие написанные в SOLID стиле классы. Во-вторых, такая цепочка очень легко расширяется новыми операциями практически на любом этапе, что обеспечивает хорошую гибкость. В-третьих, давно хотел написать собственную реализацию.
В дополнение к операциям я создал несколько сервисов, которые можно передавать с помощью DI. Они позволяют переиспользовать код, легко подменить реализацию для низкоуровневых системных задач (загрузка файла, распаковка архива, запись в базу данных и других) и обеспечить хорошее покрытие тестами благодаря мокам.
Как итог, библиотека содержит четыре основных типа объектов, для каждого из которых чётко определена зона ответственности:
С помощью компоновки операций и сервисов, предоставляемых библиотекой, можно легко получить любую новую цепочку или дополнить существующую, используя только конфигурационные файлы.
Фреймворки
С большими перерывами и постоянным рефакторингом я работал над библиотекой в течении полутора лет.
Первая относительно стабильная версия была готова за два месяца работы по вечерам. Фактически она могла существовать отдельно от фреймворка и содержала всё необходимое: входной скрипт для запуска в консоли, DI контейнер, надстройку над PDO, собственный логгер и миграции структуры БД — чем я очень гордился.
Конечно же, коллеги её беспощадно забраковали.
Главным аргументом против стало отсутствие поддержки популярных фреймворков. Никто не хотел писать отдельную обёртку для библиотеки. Из-за этого я допустил самую дорогостоящую по времени ошибку: начал поддерживать как standalone версию, так и отдельные обёртки для каждого фреймворка. Реальные файлы ФИАС отличаются от того, что написано в документации. Каждый раз, когда нужно было убрать или добавить, например, not null в описание колонки, приходилось вносить изменения в три репозитория. Из-за утомительности процесса работа застопорилась ещё на полгода.
Ключевым моментом стали модели. Постоянно обновлять разнотипные наборы объектов в нескольких репозиториях не хотелось. В это же время на основной работе мне достался проект на Symfony. После беглого ознакомления с ним я решил, что наиболее полезная функция SF — это кодогенерация и именно она решит все мои проблемы. Я создал yaml файл в основном пакете, который содержит декларативное описание данных ФИАС. Затем я добавил кодогенераторы, которые на основе этого описания создают конкретные классы для моделей: сущности Doctrine для Symfony и объекты Eloquent для Laravel. Во время разработки генераторов я понял, что twig-шаблоны для этого не подходят, и остановился на специализированном решении — Nette PHP Generator.
В качестве proof of concept я создал бандлы для Laravel и Symfony. Поскольку со вторым я работал дольше, то всё последующее буду описывать в его контексте.
Инфраструктура
Большая часть моих боевых проектов была написана на устаревших технологиях, поэтому ни на одном из них я не мог применить современные анализаторы кода. Избавившись от гнёта legacy, я установил и настроил все инструменты контроля качества кода, какие смог:
Интегрировал проверки в Github с помощью Travis. В качестве финального штриха добавил Docker файл для создания локального окружения разработчика в комплекте с make файлом, который содержит основные команды для контейнера (запуск проверок, тестов, создание моделей и другие).
Итоги обучения
PHP 7
До начала работы над библиотекой я ни разу по-настоящему не использовал новые возможности PHP 7. Они прекрасны: от строгих типов до значительного роста производительности. Отдельное сердечное спасибо разработчикам за null coalescing operator. Такого серьёзного уменьшения кодовой базы после введения одного оператора я ещё не видел.
Удивительно, но в PECL нашёлся пакет для работы с RAR. Обычно такие расширения не вызывают доверия и я стараюсь их избегать. Это же оказалось подозрительно стабильным: без проблем установилось в 7.2, относительно быстро и с малым потреблением оперативной памяти смогло распаковывать огромные архивы (6 Гб распаковывается за 10-20 минут в зависимости от доступных ресурсов системы). До сих пор опасаюсь, что это некое проявление закона Мёрфи.
XmlReader
Прочитать гигантские xml файлы — нетривиальная задача. И снова на помощь пришло PECL расширение — XmlReader. Я далеко не сразу осознал всю его мощь, но в несколько подходов приспособил в связке с Symfony serializer для быстрого и экономного получения данных из файлов ФИАС. На стороне библиотеки объект для чтения реализует интерфейс итератора, который последовательно возвращает строки с xml, соответствующие одной записи в файле. С помощью Symfony serializer эти строки преобразовываются в объекты. 20 Гб файл читается за 3-4 минуты при этом используется не более 50 Мб оперативной памяти.
Запись в базу данных
Конечно же я начинал с ассоциативных массивов с данными и громоздкими описаниями таблиц. Код быстро превратился в мешанину из конфигов и классов-преобразователей.
Волшебство сущностей Doctrine показало насколько объекты могут быть самоописательными. Я решил использовать тот же подход, а заодно избавиться от собственной реализации записи данных в базу с помощью PDO. Взамен я создал интерфейс Storage, который описывает методы обработки объектов. На основании класса сущности конкретная реализация Storage решает как именно и куда записать данные. Такой подход позволил легко подключать самые разнообразные хранилища: от MySql до csv-файлов.
Оптимизация вставки данных
Первый импорт я прервал после того, как он перевалил за 48 часов. Стало очевидно, что нужно оптимизировать процесс вставки данных.
Сначала я перешёл на встроенные в PostgreSql колонки типа uuid для первичных ключей. Запись в uuid колонку с индексом значительно быстрее, чем запись в строку.
Следом я отказался от всех некритичных индексов и внешних ключей, поскольку забота о целостности данных полностью на стороне команды ФИАС.
Несмотря на эти изменения, время на импорт переваливало за 30 часов. Нужна была радикальная смена подхода.
Параллельные процессы
Интернет пестрит статьями про асинхронность в PHP. Мой выбор пал на Amp. Просто так взять и сделать асинхронно не получилось. Во-первых, код быстро превратился в ужасающую простыню коллбэков и неочевидных вызовов (вероятно, в этом виноват я, а не асинхронный подход). Во-вторых, пришлось отказаться от использования стандартных ORM потому, что нужны неблокирующие обращения к базе через специальный фреймворк. В-третьих, хоть и существуют условия, при которых PostgreSql сможет вставлять строки параллельно, их крайне сложно выполнить. В итоге после 5 часов работы я наблюдал, как все мои асинхронные запросы принудительно «синхронизировались» на стороне базы данных.
Зато импорт отлично разбивается на параллельные процессы: несколько абсолютно независимых задач, у которых нет общих ресурсов, за которые они могли конкурировать, и данных, которыми они могли обмениваться. Более того, в рамках одного потока я получал красивый и линейный код.
Первым я решил попробовать расширение Parallel. У него есть один фатальный недостаток — интерпретатор должен быть собран с поддержкой ZTS (Zend Thread Safety). Поскольку ZTS не работает в обычных web скриптах, пришлось бы иметь две разных версии интерпретатора. Одну, без ZTS, для web, вторую, с ZTS, для установки ФИАС. Потенциальный прирост производительности перевешивал это неудобство, особенно с учётом того, как легко собрать новый Docker контейнер и использовать его совместно со старым. К сожалению, запуск Symfony внутри нового потока вызывал переполнение стека PHP, а отказываться от DI контейнера и удобной конфигурации я был не готов.
Наконец, я нашёл Symfony process. Фактически он запускает новый процесс для указанной консольной команды и следит за его завершением. Пришлось добавить две дополнительные цепочки. Первая скачивает архив, распаковывает его и инициирует параллельные процессы для обработки данных. Вторая принимает список файлов из аргумента командной строки и записывает их содержимое в базу.
Из-за нехватки опыта работы с параллельными процессами я, похоже, совершил все ошибки новичка.
Например, мой инициирующий процесс проверял завершение дочерних с помощью бесконечного цикла и, конечно же, он тратил на это неприлично много ресурсов процессора. Помог вызов sleep между итерациями.
В первой реализации файлы по процессам распределялись неравномерно. Два самых крупных попадали в один поток, который обрабатывался более 20 часов. Во второй реализации я добавил специальный диспетчер, который распределяет файлы с учётом времени на их импорт. Теперь процессы нагружаются равномерно.
После этих правок я смог добиться импорта полной версии ФИАС за 16-20 часов в зависимости от ресурсов сервера. Не так хорошо, как хотелось бы, но я продолжаю работу над оптимизацией. На очереди полный отказ от PostgreSql в пользу Elasticsearch.
Выводы
Работу я всё же сменил. Во время тура по десятку собеседований я ответил на много каверзных вопросов только благодаря своему pet project.
Панические настроения в связи с тем, что PHP умирает, постоянно становятся сильнее. Не буду скрывать, что и сам подумывал о миграции на другой язык.
После того, как я увидел тот огромный труд, который команда PHP вложила в 7 версию; на личном примере убедился насколько взрослым стал язык и насколько богатой экосистемой он оброс; я смело могу заявить о том, что слухи о смерти PHP сильно преувеличены. И это только начало: в будущем нас ждёт JIT, асинхронность из коробки и многое другое.