LINUX.ORG.RU

Обновился инструмент для работы с агентами в C++: SObjectizer 5.5.0

 , , ,


4

1

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

Последние несколько лет SObjectizer развивается на SourceForge как OpenSource проект под BSD-лицензией. Подробнее об истории, текущем состоянии и направлении движения SObjectizer можно прочитать здесь.

Версия 5.5.0 является результатом очередного, очень значимого этапа развития проекта.

Главное отличие v.5.5.0 от предыдущих версий — это отсутствие зависимости от ACE Framework. Т.е. теперь ACE в коде ядра SObjectizer не используется вообще, для SObjectizer достаточно наличия стандартной библиотеки C++11. Это означает, что SObjectizer уменьшился в размере, нужно меньше времени на сборку SObjectizer-проектов, упрощается поддержка различных компиляторов и платформ. В частности, эта версия SObjectizer тестировалась посредством MSVS2013 (Windows), GCC 4.8/4.9 (Windows, Linux), Clang 3.5.0 (Linux).

Из более мелких изменений можно отметить прямую поддержку std::chrono при работе с отложенными/периодическими сообщениями, а так же небольшое изменение названий некоторых классов/функций (с сохранением старых имен для обеспечения совместимости). Более подробная информация о нововведениях в v.5.5.0 доступна в соответствующем разделе Wiki проекта. Так же увеличилось количество страниц с описаниями базовых вещей SObjectizer.

Версия 5.5.0 может быть загружена из раздела Files или получена из Subversion-репозитория.

Примечание. Этот релиз содержит только ядро SObjectizer (т.е. проект so_5). Никакие другие подпроекты (вроде so_log или so_sysconf) в релиз не включены. Возможно, сборка SObjectizer Assembly со всеми подпроектами будет сформирована и опубликована позже (если она действительно кому-то потребуется).

PS. Анонс делается просто для того, чтобы уведомить, что такой проект есть, живет, развивается. Доступен под BSD-лицензий, т.е. даром, в том числе и для коммерческих проектов. Это не просьба сделать code review. И не попытка кому-то что-то «продать».

PPS. Специально для желающих постебаться над синтаксисом и посравнивать программирование на C++ с Perl-ом. Вот классический пример Hello, World. В традиционном, ООП-шном варианте, с созданием класса агента и переопределением виртуальных методов (хотя есть и более модерновый вариант, с использованием С++ных лямбда-функций):

#include <iostream>

// Main SObjectizer header files.
#include <so_5/all.hpp>

// Definition of an agent for SObjectizer.
class a_hello_t : public so_5::rt::agent_t
{
	public:
		a_hello_t( so_5::rt::environment_t & env )
			: so_5::rt::agent_t( env )
		{}

		// A reaction to start of work in SObjectizer.
		virtual void
		so_evt_start() override
		{
			std::cout << "Hello, world! This is SObjectizer v.5."
				<< std::endl;

			// Shutting down SObjectizer.
			so_environment().stop();
		}

		// A reaction to finish of work in SObjectizer.
		virtual void
		so_evt_finish() override
		{
			std::cout << "Bye! This was SObjectizer v.5."
				<< std::endl;
		}
};

int
main( int, char ** )
{
	try
	{
		// Starting SObjectizer.
		so_5::launch(
			// A function for SO Environment initialization.
			[]( so_5::rt::environment_t & env )
			{
				// Creating and registering single agent as a cooperation.
				env.register_agent_as_coop( "coop", new a_hello_t( env ) );
			} );
	}
	catch( const std::exception & ex )
	{
		std::cerr << "Error: " << ex.what() << std::endl;
		return 1;
	}

	return 0;
}

PPPS. Специально для желающих узнать, чем SObjectizer лучше libcppa/CAF. В двух словах — это две совершенно разные разработки, ставящие перед собой разные цели и достигающие их разными способами. Подробнее здесь и здесь.

★★★★★

Последнее исправление: beastie (всего исправлений: 2)
Ответ на: комментарий от staseg

Вот набросок: http://pastebin.com/ccDk2wKG Там псевдокод для функции event-loop-а, внутри которой для каждого нового подключения создается новый агент, а при обнаружении закрытия подключения агенту дается команда на уничтожение.

А так же наброски двух агентов — парсера потока и зипователя данных.

Кода для записи данных в выходной поток нет, т.к. это еще какой-то event-loop, который вряд ли будет реализован каким-то агентом, скорее будет задействован механизм соответствующей библиотеки.

Вообще, данный пример сейчас как бы не ко времени, т.к. в процессе отказа от использования ACE я буду пересматривать способы работы с внешним миром в SO5. И как именно они будут выглядеть станет понятно через три-четыре недели, в процессе работы над демо-проектом для SO-5.5. Поэтому пример выглядит так, как выглядит.

В комментариях я постарался отметить основные моменты. Если будут какие-то вопросы или непонятки, я постараюсь ответить.

eao197 ★★★★★
() автор топика
Ответ на: комментарий от eao197

реализация сопрограмм/файберов/зеленых нитей

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

таким образом, мы установили, что ты тролль (см выше), лжец (см здесь) и, предположительно, девственник.

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

anonymous
()
Ответ на: комментарий от anonymous

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

ващет он как раз и говорил, что это нифига не «сопрограмм/файберов/зеленых нитей». Это как раз и есть функтор с состоянием. хз что ты там подумал, но по твоим тут орам понятно, что ты явно не понял о чем речь. и да, тут уже предложили обмазаться ссылками на свои «9000 примеров» или сделать вдоль. Почему ты еще не «поставил мелкоту на место» и не дал ссылки на свой код, чтоб все узрели и поняли, что «сынку мы перед тобой»?

anonymous
()
Ответ на: комментарий от anonymous

функтор с состоянием

на кой может понадобиться функтор без состояния? навелосипедить подобие функции первого порядка?

Почему ты еще не «поставил мелкоту на место»

не считаю необходимым.

anonymous
()
Ответ на: комментарий от anonymous

Это как раз и есть функтор с состоянием.

приблизительно так я и охарактеризовал поделие из оп-поста: подобие stl-алгоритмов с несколькими функторами (впрочем, можно и одним проэмулировать).

anonymous
()
Ответ на: комментарий от anonymous

тада я ваще хз о чем вы тут спорите ... пятница же.

anonymous
()
Ответ на: комментарий от anonymous

называй вещи своими именами: ниасилил.

Ануткать, проходим вперед, не стесняемся, показываем как нужно.

eao197 ★★★★★
() автор топика
Ответ на: комментарий от anonymous

где множественные точки входа и выхода?

Э... О чем, собственно, речь? Пример в псевдокоде можете показать?

eao197 ★★★★★
() автор топика
Ответ на: комментарий от anonymous

таким образом, мы установили, что ты тролль (см выше), лжец (см здесь) и, предположительно, девственник.

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

Ох не спроста вы под анонимусом здесь, ох не спроста. Какой конфуз бы вышел, если бы вашу реальную личность удалось бы вычислить.

eao197 ★★★★★
() автор топика
Ответ на: комментарий от anonymous

хоспаде, шо за говнокод? совсем упоролся?

Добавляем сюда еще и проверку аргументов, обработку кодов возвратов, обеспечение exception safety, сбор мониторинговой информации, настраиваемое логирование... За за*бетесь писать слово «говнокод»?

Вы вообще к реальному программированию имеете отношение? Или на работе только перечитываете CSP и пишете кляузы на работающих коллег дабы заполучить лычки тимлида на еще одном проекте?

eao197 ★★★★★
() автор топика
Ответ на: комментарий от eao197

Добавляем сюда еще

сначала исправь детские ошибки. неудивительно, что ты пилишь это поделие уже 20 лет: «с листа» писать ты вообще не умеешь.

anonymous
()
Ответ на: комментарий от eao197

Вы вообще к реальному программированию имеете отношение?

ты — не имеешь. что подтвердил своим «примером».

ps капча anectodes xudina как бы намекает

anonymous
()
Ответ на: комментарий от anonymous

сначала исправь детские ошибки.

Например?

ты не ответил на мой вопрос.

Какой именно?

eao197 ★★★★★
() автор топика
Ответ на: комментарий от eao197

Например?

будем читать сверху вниз. строка 9.

Какой именно?

я спрашивал о цели этого наброса. ты пытаешься дискредитировать си++?

anonymous
()
Ответ на: комментарий от anonymous

будем читать сверху вниз. строка 9.

Если вы о том, что channels по ошибке был продекларирован как автоматическая переменная, то это из области того, что при желании можно и к столбу приколупаться. Там вообще код некомпилябильный и сама функция event_loop будет выглядеть сильно по-разному, в зависимости от фреймворка. Например, если вместо libuv взять ACE, то не будет функции event_loop-а, а будет ACE_Event_Handler, в котором env и channels будут атрибутами класса.

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

я спрашивал о цели этого наброса.

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

PS. Анонс делается просто для того, чтобы уведомить, что такой проект есть, живет, развивается. Доступен под BSD-лицензий, т.е. даром, в том числе и для коммерческих проектов. Это не просьба сделать code review. И не попытка кому-то что-то «продать».

Что не понятно?

ты пытаешься дискредитировать си++?

Походу, вы совершенно не представляете, насколько разным бывает C++ в совершенно разных прикладных областях и коллективах. Что неудивительно, т.к. вы признаете только свою точку зрения, а несогласных выживаете посредством докладных записок руководству.

eao197 ★★★★★
() автор топика
Ответ на: комментарий от eao197

при желании можно и к столбу приколупаться.

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

заставляют соискателей писать на собеседованиях

предлагаешь послушать в этом вопросе твоё мнение?

прочитать стартовое сообщение

это и есть наброс. я пытаюсь разобраться в истинных его целях.

насколько разным бывает C++ в совершенно разных прикладных областях и коллективах.

с этим не поспоришь. но бедный язык здесь причём?

anonymous
()
Ответ на: комментарий от anonymous

https://ru.wikipedia.org/wiki/Сопрограмма

yield может применяться произвольное количество раз.

Ну давайте подсчитаем, сколько раз вам уже это все объясняли в данной теме:

Раз, два, три, четыре, пять, шесть. Причем, что характерно, пояснения давали разные люди, не только я.

Но, поскольку не доходит, будет еще и седьмой раз.

SO5 не пытается внести в С++ что-то, чего там нет в принципе. А нет такого диспетчера с возможностью вытеснения легких потоков с процессора, который есть в Erlang-е. Отсутствие такого диспетчера означает, что агенты должны будут поддерживать какую-то кооперативную многозадачность и вместо синхронных блокирующих вызовов использовать асинхронные неблокирующие. Либо же в реализации будут использоваться какие-то хаки, которые привязывают реализацию акторов к конкретной платформе (компилятору). Либо же реализации будет требовать прогона исходных текстов/объектного кода через специальные инструменты, которые автоматически будут вставлять в код вызовы кастомного шедулера для предоставления возможности вытеснения текущего легкого потока.

Можно понять, что лично вы не можете считать инструмент, который не соответствует вашим личным взглядам на «единственно правильную реализацию» достойным вашего внимания. Это ваше личное дело.

Только мне пох. Я здесь рассказываю об инструменте, который требует от пользователя реализации агентов в виде конечных автоматов: среагировал на сообщение, изменил что-то в себе, отдал управление сам. В этом случае не нужно никаких yield-ов в языке. Каждый event — это и есть очередная точка входа и точка выхода.

Соответственно, пример из Wiki будет выглядеть в SO5 как:

class producer : public so_5::rt::agent_t
{
public :
  void evt_some_external_event(...)
  {
    create new item;
    consumer_mbox->deliver_message( new item );
  }
...
};

class consumer : public so_5::rt::agent_t
{
public :
  void evt_consume(...)
  {
    consume received item;
  }
};

А все loop-ы, которые есть в псевдокоде из Wiki, будет крутить сам SObjectizer RunTime.

Так что еще раз: SO5 дает пользователю именно такую реализацию. Собственно, как Theron. И, в некоторых случаях, как libcaf. Если вас это не устраивает — нет проблем. Как тут выяснили, вы всегда можете продекларировать, что способны написать свой Erlang сами.

eao197 ★★★★★
() автор топика
Ответ на: комментарий от anonymous

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

Фреймворки для того и делают, чтобы каждый разработчик сам не писал собственный лисапед. Или же вы настолько круты, что для своих задач сами пишете свой event-loop? А разработки вроде libuv/libev/libevent, boost.asio и ace считаете никому ненужными поделками для ниасиляторов?

зато, возможно, начинаешь догадываться почему твоё ненужно ненужно.

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

Вообще, в чем смысл высказывания «ненужно» в данном случае? Библиотека есть, она развивается, используется. Вашего мнения при этом никто не спрашивал, не спрашивает и не собирается спрашивать, ибо вы никто и звать вас никак. Так к чему это повторение?

Может из-за того, что это LOR и здесь так принято?

заставляют соискателей писать на собеседованиях

предлагаешь послушать в этом вопросе твоё мнение?

Т.е. я оказался прав. Да вы, батенька, кроме того, что долбо*б, так еще и мудак. И понятно, почему люди предпочитают с вами не работать.

это и есть наброс. я пытаюсь разобраться в истинных его целях.

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

с этим не поспоришь. но бедный язык здесь причём?

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

eao197 ★★★★★
() автор топика
Ответ на: комментарий от eao197

А разработки вроде libuv/libev/libevent, boost.asio и ace считаете никому ненужными поделками для ниасиляторов?

про ace я уже сказал

libuv/libev выглядят как пионерские поделки, использованию не подлежат

boost::asio обладает кривым (тем не менее, грамотным, в отличие от твоего) интерфейсом. мне неудобно. плюс та же проблема, что и с libevent

libevent — неплохая библиотека. в первой версии была очень тормозной, за что я её в те времена нещадно банил. не поленился написать об этом разработчикам — во второй версии исправили. отсутствие доступа в event-loop (see also boost) является stopper-issue для большинства моих задач; для маленьких поделок иногда использую.

соответственно, за последние 10-15 лет я написал уже несколько аналогов: на нормальных крестах с нормальными интерфейсами (этот вопрос до сих пор совершенствуется).

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

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

anonymous
()
Ответ на: комментарий от anonymous

соответственно, за последние 10-15 лет я написал уже несколько аналогов: на нормальных крестах с нормальными интерфейсами (этот вопрос до сих пор совершенствуется).

И где же можно глянуть сии шедевры?

пожалуйся в гугл, в них такая корпоративная политика.

Вы работаете в Google и проводите там собеседования?

eao197 ★★★★★
() автор топика
Ответ на: комментарий от eao197

И где же можно глянуть сии шедевры?

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

чтобы ты не тявкал за следы, объясню: я не отливаю свой код в граните. кто считает нужным — изменяет.

anonymous
()
Ответ на: комментарий от anonymous

в кодовой базе нескольких крупных компаний.

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

Показать публике что-нибудь можете?

eao197 ★★★★★
() автор топика
Ответ на: комментарий от anonymous

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

Но тут хоть, по-моему, стала более ясной причина волей данного товарища. Могу предположить, что это какой-то крутой спец, который последние лет пятнадцать плотно копается внутрях Unix-ов и на «ты» сетевым стеком и его окрестностями. Эти знания востребованы крупными компаниями, вроде Яндекса, которым реально нужно выжимать максимум из железа и обеспечивать поддержку максимального числа коннектов на одной ноде. Т.е. чувак занимается задачами, с которыми сталкиваются считанные компании во всем мире. И, вполне возможно, действительно является матерым проффи, коих мало.

Однако, из-за своего профессионализма и специфического опыта он и на весь остальной мир смотрит только со своей специфической колокольни. Если чья-то разработка не позволяет держать миллион коннектов на одном ядре — значит это дерьмо и ненужно.

Ну, в общем-то, понятная точка зрения. Ущербная, правда. Это как если бы главный конструктор БелАЗА высказался бы про Газель: дерьмо и не нужно. Что правда, если кто-то попробует возить в карьерах породу на Газелях. И полная хрень, если кому-то нужно развозить, скажем, школьные тетради по ларькам «Союзпечати». Не на БелАЗАх же это делать, прямо слово.

Мир настолько многообразен, что в нем вполне находится место и для ACE, и для libuv, и для libev/libevent, и для boost.asio, и для POCO и еще для кучи всего. И, что характерно, на каждом из этих проектов построена куча реально работающих проектов, разработчики которых совершенно не переживают, что полагаются на выбранный ими фреймворк.

Но с колокольни данного тимлидуса анонимуса — все это херня, дерьмо и кривота. Потому что вне того, что он делает, нет ничего хорошего и нужного.

eao197 ★★★★★
() автор топика
Ответ на: комментарий от eao197

1. ты — не программист, и поэтому не знаешь как организуется разработка по. поэтому до тебя не доходит, что у программистов не бывает подчинённых.

2. ты считаешь, что хамство и оскорбления хоть немного изменят твою ничтожность?

anonymous
()
Ответ на: комментарий от anonymous

1. ты — не программист, и поэтому не знаешь как организуется разработка по. поэтому до тебя не доходит, что у программистов не бывает подчинённых.

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

2. ты считаешь, что хамство и оскорбления хоть немного изменят твою ничтожность?

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

eao197 ★★★★★
() автор топика
Ответ на: комментарий от eao197

Вы уж определитесь, тимлид вы или не тимлид.

Да тролль он обычный. неужели не понятно уже со второй страницы? Я, например, тоже все соревнования по ... хм ...боксу за последние 15 лет выигрывал, только ссылки на них я вам не дам, потому что сами ищите и вообще бои закрытые, но я еще и молодняк натаскиваю...тайсоны и прочие «боксеры» - лохи.

да этож типичный двачевский способ троллить.

anonymous
()
Ответ на: комментарий от anonymous

Да тролль он обычный. неужели не понятно уже со второй страницы?

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

Ну а в наездах подобных личностей удается лучше рассказать о том, что за библиотеку мы делаем (иногда и лучше понять самому, где расставлять акценты). Например, после данного спора я стал подозревать, что большинство читателей под термином «событийно-ориентированных приложения» понимаю приложения, работающие с сетью или файловой системой. Тогда как мы понимаем это иначе. Ведь вещи типа «температура изменилась на 5 градусов», «подошло время опроса датчиков влажности», «получен запрос на проверку криптоподписи» — это все тоже события, которые нужно как-то обрабатывать. Как раз SObjectizer предоставляет один из возможных способов обработки таких событий.

eao197 ★★★★★
() автор топика
Ответ на: комментарий от eao197

как формулирование задач соотносится с руководством? такое только в рогах и копытах на 10-20 программистов может быть.

anonymous
()
Ответ на: комментарий от darkenshvein

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

anonymous
()
Ответ на: комментарий от anonymous

диагноз по фотографии?

Ну пока что вы пытаетесь ставить диагнозы по Интернету:

не программист, и поэтому не знаешь как организуется разработка по

Ну а на счет тимлидерства что: тимлидим или не тимлидим? Или все-таки обычный программист, который код по кем-то выданным заданиям педалит с 9:00 до 18:00 с перерывом на обед и размер премии которого от формальных KPI зависит?

eao197 ★★★★★
() автор топика
Ответ на: комментарий от eao197

«подошло время опроса датчиков влажности»

запахло пыльной полкой :)

чем это отличается от пакета из сети? протокол другой? или физический уровень ты тоже берёшься обрабатывать?

anonymous
()
Ответ на: комментарий от eao197

ставить диагнозы по Интернету:

я ставлю диагноз по коду.

Ну а на счет тимлидерства

«помощником пм-а по всяким непонятным техническим штукам» не работаю. за последние лет 10 ни в одной компании такого толкования не видел.

anonymous
()
Ответ на: комментарий от anonymous

«помощником пм-а по всяким непонятным техническим штукам» не работаю.

Хер знает, откуда здесь эта формулировка.

за последние лет 10 ни в одной компании такого толкования не видел.

Вопрос был простой: тимлид или нет?

eao197 ★★★★★
() автор топика
Ответ на: комментарий от anonymous

ответ тоже простой: дважды, плюс ещё две роли в двух других проектах.

Если тимлид, значит есть команда, в которой вы главный. Раз так, значит есть те, кто вам подчиняются внутри команды.

Впрочем, тимлид слишком маленькая должность, чтобы с аплобом рассуждать о процессе разработки ПО.

eao197 ★★★★★
() автор топика
Ответ на: комментарий от eao197

твоё непонимание из-за того, что практически всю сознательную жизнь варишься в небольшом собственном соку.

я правильно понимаю, что по теме оп-поста обсуждать уже нечего и моя персона значительно интереснее этой так называемой «библиотеки»?

anonymous
()
Ответ на: комментарий от anonymous

я правильно понимаю, что по теме оп-поста обсуждать уже нечего и моя персона значительно интереснее этой так называемой «библиотеки»?

Это я у вас должен спросить. Вы же здесь исходили на говно по поводу моей персоны. Ни одной объективной претензии к самой библиотеки вы выдавить из себя не смогли.

eao197 ★★★★★
() автор топика
Ответ на: комментарий от anonymous

чем датчики подключаем?

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

SObjectizer не решает проблем низкого уровня, как это делает, например, libuv/ACE/asio. Но вот инициировать команды или реагировать на данные из более низких уровней — это вполне возможно.

eao197 ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.