понедельник, 1 октября 2018 г.

[prog.thoughts] Будет ли SObjectizer-6? И, если, то каким и когда?

Этот пост появился под влиянием комментария к одной из предыдущих заметок. Если кому-то интересно, что лично я думаю о перспективах возникновении принципиально новой версии SObjectizer-а, то милости прошу под кат. Для остальных вряд ли размышления на эту тему будут интересны, сорри.

Пришло время переделать SObjectizer?

Если оглядываться на историю собственно SObjectizer-а, то SObjectizer-4 появился в 2002-ом и активно развивался где-то до 2004-го года. До 2006 развитие продолжалось, но уже с меньшей скоростью. А к 2008-му стало понятно, что в рамках SO-4 оставаться уже нельзя. Т.е. от начала работ над SO-4 до момента, когда стало окончательно понятно, что нужно идти другим путем, прошло около шести лет.

SObjectizer-5 начал разрабатываться в середине 2010-го, в 2011-ом он уже активно использовался. В промежутке с 2013-го по 2014-й SO-5 претерпел множество внутренних переделок и в октябре 2014-го, как раз четыре года назад, появилась ветка 5.5, в рамках которой SObjectizer-5 развивается до сих пор. За это время SO-5, как мне думается, ушел далеко вперед, но при этом мы действовали с сильной оглядкой на обратную совместимость. И все эти четыре года проекты, использующие SO-5.5, можно было без особых усилий переводить с одной версии SO-5.5 на другую.

Т.е. с момента запуска SO-5 в эксплуатацию уже прошло более семи лет, при этом, на мой взгляд, потолок возможностей развития SO-5 еще не достигнут. Новые фичи, если идеи таковых возникают, все еще можно впихивать в SObjectizer-5. Более того, их все еще можно впихивать в ветку 5.5, продолжая придерживаться стабильности и хорошей совместимости. А совместимость, имхо, одно из ключевых требований к фреймворку, который претендует на использование в промышленной разработке.

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

Так что если в качестве мотивации для SObjectizer-6 рассматривать возможность отбросить груз совместимости и сделать обновленный SObjectizer, в котором фичи будут более согласованы и лучше увязаны между собой, то это, конечно, соблазнительно, но недостаточно.

Особенно с учетом того, что SObjectizer-5 сейчас не так "раскручен", как нам хотелось бы. Если бы у SO-5 были сотни внедрений по всему миру, шел поток новых хотелок и существенных претензий к существующей реализации, тогда можно было бы пойти на то, чтобы перевести SO-5 в режим maintenance-only и вложиться в разработку SO-6, понимая, что в какой-то части из внедрений на новый SObjectizer перейдут. И что SO-6 будет не мертворожденным проектом, а востребованным инструментом (пусть даже количество внедрений будет измеряться десятками).

Но сейчас, с эпизодическими случаями использования SO-5 "на стороне", уйти на полгода-год в разработку SO-6, чтобы затем опять активно вкладываться в пиар и продвижение... Как по мне, так это слишком рискованно.

Однако, есть и другая сторона этой проблемы.

Мир изменился. И роль C++ в мире

SO-5 мы начинали делать когда мир все-таки был другим и C++ в том мире играл гораздо большую роль, чем сейчас.

Ну, в частности, тот же язык Go был явлен миру еще в сыром виде в конце 2009-го, стабильная версия Go появилась в 2012-ом. Стабильная версия Rust-а -- в мае 2015-го. И это две сильно привлекательные технологии, которые непосредственно топчутся на поляне C++: т.е. эффективные нативные языки, не требующие таскать за собой JVM или .NET Framework.

Так же не забываем, что никуда не делась Java (Scala) + появились Ceylon и Kotlin. И, что важно, MS пошла на обеспечение реальной кроссплатформенности для .NET и сделала .NET Core.

Т.е. ландшафт разработки софта в очередной раз претерпел существенные изменения. Для C++, конечно, остались свои ниши, из которых его если кто и выдавит, то нескоро. Но вопрос в том, насколько SObjectizer-5 может применяться в этих нишах.

Почему это важно?

Дело в том, что SO-5 активно использует такие возможности C++, как динамическая память, RTTI и исключения. Кроме того, упор при разработке SObjectizer-а был сделан на то, чтобы обеспечить разработчику функциональность, гибкость, удобство, простоту и защиту от ошибок. Но ценой предсказуемости и эффективности механизмов диспетчеризации сообщений.

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

На мой сугубо субъективный взгляд, все это не является проблемой, если SO-5 используется в многопоточных GUI-приложениях.

Или в таком server-side, где удельные затраты на обмен данными между агентами при обработке запроса составляют мизерную часть от затрат на саму обработку запроса. Наш демо-проект Shrimp тому яркий пример: когда картинка обрабатывается пусть даже 10ms (что раз в 15-20 меньше, чем на самом деле), то это все равно на порядки(!) больше, чем стоимость обмена сообщениями между агентами.

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

Однако, если у вас стоит задача обрабатывать реально большие потоки событий (десятки и сотни миллионов сообщений в секунду), то SO-5 вам не подойдет. Так же вы не сможете использовать SO-5 в системах жесткого реального времени. Да и в системах мягкого реального времени, если у вас в проекте, скажем, под запретом RTTI и исключения.

Поиграем в оракула

Между тем, опять же на мой субъективный взгляд, C++ в ближайшем будущем будет хорошо себя чувствовать в следующих нишах:

  • древнее легаси. Которое, в основном, только сопровождается. Иногда и развивается, поскольку переиспользовать существующую кодовую базу дешевле, чем переписывать. Но в легаси-проекты вряд ли будут запихивать SObjectizer;
  • тяжелые вычислительные системы. Скажем, расчеты прогнозов погоды, распознавание образов, машинное обучение, вычислительные эксперименты и т.п. В общем, там, где C++ до сих пор борется с Fortran-ом и где реализации Модели Акторов, CSP, Publish-Subscribe и пр. вообще практически-то и не нужны. Зато нужны MPI, OpenMP и их конкуренты;
  • системы, от которых требуется высочайшая производительность. Например, высокочастотный трейдинг или телеком. Но тут вряд ли вообще будут использоваться универсальные фреймворки. Насколько я знаю, обычно речь идет о специализированных решениях, заточенных и под специфику задачи, и под конкретное оборудование и ОС;
  • системы, от которых требуется предсказуемость. Как по времени реакции, так и по потребляемым ресурсам. Например, системы реального времени и встраиваемое ПО (причем зачастую это одно и тоже).

К сожалению, остаются либо ниши, в которых SObjectizer не особо-то и нужен, либо ниши, в которых существующие принципы работы SObjectizer-а играют против SObjectizer-а.

Поэтому я думаю, что если и есть смысл создавать SObjectizer-6, то делать это нужно с прицелом на такие ниши, как системы реального времени и встраиваемое ПО (тем более, что уже давно в категорию "встраиваемого" попадают не только 8-битовые микроконтроллеры, но и многоядерные 64-х битовые платформы). А для этого нужно совершенно по другому подойти и к организации механизма обмена сообщениями (избежать работы с динамической памятью вообще или же дать разработчику полный контроль над этой работой). А так же озаботится тем, чтобы SObjectizer мог работать в условиях отсутствия RTTI и исключений.

Это кардинальная переделка SObjectizer-а.

И тут мы подходим к самому главному вопросу.

Кто будет оплачивать этот банкет?

Поскольку с 2013-го года SObjectizer-5 развивается исключительно за наш счет, то повторять этот "подвиг" с SObjectizer-6 мы точно не будем. Если кто-то согласится разделить эти расходы, т.е. если кто-то готов инвестировать в опытно-конструкторские работы вокруг SObjectzer-6, то у проекта появятся шансы на реализацию. Но только за свои деньги мы делать SO-6 не будем.

Опыт показывает, что разработка OpenSource за собственный счет не окупается. Расходы на развитие OpenSource инструментария нужно делить между теми, кто затем этот инструментарий будет использовать.

Цена вопроса

Для того, чтобы мы решили ввязаться в проектирование и разработку SObjectizer-6, нужно, минимум, $15K или ~1M RUR внешних инвестиций на 2019-й год. При условии, что SO-6 будет полностью открыт под BSD-подобной лицензией.

Для нашего, не самого дешевого правда, восточноевропейского рынка, это стоимость (стоимость, а не чистая ЗП) трех-четырех месяцев работы толкового C++ разработчика. Так что могу уверенно сказать, что если кто-то попробует сделать инструмент, подобный SObjectizer-у, собственными силами в качестве внутреннего проекта, то дешевле точно не будет. Скорее выйдет в разы дороже, т.к. тремя-четырьмя месяцами ограничиться не получится.

Почему речь идет про год?

Думаю, что не ошибусь, сказав, что в SObjectizer-5 было вложено порядка 3.5-4 человеколет. Т.е. если представить, что SO-5 разрабатывал один человек непрерывно работая над ним full-time, то ушло где-то около четырех лет его работы.

Соответственно, не стоит ожидать, что новый инструмент, хотя бы сравнимый с SO-5 по фичам, покрытию тестами и объему документации, появится за срок меньше года.

Я бы вообще исходил из следующего оптимистичного сценария:

  • первые два-три месяца -- это сбор и анализ требований, предварительная проработка основных принципов работы и первоначальных проектных решений. Самые первые грубые прототипы и варианты API (и то вряд ли);
  • следующие три-четыре месяца -- это уже нормальное прототипирование и формирование стабильного API для первой версии. На выходе должно быть понятно что и как должно работать, как этим можно будет пользоваться;
  • оставшаяся часть года -- это основная разработка, покрытие тестами, формирование базового комплекта документации. Возможно, вместе с опытной эксплуатацией первых альфа-версий с анализом результатов этой самой опытной эксплуатации.

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

Эти прикидки сделаны из предположения, что работа будет вестись силами одного-двух, максимум трех человек. Ну и, объективно, увеличение проектной команды может иметь смысл разве что на третьем этапе. На первых двух этапах даже команда из 4-5 человек может лишь удлинить сроки (если не вообще похоронить всю разработку), т.к. достигать консенсуса на этапе проектирования тем сложнее, чем больше народу в команде.

Вопрос не только в деньгах

Что еще очень важно, для такого проекта, как разработка кардинально новой версии SObjectizer-а, так это наличие пары-тройки заинтересованных в его применении компаний. Это нужно, чтобы делать не сферического коня в вакууме, а инструмент, нацеленный на практическое применение здесь и сейчас (ну пусть не сейчас, но не далее, чем завтра). Представители таких заинтересованных компаний, во-первых, нужны для сбора требований и обсуждения проектных решений. И, во-вторых, для обкатки выбранных решений и первых версий нового инструмента в максимально приближенным к реальности условиям.

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

Рисковость этой затеи

Поскольку здесь я пишу как инженер, а не PR-щик или прожженный бизнесмен, то вынужден подчеркнуть, что разработка SObjectizer-6 -- это опытно-конструкторская работа. Фактически, даже НИОКР, результат которого не гарантирован. Т.е. какой-то результат обязательно будет. Но это может быть как работающий инструмент, так и понимание того, что создать инструмент, удовлетворяющий требованиям, в текущих условиях невозможно.

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

Собственно, сам SObjectizer является тому подтверждением. Из более нового -- это RESTinio, в котором моего кода практически нет, но следы железной руки невеликодушного диктатора присутствуют ;)

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

Только ли C++?

Выше неявно предполагалось, что развитие SObjectizer-а возможно только в рамках языка C++.

Что не совсем соответствует действительности.

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

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

Rust

Язык Rust на данный момент, объективно, является единственной реальной альтернативой C++ в той же самой нише. Причем альтернативой модной и молодежной, еще не обремененной большим количеством качественного инструментария.

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

Минусов в этом направлении я лично вижу два:

Первый -- это наличие в Rust-е уже имеющегося акторного фреймворка Actix. Rust-сообщество пока не такое большое, чтобы переварить несколько акторных фреймворков. Тем более когда один стартует сильно позже другого и обречен на роль догоняющего.

Второй -- это перспективы самого Rust-а. Т.е. понятно, что Rust заставит потесниться C++. Но сколько места останется самому Rust-у?

Мы живем в мире, когда нормой становится массовое производство с использованием ориентированных на не сильно квалифицированную рабочую силу языков и технологий (вроде Go, Java и даже JavaScript). Имхо, Rust в этих условиях, не смотря на все свои достоинства, но из-за своего высокого порога входа, обречен оставаться нишевым языком. Как тот же C++.

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

C# и .NET Core

Могу ошибаться, но мне думается, что за счет .NET Core Microsoft может достичь большей популяризации C#. И вход в эту нишу с SObjectizer-ом может оказаться более выгодным, чем в какую-то другую. Поскольку, если мы говорим про управляемые языки, то кроме .NET-а у нас есть либо экосистема JVM, либо экосистема JavaScript. В мире JVM доминантой является Akka, плюс там есть ряд инструментов калибром поменьше. С миром JavaScript-а пересекаться в принципе не хочется, т.к. сам JavaScript и творения на нем есть надругательство над здравым смыслом :)

Как по мне, так C# более интересный и удобный язык, чем Java. Да и экосистема .NET Core в новых инструментах, думаю, нуждается больше, чем мир JVM.

Главные минусы: в сторону C# и .NET-а я не смотрел уже больше десяти лет. Ну и все-таки не очень понятно, каковы шансы у .NET Core против JVM.

D

Лично мне было бы интересно сделать инструмент на D и для D. Тем более, что это единственный достойный конкурент для Go: нативный, безопасный, со сборщиком мусора и без лишних зависимостей. Только в разы, если не на порядок более выразительный.

Но рынок разработки на D настолько узок, что, боюсь, вложения в разработку под D не окупятся вообще никогда.

Заключение

В общем, спасибо всем, кто дочитал. В сухом остатке:

  • я не вижу смысла начинать SObjectizer-6 только из-за того, что сложность наполнения SObjectizer-5 новыми фичами растет от релиза к релизу;
  • если SObjectizer-6 на C++ и делать, то ради переориентирования его на ниши ПО реального времени и встраиваемого ПО;
  • разработка SObjectizer-6 на данный момент возможна только при наличии внешнего софинансирования. Минимальный размер оного для начала предметного обсуждения такого проекта -- это порядка $15K или 1M RUR;
  • не обязательно SObjectizer-6 делать для C++, можно рассмотреть и такие варианты, как разработка SO-6 для Rust-а (опять же ориентация на ниши ПО реального времени и встраиваемого ПО) или для C# и .NET Core (тогда это просто будет универсальный "акторный" фреймворк).

Поскольку перспективы SO-6 на данный момент не ясны (я бы даже сказал призрачны), то в ближайшем обозримом будущем продолжится работа над SO-5.5 и его популяризацией. Если кому-то интересны планы именно по SO-5, то задавайте вопросы, постараюсь ответить.

Обязательный Discalimer

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

Это просто мое текущее мнение на счет того, при каких условиях я смог бы заняться такой темой, как SObjectizer-6. Мнение, возникшее не просто так, а на основании размышлений вокруг этой темы.

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

Комментариев нет: