суббота, 6 мая 2017 г.

[book.business] Интересная книга "Что не убило компанию LEGO, а сделало ее сильнее. Кирпичик за кирпичиком"

Закончил читать интересную книгу Билла Брина и Дэвида Робертсона "Что не убило компанию LEGO, а сделало ее сильнее. Кирпичик за кирпичиком". Книга о том, как компания LEGO достигла своего расцвета в середине 1990-х, затем затеяла целую волну инноваций, чуть не вылетела в трубу в начале 2000-х, но смогла перестроиться и пережить кризис.

Книга интересная, но читается достаточно тяжело. Мне с трудом дались первые страниц семьдесят. Ибо авторы выбрали достаточно специфический подход к изложению материала. Сначала они описали проблемы, с которыми LEGO столкнулась во второй половине 1990-х. Затем описали шаги для преодоления этих проблем, предпринятые руководством компании и перечислили достоинства и преимущества этих самых шагов. И вот тут у меня зачастую возникало ощущение, похоже на "что за фигня?", ибо здравый смысл подсказывал, что ничего хорошего не должно было произойти... А авторы пишут про положительные результаты... Не было понятно, то ли я идиот (что весьма вероятно), то ли авторы врут (во что не верилось), то ли нужно было набраться терпения и посмотреть, что будет дальше.

Как выяснилось, нужно было набраться терпения. Авторы сначала описали ожидаемые результаты преобразований и инноваций в LEGO на рубеже 2000-х. Именно ожидания. В которые лично мне не верилось. А потом авторы книги перешли к описанию того, что получилось на самом деле и в какой катастрофической ситуации LEGO оказалась в итоге всех этих инициатив. Вот тут-то все и встало на свои места.

По ходу чтения неоднократно возникало ощущение, что описываемое в книге очень сильно перекликается с тем, о чем говорится в замечательной книге "Живая компания". В частности, мне показалось, что предпринятые LEGO шаги по выходу из катастрофического пике в 2003-2004 годах, полностью соответствуют, как минимум, трем принципам, описанным Ари де Гиусом:

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

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

В общем, книга хорошая, интересная. Хотя читать "запоем" вряд ли получится, нужно будет приложить некоторые усилия. Но оно того стоит.

пятница, 5 мая 2017 г.

[prog.humour] Ну реально: "Why do all this RAII or GC shit, if you just can manage your runtime as a round robin?"

По наводке из G+ ленты Meeting C++ вышел на интересное на reddit-е:

Here is something that was described to me as a real production configuration that was done to solve memory leaking everywhere.

It was a Java service taking fairly high amount of traffic. In order to get consistent response times they setup this configuration in each machine:

1) Each machine runs 4 JVMs. 2) 1 JVM that is starting up 3) 1 JVM that is shutting down 4) 2 JVMs that are serving traffic. 5) Every 2 minutes a JVM starts/stops. 6) No JVM lives for more than 8 minutes.

I found that to be both horrifying and a rather clever way to work around the problem.

Т.е. рассказывают по некую систему на Java, которая должна была обрабатывать изрядный поток трафика. И для того, чтобы не бороться с утечками памяти люди просто сделали так, что у них одновременно работает четыре JVM: одна стартует, вторая завершается, две другие нормально работают и обслуживают трафик. Каждые 2 минуты одну из работающих JVM заглушают, а на ее место запускают новую JVM. В итоге ни одна из JVM не работает дольше 8 минут.

Был бы я лет на 10 помоложе, наверняка бы постебался на тему криворуких программистов в частности и атрофии головного мозга, которую вызывает использование Java вообще. Но количество набитых шишек все-таки дает о себе знать. Поэтому сейчас мне кажется, что это отличное инженерное решение. Ну что поделать, shit happens. А если можно построить железобетонное решение, которое работает не смотря на этот самый shit, то это просто здорово.

В связи с чем вспоминается две похожие истории.

Первая связана с патерном Disruptor, о котором много говорили в узких кругах несколько лет назад. Помнится, компания Lmax, которая Disruptor и описала, рассказывала, что у них JVM, внутри которой массированная обработка событий посредством патерна Disruptor и крутилась, просто-напросто раз в сутки перезапускалась. На сутки RAM для этой JVM хватало, а потом следовал простой "освежающий рестарт" и следовали очередные сутки работы нагруженного приложения.

Вторая история связана с одним из написанных на C++ проектов в компании Интервэйл. Там был родительский процесс диспетчер и N дочерних процессов. Каждый дочерний процесс выполнял запросы к удаленному серверу по HTTPS. Но время от времени, иногда после нескольких часов, иногда после нескольких дней непрерывной работы какой-нибудь из дочерних процессов тупо повисал. Непонятно почему. Просто зависал и все. Естественно, это обнаруживалось и процесс прибивался, но т.к. запрос не был выполнен, то это сказывалось на пользователе, чей запрос не обрабатывался. И хотя таких сбойных запросов оказывалось всего ничего, какие-то тысячные доли процента, но все равно неприятно.

Т.к. причину подвисаний нам найти не удалось (непонятно, на что нам было грешить -- на libcurl, openssl, CryptoPro или еще что), то мы просто сделали ограничение на время жизни дочерних процессов. Прожил больше нескольких часов -- будь добр, заверши свою работу, а мы вместо тебя запустим новый дочерний процесс. Поскольку такое принудительное умерщвление дочерних процессов приходилось на моменты, когда дочерний процесс запросы пользователей не обрабатывал, то получилось, что мы и от проблемы избавились, и запросы пользователей терять перестали.

PS. Пока писал, вспомнил еще одну историю. Совсем древнюю, относящуюся к временам, когда Ruby-On-Rails произвел эффект разорвавшейся бомбы. Помниться, читал какой-то блог пост, в котором автор описывал как они решали проблему обслуживания большого количества запросов в RoR-приложении. Способ был примитивный: на сервере запускалось несколько десятков серверов lighttpd и отдельный балансировщик разруливал нагрузку между ними. Но важно то, что RoR вместе с lighttpd не всегда работали устойчиво и иногда падали. Поэтому у них на серверах работал по крону специальный скрипт, который опрашивал инстансы lighttpd и, если обнаруживал отсутствие оного, то просто рестартовал упавший инстанс заново. Самая мякотка была в том, что рестарты происходили с темпом где-то раз в минуту. Т.е. раз в минуту какой-то инстанс RoR-приложения и lighttpd просто переставал работать. Ну, по крайней мере, я так запомнил :)

четверг, 4 мая 2017 г.

[prog.tale] Сегодняшнее. Hа тему "ну как жопой чувствовал..."

Функциональность новой версии SO-5 готова уже несколько недель как. Первоначально даже были планы сделать сегодня, 4-го мая, официальный релиз. Но где-то пониже спины было неприятное чувство, что этого делать не нужно. Во-первых, хотелось больше актуальной документации подготовить. Во-вторых, имело смысл дождаться окончания майских праздников, поскольку у изрядной части русскоязычной аудитории сейчас что-то вроде небольших каникул. В-третьих, было ощущение, что можно еще накидать каких-то тестов и примеров, которые бы позволили выявить какие-нибудь скрытые ошибки в новом функционале. Про такие ощущения еще говорят "жопой чую", уж простите мне мой французский.

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

В общем, с одной стороны, повезло. С другой -- интуиция не подвела, что не может не радовать :)

вторник, 2 мая 2017 г.

[prog.c++] Пример асинхронного однопоточного http-сервера на базе so-5.5, restinio и asio

Подготовка к релизу SO-5.5.19 вышла на финишную прямую. Есть надежда, что за неделю завершим подготовку документации и сопроводительных материалов, и после майских праздников выкатим официальный релиз. Пока же попробую на примитивном примере показать две основные фичи версии 5.5.19: способность SObjectizer-а работать только на одной рабочей нити и распространение мутабельных сообщений. Более того, в этом примере будет использоваться такой вариант SObjectizer Environment, который использует asio-шный event-loop в качестве бэк-энда. Подробнее обо всем этом ниже в посте.

Пример представляет из себя примитивнейший http-сервер, который при выполнении запроса к URL '/' генерирует простенькую html-страничку. Но генерирует с задержкой, которая постепенно увеличивается. При этом, не смотря на то, что обработка отдельного http-запроса "тормозит", http-сервер спокойно занимается приемом и обработкой параллельных запросов.

В качестве http-сервера используется наш restinio, который мы как раз и создавали для того, чтобы иметь возможность легко и непринужденно делать асинхронную обработку http-запросов. Так, благодаря архитектуре restinio мы имеем возможность делегировать обработку запроса SObjectizer-овскому агенту (хотя сам restinio к SObjectizer вообще не привязан и может использоваться отдельно). В примере задействована находящаяся в активной разработке версия restinio-0.2. В публичный ее репозиторий актуальные изменения мы пока еще не влили, вероятно сделаем это ближе к дате релиза SO-5.5.19.

Основная фишка данного примера в том, что в нем все работает на одной общей нити: и asio, и restinio, и SObjectizer. Т.е. SObjectizer не создает никакой дополнительной инфраструктуры, для диспетчеризации событий агентов и таймеров используется asio и евоный event-loop.

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

Итак, сначала подключаем необходимые заголовочные файлы:

воскресенье, 30 апреля 2017 г.

[life.cinema] Очередной кинообзор (2017/04)

Незаметно пролетел целый месяц и подошло время очередного кинообзора. В начале идут те фильмы, которые понравились больше. Затем те, что понравились меньше. Плюс отдельно несколько слов по фильму "Волынь", который нельзя включать в какую-то из категорий, он сам по себе.

Время первых (2017). К сожалению, не шедевр. Но очень хороший фильм.

Собачья жизнь (A Dog's Purpose, 2017). Милый, прямолинейный и сентиментальный фильм для семейного просмотра.

Грешники и праведники (Outlaws and Angels, 2016). Весьма суровый и атмосферный фильм. Жалко только, что несколько нудноват.

Человек с тысячью лиц (El hombre de las mil caras, 2016). Немного скучновато, но такое европейское кино лично мне нравится. Поэтому я посмотрел с удовольствием.

Сплит (Split, 2016). Если бы я в начале понимал, что это чистой воды фэнтези, то впечатление было бы другим. А так начинал смотреть как нормальный триллер, поэтому ближе к концу пришлось воскликнуть "ну чё за фигня?!!" Правда, разочарование чуть-чуть было компенсировано эпизодическим появлением Брюса Уиллиса в самом конце с отсылкой к "Неуязвимому" от 2000-го года. В общем, смотреть нужно как фантастику или фэнтези, в которой возможно все.

Призрак в доспехах (Ghost in the Shell, 2017). Перед просмотром этого фильма посмотрел оригинальным мультфильм от 1995-го года. Не могу сказать, что мне сильно понравилось что-то из этого. Как по мне, первые 3/4 нового фильма гораздо лучше старого мультфильма. Просто из-за более крутой визуальной составляющей. Но развязка в новом фильме -- это просто полный отстой.

Бессоная ночь (Sleepless, 2017). Вроде бы и актеров подтянули, и событий наворотили, но получилась какая-то невразумительная муть.

Ценный груз (Precious Cargo, 2016). Незамысловатое, чисто развлекательное кино.


Волынь (Wolyn, 2016). Фильм, в котором нельзя выделить какую-то выдающуюся актерскую игру или работу оператора, или какие-то тонкие сюжетные ходы, или еще что-то художественное. Тем не менее, сочетание очень простой и прямой формы подачи материала с звериной жестокостью происходящего на экране производит очень сильное впечатление. Не берусь сравнивать с советским "Иди и смотри", ибо смотрел последний ну очень давно и духу пересмотреть все равно не хватит. Но по силе воздействия на зрителя они должны быть сравнимы.