Над 40 дни от последния пост в блога ми. Ако сте си помислили, че ми се е случило нещо от голямо значение… правилно сте си помислили. Последните пет седмици бях в интензивен период касаещ Адския проект, който търкалям през последните две години. Това включва финалната права за завършване на всичко, истерия покрай deploy, дълга и приятна двуседмична почивка по празниците, пускане на версия 1.0.1 (по-точно 1.0.0.1) и онази досадна поддръжка в първите дни след release, изпълнена единствено със ситни подобрения. Понеже това бе „основният“ ми проект толкова време, той оказа голямо влияние както в професионалното ми развитие, така и в личния ми живот.
Ще ми се да споделя някои от нещата които научих от него. Ако не за друго, за да има къде да ги прочета след време. И ще ги разбия на няколко поста – така хем да не отегчавам малкото хора четящи този блог, хем ще се върна плавно към навика да пиша тук.
Работното име на проекта е Rebirth, монетизирано от бате Ани. За това деяние му бе обещана бутилка вино от клиента, която той така и не получи. Вероятно това бе причината да ни напусне и да отиде да покорява българските софтуерни върхове. Цялото нещо се започна да се търкаля февруари 2006та след една командировка в планините, неудачни опити за каране на сноуборд и ядене на бански старец.
Аз имах скромната роля на „team leader“ в цялата работа. Проектът беше изцяло в моите ръце от началото до края и с гордост мога да заявя, че успях да допусна всички класически грешки плюс няколко екзотични – и то повече от веднъж. На мое разположение е бил екип между един и седем человека с много вариращи умения. Преминахме през всевъзможни глупости, включващи драстични промени на технологиите по средата на проекта, няколко чисти пренаписвания на ключови компоненти, тотално неразбиране на спецификацията/проблемната област и цялостна промяна на клиентна. В резултат, след почти две години разполагам с една дебеличка база код с неприятен, но поносим процент излишни/остарели неща, която прелива 100 000 реда твърде подробно документиран Java код. И ако сега изтрия всичко и започна начисто, ще успея да пренапиша проекта с далеч по-добро качество за 2-3 месеца. Кофти тръпка.
Идеята
Понеже още не съм споменал – проектът представлява услуга за следене на новини в реално време. Един специален паяк ходи и събира стати от голям брой сайтове (към 8000 в момента) и ги категоризира в база данни. Възможно най-бързо се индексират от търсачка (search engine, не в смисъла на google). След някакво време (оптимистично 5 минути, песимистично – час) са намираеми чрез free text search. Допълнително, клиентите могат да дефинират комбинация фрази които ги интересуват (например „бойко борисов“) заедно с подбор от сайтове (български новинарски сайтове) и да получават редовно новини, които отговарят на тези критерии. Нещо като онова с изрезките от вестници, но автоматизирано, дигитално и доволно скъпо.
Началото
Проекта бе разбит на две части – търсачката, работа на нашите шведски клиенти и всичко останало – база данни, уеб сайт, редица дребни системи и сателитни приложения – които бяха наша работа. Започнахме с блага, макар и наивна техническа визия – Struts с Velocity и EJB 3.0 (тогава още бета). Помъчихме се около месец, след което към април 2006 ми дотегна да променям 7(!) файла за да добавя поле във форма и реших да сменя web framework-а. Кратко, но усърдно търсене, спря погледът ми на Wicket, който тогава още беше версия 1.1 и дори не мечтаеше да се присъедини към Apache.
Wicket и JBoss EJB изглеждаха стабилна комбинация и позволяваха да са работи сравнително ефективно. През следващите месеци нахвърляхме стабилна част от хавата – технологиите позволяваха продуктивен цикъл и можехме бързо (за флегматичния свят на Java) да изграждаме функционалност. Въпреки че работехме с изцяло алфа продукти (EJB public draft 1, Wicket 1.2-SNAPSHOT от SVN trunk-а) се справяхме прилично с непознатото. Единствената тесла бяха unit тестовете – за да ги подкараме трябваха немислими магии с Apache Cactus, наш си Maven 2 плъгин и чакане повече от две минути за изпълнението им. Стартирането на приложението (application server и всичко останало) отнемаше към 1:20 мин. А Eclipse издъхваше отвсякъде (макар че имало решение). Това доведе до логична развръзка – поредния смел ход. Реших да минем на Spring и Tomcat.
Въпреки че вече бяхме с 40 000 реда код, миграцията отне по-малко от седмица. EJB 3.0 и нашата интерпретация на Spring бяха много сходни и единствената болка бе адаптацията на тестовете. Като страничен ефект се оформи един ситен проект с отворен код, вдъхновен от rails и fixture-ите му (някой ден трябва да му придам по-публична форма). В резултат тестовете минаваха за 20 сек., а приложението се стартираше за 11 сек. Огромен бонус за нашата продуктивност
Праймтайм
Така продължихме до октомври. През това време, разбира се, бяхме пренаписали ключовите части от уеба поне по два пъти. Колегите много ми се дразнеха на ентусиазма, с който изхвърлях големи порции мъчително написан код, желайки ги пренапиша по-чисто и по-стабилно. Дойде и време за release, но имахме проблем – търсачката още не бе готова. През цялото време работехме със собствен mock-up и макар да имаше чиста абстракция, не бяхме помирисвали истинския search engine. Най-накрая получихме нещо частично работещо три седмици преди да излезем в продукция. Един колега се зае да го интегрира. После последва командировка до Швеция, където с друг колега довършвахме интеграцията и оправяхме редица дребни неща. Беше една седмица от 15-часови работни дни в чужда държава. От Стокхолм видяхме единствено пътя между хотела и офиса, който макар да бе сред най-зрелищните места, далеч не задоволяваше любопитството ни. В крайна сметка, успяхме да интегрираме търсачката и да оправим редицата, но не бяхме готови за release. Ако сред нас имаше някой с поне малко мозък, това развитие щеше да му е очевидно доста по-рано.
Вече не си спомням защо падна мотането от октомври 2006 до януари 2007 – но то беше от класа. Струва ми се, че хем търсачката не бе напълно готова, хем нямаше достатъчно хардуер, хем имаше още куп промени и една възпълна bugzilla. А в личен план това бе много странен момент – изживявах меланхоличен етап от живота си и нямах никаква енергия да бутам проекта напред. От което работата ми силно пострада.
Rebirth: Презареждане
Като мое оправдание дойде едно сериозно раздвижване от „шведска страна“, което резултира във втора командировка до Стокхолм. Новините бяха притеснителни – голяма компания е купила клиентската фирма и е променила почти целия състав. Човекът с визията си бе заминал – заменен с нов човек и нова визия. Тръгнали си бяха и двамата програмисти, създали търсачката – в резултат трябваше да преминем към нова и да работим с напълно непознати. А както разбрах и няколко седмици по-късно – изцяло да преработим уеба, понеже новия product management намираше стария уеб сайт тотално непотребен на клиентите.
В този момент проекта започна да става силно неприятен. Още от ноември 2006 нещата бяха започнали да стават скучни, а занапред не се очертаваше нищо интересно. Възполвах се от момента да мина на Wicket 1.3-SNAPSHOT от SVN trunk (вече Apache Wicket), но отвъд това нямаше нищо забавно. Екипа бе сериозно намален (трима човека, всички с добро ниво) и паралено работехме над друг проект. Работехме с много бавни темпове въпреки доброто технологично познание. Не съм много сигурен за причината – от една страна на всички ни беше дотегнало от до болка познатите неща в Java и това не ни даваше много стимул за работа. От друга, аз вече навлизах в много дълбоки емоционални води, които сериозно ми пречеха да се фокусирам. Въобще не се справях с ръководната си роля и това съвсем обричаше Rebirth на провал.
Това положение продължи до септември тази година. В личен план за мен тези месеци бяха отвратителни. Не направих никакъв прогрес професионално, бях много по-нестабилен, по-избухлив и като цяло не бе красива гледка. Още се чудя как успях да завържа няколко добри приятелства през това време. Единственото хубаво нещо което ми се случи беше курсът по Python, към който още храня невероятно топли спомени. Но въпреки личните ми драми, наесен някак успяхме да придвижим проекта напред и да заковем функционалността на новата уеб част плюс интеграцията с новата търсачка.
Праймтайм, отново
После се случи нещо канонично за този проект – открихме, седмици преди планираният release, че решението с новата търсачка нямаше да ни свърши работа. Архитектурата просто не минаваше и трябваше да се направи нещо по въпроса. Вместо един монолитен индекс трябваше да разбием голямата база от статии (80 000 000 документа) на четири части и да въведем сложен режим на ежедневно генериране на нови индекси. Добавете към това, че старата база данни трябваше да се мигрира към съвсем нова схема и нов енджин (от Postgres към MySQL) и вече беше ясно, че щеше да коства още около два месеца.
И двата процеса се развиха относително зле. Някой се бе отнесъл крайно идиотски към миграцията на 80 милиона документа и в резултат тя отне към 500 часа – три седмици календарно време, през което просто чакахме MySQL да глътне всичко. И когато това време най-накрая изтече ни чакаше поредната приятна изненада – голяма част от документите бяха сериозно развалени и трите седмици бяха загубени.
След малко мисловен процес и методичност успяхме да повторим процедурата, този път за по-малко от три дена. След много проби и грешки бе направено и по-добро решение с търсачката. Оправихме поредната редица дребни неща, настроихме това-онова и късната вечер на 18 декември хвърлих .jar файла в /webapps
, стартирах „томкотката„, скръстих пръсти и насочих стария домейн към новия сървър.
В продукция, най-сетне
19 декември бе странен ден. Приложението окупиращо работния ми ден най-накрая беше излязло на пазара. Трудно бе за вярване, тъй като Rebirth с право си извоювал титлата „never-ending project“. Но краят бе дошъл.
Струва си да отбележа няколко неща.
Първо, бях много приятно изненадан колко добре се държеше проекта. Повечето колеги бяха много скептични както към подбраните технологии, така и към големи части от кода. Аз също имах съмнения дали ще му стигне паметта, дали ще се справи с натоварването, дали няма да е твърде бавен и въобще дали ще става за нещо. Но паметта му стигаше, хардуера бе натоварен под 20%, работеше прилично бързо и всички бяха много щастливи. Въпреки огромното забавяне, проекта бе обявен за голям успех. Още повече, за последния месец не ми се наложи да го рестартирам нито веднъж и не се появи нито един бъг, който не бях способен да отстраня за по-малко от 15 минути. Въпреки количеството код, няколко излишно сложни абстракции и много „боклук“, системата бе изрядна.
Второ, все още не мога да повярвам колко малко разбирах от бизнес модела и маркетинга на продукта. Бяхме инвестирали твърде много време в малко използвани или маловажни компоненти. Продаваемите (и скъпи) части бяха претупани. А бях толкова уверен, че добре разбирам какво правя.
И трето, не мога да опиша колко добре се чувствам. Всякаш от гърба ми се е смъкнал огромен товар – бирата отново има добър вкус и жените отново са привлекателни. Не осъзнавах до каква степен неуспеха и статуквото в професионалния ми живот се отразяваха на личния. Последните месеци имаше цели седмици, през които не съумявах да напиша нищо ползотворно. Вместо това си клатех краката и цъках хаотично из нета по цял ден. Продуктивността бе почти нулева. Сега отново работя с огромен мерак, справям се бързо и ефективно със задачите и изпитвам огромно удовлетворение от кадърно свършена работа. Накратко, живота отново е хубав.
Развръзка и епилог
Това бяха две години, които няма да забравя. Научих много неща за занаята, за живота, за офисната култура, за това как се печелят пари и за какво ли още не. Силно съм благодарен на всички хора, които бяха замесени – тези с които още се разбирам чудесно, тези с които за нещастие злобно се скарахме и дори тези, които не мога да понасям. Беше емоционално.
Този пост прехвърли 12 печатни страници, така че спирам дотук. Живот и здраве, ще пусна още няколко свързани с този проект – надявам се по-кратки. Има доста неща, за които трябва да се правят равносметки.
Чудесен текст, благодаря 🙂 Поздравления от мен 🙂
Честито, Аква. Разбирам какво ти е било, макар че при мен нещата са от по-малък калибър. Но да влачиш нещо 2-3 години винаги е кофти 😉
Браво, Стефчо 🙂 Радвам се, че най-накрая сте го завършили този проект.. Наистина беше заприличал на never-ending проект.
А винцето можете и да не ми го опаковате в нещо кой знае какво 😀
Напоследък съм в настроение да търся проблемите на софтуерната индустрия (и на свинщинките, които аз творя) в нетехнически причини – постановка, комуникация с клиента, как проекта се намира в цялостната бизнес история…
В поста си описал техническите части на развитието му. Да смениш платформите – иди/дойди, сигурно е оправдано. Човешките май са довели до повече трудности? Замисли се и за твоята роля, опитай се да потърсиш какво е могло да не се случи другояче…
Иначе – 100к код звучи гадно. Не мисля, че трябва да е толкова, макар, че не познавам джавата и това, което сте ползвали. Не знам няколкото прасета, които имам колко са, но със сигурност са по-малко. Мога да компенсирам с това, че кода не е мой. Последното нещо, което трябвше да поддържам активно и постоянно беше към 12, пренаписах го до около 3-4. Дребна риба.
Иначе – опит на чужд гръб – е това е най-важното ;).
Ми проблемите определено бяха човешки, а не технически. Трудни технически проблеми, според мен, имаше доста малко. Виж, обаче, взаимоотношенията между хората пораждаха доста.
Впрочем, мисля един от следващите постове да е именно какво ме подтикна да сменя технологиите, как го направих и къде ударих на камък. Донякъде е свързано и с 100к код – в един момент ми хрумна с хитра и пестелива нотация да специфицираме какви са ефектите на всички service методи от service layer-а (който не беше толкова голям). В резултат, много от тези редове са коментари, които едва ли някой чете…