понедельник, 25 января 2021 г.

[soft.business] Ищу финансирование для развития RESTinio/SObjectizer/so5extra

Наша совсем маленькая компания stiffstream на протяжении нескольких лет делает такие OpenSource инструменты для С++ как:

  • RESTinio: встраиваемый HTTP/WebSocket сервер, ориентированный на эффективную асинхронную обработку входящих HTTP-запросов;
  • SObjectizer/so5extra: реализация Actor Model, Publish-Subscribe и Communicating Sequential Processes, существенно упрощающая разработку сложных многопоточных приложений.

Прибыли эти разработки не приносят, мы вели их за свои деньги.

К сожалению, кризис 2020-го ударил и по нам. Наши собственные финансовые ресурсы для развития RESTinio и SObjectizer/so5extra практически исчерпаны.

Поэтому мы приостанавливаем работы над этими проектами на неопределенный срок.

UPD. На данный момент история с поиском финансирования закончилась ничем. Развитие наших OpenSource-проектов пока приостановлено. Мы попробуем поднакопить средства на заказной разработке/консультациях, чтобы затем вернуться к работам над RESTinio/SObjectizer/so5extra. Кому интересно, вот послесловие к этой затее.

Соответственно, те предложения, которые были первоначально описаны в этом посте, стали не актуальны. Я спрятал их под кат, сохранив просто для истории.

Если же кто-то на тех или иных условиях готов вложиться в разработку наших OpenSource-проектов, то контакты под катом внизу. Давайте пообщаемся, нам нужна не такая уж и большая сумма.

[prog.c++] Текущие хотелки по SObjectizer/so5extra

Две недели назад был пост о том, что хотелось бы поиметь в RESTinio. Попытаюсь сформулировать что-то подобное и в отношении SObjectizer+so5extra.

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

На данный момент я вижу два направления, в рамках которых можно произвести НИОКР и, если в сухом остатке получится приемлемый результат, перенести результаты исследований в SObjectizer.


Первое направление -- это попытка подружить агентов с pull-моделью извлечения новых заявок на обработку.

Суть в том, что сейчас агенты в SObjectizer-е работают в соответствии с push-моделью.

Это значит, что когда вы отсылаете сообщение в mbox, то обычный mbox запихивает заявку на обработку сообщения в очередь событий агента. Рано или поздно дело доходит до обработки этой заявки: диспетчер владеет очередью событий и именно диспетчер извлекает очередную заявку из этой очереди. При этом mbox, который сформировал заявку, не знает когда именно это произойдет.

Push-модель проста, понятна, эффективна и подходит для огромного количества случаев.

Однако бывают моменты, когда агенту выгоднее использовать pull-модель.

Первый сценарий, который можно закрыть посредством pull-модели -- это поддержка приоритетов для заявок (см. недавнюю статью на Habr-е на эту тему). Причем такая поддержка, которая бы позволила использовать приоритеты заявок совместно с базовыми штатными диспетчерами SObjectizer-а, которые изначально для этого вообще не предназначались (например, one_thread, active_obj, active_group, thread_pool, а также asio_thread_pool и asio_one_thread из so5extra).

Второй сценарий -- это еще одно возможное решение проблемы producer-consumer, которое давеча обсуждалось в issue на GitHub-е. Идея в том, что специализированный mbox собирает отосланные в него сообщения, но не сразу отсылает сообщения в очереди событий агентов, а хранит у себя до тех пор, пока какой-то из consumer-ов не освободится и не обратиться за следующим сообщением. В этом случае pull-модель выглядит предпочтительнее push-модели.

Третий сценарий -- это возможность агента читать сообщения напрямую из mchain-а как из обычного mbox-а. Дело в том, что mchain-ы задумывались как средство передачи информации от агентов наружу, в те части приложения, которые написаны без SObjectizer-а (в обратную сторону отлично работают старые-добрые mbox-ы). И в этом качестве они работают отлично. Но иногда их хочется использовать и для общения агентов между собой. А вот тут не все так хорошо, поскольку нет простого и эффективного способа проинформировать агента, заинтересованного в чтении сообщений из mchain-а, о том, что в mchain-е есть информация и можно вызывать receive.

Так что желание подружить агентов и mchain-ы у меня лично есть уже давно, а вот четких мыслей о том, как это сделать, пока не было. Возможно, эксперименты с pull-моделью помогут.

Четвертый сценарий -- это возможность сделать поддержку чего-то вроде selective receive (например, по аналогии с механизмом Stash из Akka). Правда, я не уверен, что это действительно реализуемо. Но, думается, что pull-модель предоставляет здесь несколько больше шансов на успех, нежели push-модель.

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


Второе направление -- это предоставление возможности пользователю создавать свои экземпляры рабочих нитей в штатных диспетчерах.

Тут дело вот в чем: штатные диспетчеры самостоятельно создают экземпляры std::thread когда им требуется очередная рабочая нить для обслуживания заявок агентов. Пользователь никак не может повлиять на то, что за экземпляр создается. Так же пользователь не имеет никакой возможности запустить какие-то действия на этой новой рабочей нити до того, как та начнет цикл обслуживания заявок для агентов.

Временами это не есть хорошо. Например, если пользователь хочет создать 100500 агентов, привязанных к active_obj-диспетчеру (т.е. работающих на собственных рабочих нитях), но при этом желает ограничить размер стека для каждой из рабочих нитей всего 32KiB. Работай пользователь напрямую с POSIX threads у него была бы такая возможность. А вот штатные диспетчеры не позволяют это сделать.

Другой сценарий: пользователь хочет поиграться с приоритетами рабочих нитей. Например, создать one_thread-диспетчер с высоким приоритетом рабочей нити. И thread_pool-диспетчер с низкоприоритетными рабочими нитями. Опять же, на чистом POSIX threads API это можно было бы сделать. А через штатные диспетчеры SO-5 -- нет.

Или, предположим, пользователь хочет привязать конкретную рабочую нить к конкретному ядру процессора. Опять же, посредством штатных диспетчеров SO-5 этого не сделать.

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

Нужно сказать, что диспетчеры asio_one_thread и asio_thread_pool из so5extra позволяют в свойствах диспетчера задать тип для рабочей нити. Так что эти два диспетчера позволяют пользователю реализовывать рабочие нити вручную со всеми нужными свойствами, тогда как основная внутренняя логика работы диспетчера остается на нашей (т.е. мейнтенеров SO-5) совести.

В общем, это направление выглядит гораздо более реалистичным и не требующим настолько большого объема предварительных исследований и прототипирования, нежели эксперименты с pull-моделью. Грубо говоря, можно брать и делать.


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

Так что если вы хотели бы видеть что-то в SObjectizer-е, что могло бы облегчить вам вашу работу, то скажите об этом нам. Например, через issues или discussions на GitHub-е.

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


Наверное, немного странно записывать хотелки когда вопрос о финансировании работ для наших OpenSource проектов еще не решен. И непонятно когда мы сможем вернуться к работе над RESTinio/SObjectizer.

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

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

[work.opensource.c++] arataga: что это вообще и зачем мы публикуем это в OpenSource?

arataga -- это работающий прототип socks5+http/1.1 прокси сервера, который мы в прошлом году разрабатывали для одного из наших клиентов. К сожалению, этот прототип остался невостребованным. Ну а чтобы не пропадать добру и самопиара ради, мы решили открыть его исходники.

Как все развивалось

Дело было так: с 2019-го года мы работали с заказчиком, который эксплуатировал у себя некий старый прокси-сервер. Весьма старый, написанный с применением модели thread-per-connection, да еще и оставшийся без сопровождения. Собственно, мы как раз и занимались его доработкой под нужды заказчика.

Где-то к концу весны 2020-го стало понятно, что больше ничего хорошего из этого прокси-сервера не выжать. Что нужно его заменять на что-то новое, написанное с нуля или же переделанное готовое (типа nginx или envoy после обработки напильником).

Изначально в этот проект влезать не хотелось вообще, т.к. объем работ предполагался большим, сроки короткими, поэтому наших ресурсов могло тупо не хватить. Но мы согласились помочь в написании ТЗ для будущих исполнителей и уже в процессе подготовки ТЗ сложилось ощущение, что здесь можно будет применить и SObjectizer, и RESTinio, и что при должном разбиении на итерации можно будет справиться и своими скромными силами. Посему ввязались в разработку нового прокси-сервера под требования заказчика.

В итоге в довольно сжатые (как мне кажется) сроки мы сделали прототип, который уже нужно было запускать на нормальное тестирование на площадке клиента... Но сам клиент утратил интерес к этой разработке и перестал реагировать на внешние раздражители.

Что стало неприятным сюрпризом, тем более, что до этого никаких проблем с заказчиком не было. И даже по ходу работ над arataga мы взаимодействовали по другим вопросам и он оплачивал нам сделанные ранее работы.

Наши обязательства перед клиентом закончились. У нас на руках остался arataga и с этим нужно было что-то делать. Например, выбросить и забыть. Или же открыть.

Зачем нужно было делать arataga?

У заказчика были следующие и, как мне представляется, местами весьма специфические условия: