понедельник, 29 июля 2013 г.

[prog.flame] Куски из чужой презентации о старом коде, причинах...

...доведения его до такого состояния и последствиях.

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

Итак, в 2007-м году была сделана некоторая система по обслуживанию запросов пользователей. К 2012 году система перестала справляться с возросшей нагрузкой. Почему и как это произошло автор презентации говорит прямо и откровенно. Этому посвящен специальный раздел презентации "Why good code goes bad".

Основные пункты (в скобках мой перевод):

Premise: people don't suck (Предпосылка: разработчики нормальные)

Premise: code was once beautiful (Предпосылка: изначально код был хорошим)

code tends towards complexity (gets worse) (код имеет тенденцию усложняться (т.е. становиться хуже))

environment changes (изменяется среда)

scale changes (изменяется нагрузка)

Факторы, которые обуславливают усложнение кода:

without regular love, code grows warts over time (если с кодом не трахаться постоянно не уделять коду постоянного внимания, то со временем он покрывается бородавками)

localized fixes and additions are easy & quick, but globally crappy (локальные исправления и дополнения делаются легко и быстро, но в общем все становится только хуже)

features, hacks and workarounds added without docs or tests (фичи, хаки и воркэраунды добавляются без их документирования или покрытия тестами)

maintainers come & go, (занимающиеся сопровождением разработчики приходят и уходят)

... or just go. (или же просто уходят)

Факторы, которые обуславливают изменение среды, в которой работает система:

infrastructure (hardware & software), like anybody's, is always changing (инфраструктура (железо и софт), как и везде, постоянно изменяется)

properties of networks, storage (изменяются свойства как сетевых, так и подсистем хранения данных)

design assumptions no longer make sense (исходные проектные решения сейчас уже не имеют смысла)

scale changes (design for 10x growth, rethink at 100x) (изменилась нагрузка (проектировали для 10-кратного роста, приходится иметь дело со 100-кратным))

new internal services (beta or non-existent then, dependable now) (появление новых внутренних сервисов, которых не было тогда, на которые приходится опираться сейчас)

once-modern home-grown invented wheels might now look archaic (когда-то самостоятельно переизобретенное колесо казалось очень современным, сейчас же выглядит старьем)

Почему система перестала нормально работать:

code was too complicated (код стал слишком уж сложным)

future maintainers slowly violated unwritten rules (приходящие на сопровождение разработчику потихоньку нарушают неписанные правила и соглашения)

or knowingly violated them, assuming it couldn't be too bad? (или же делают это сознательно, предполагая, что ничего плохого не случится)

single-threaded event-based callback spaghetti (спаггети из событийных коллбэков в однопоточном коде)

hard to know when/where code was running, or what "blocking" meant (из-за чего сложно понять какой и где код работает или что означает "блокирует")

Ну и выдержки из финального заключения о том, во что превратился код через пять лет (с 2007 до 2012):

incomplete docs, tests (неполная документация и наборы тестов)

stalling event loop (медленный и дырявый цикл обработки событий)

ad-hoc threads... (бездумное использование потоков)

... stalling event loops (останавливающийся цикл обработки событий)

... races (гонки)

... crashes (падения)

copy/paste code (копипащенный код)

... incomplete code (недоделанный код)

Ну а теперь читатель может сделать предположения о том, на каком языке была первоначально разработана эта система. И идет ли речь вообще о языке программирования, когда перечисляются эти факторы и причины доведения работающей системы до подобного состояния. А так же о том, есть ли вообще язык программирования, который бы от всего перечисленного защищал? Под катом же ссылки и подробности.


Выше были процитированны фрагменты презентации "dl.google.com: Powered by Go". Она рассказывает о том, как сервис dl.google.com обслуживался написанной в 2007-м году на C++ системой, которая в 2012 перестала справляться с нагрузкой и была заменена на новую, написанную на языке Go.

На мой взгляд, у разработчиков новой версии dl.google.com не было шансов на неудачу. Как я понимаю, исходная система была небольшой (в презентации сказано, что в результате перехода на новую версию было выброшено 39 файлов с кодом объемом в 15K строк). Исходная система показала, как делать не нужно. Новая команда пользовалась новым языком, который, подозреваю, им нравился и который они использовали с удовольствием.

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

Исходная проблема со старой реализацией dl.google.com, на мой взгляд, вовсе не в C++. А в том, что было допущено доведение работающей системы до такого состояния. Вопрос о ее переписывании (частичном или с нуля) нужно было ставить гораздо раньше. Вообще, по своему опыту работы в Интервэйле, где я долго отвечал за нагруженную систему, подход "один раз написали и забыли" не работает. Если приложение оказывается в условиях изменяющейся среды и/или нагрузок, то этим приложением нужно постоянно заниматься (в том числе и регулярно трахаться со старым кодом). Правда, такие вещи не очень-то понимает высокое начальство: как так, система давно написана и введена в эксплуатацию, но на ней продолжают сидеть опытные разработчики, когда как для текущих горящих заказов не хватает ресурсов... Впрочем, это уже совсем другая история.

Но все-таки вернусь к C++. Объективно, привести C++ный код к несопровождаемому состоянию намного проще, чем на многих других языках. Я убежден, что для нормальной разработки и развития C++ кода нужна небольшая, но профессиональная команда, с невысоким темпом ротации людей в ней (разработчики редко уходят, редко приходят). Имхо, это главное условие. Его выполнение приведет к тому, что код будет нормальный, он не будет "загнивать" со временем, будет сопровождаться тестами и документацией. Поскольку все это зависит вовсе не от языка, а от разработчиков.

Кроме того, со временем, не смотря на усложнение, C++ становится лучше и все более приспособленным для разработки очень больших и надежных программ. В первую очередь за счет тех фич, которые зачастую стараются ограничить или даже запретить различными корпоративными стандартами. Это шаблоны и исключения. Я начинал программировать на плюсах в далеком 92-м, когда имевшиеся в моем распоряжении компиляторы не поддерживали ни того, ни другого. А потом еще лет десять приходилось приспосабливаться к различным средам, где были те или иные проблемы с реализацией либо шаблонов, либо исключений, либо STL отсутствовала напрочь. На себе довелось прочувствовать, насколько проще становится работа на C++, когда у тебя все это есть. И тем более дико наблюдать, как в том же Google применение исключений находится под запретом. Даже приведенные в обсуждающейся здесь презентации фрагменты C++ного кода наводят на мысль, что будь они написаны с исключениями и с прицелом на exception safety, то были бы они и компактнее и надежнее.

Ну а в завершении напомню очень важную программерскую мудрость, которую, к сожалению, молодые разработчики могли даже и не слышать: программу на Фортране можно написать на любом языке программирования ;)

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

Отправить комментарий