Здравствуйте, Gaperton, Вы писали:
G>Здравствуйте, gandjustas, Вы писали:
G>>Угу, Axum так умеет.
G>>Синхронное и асинхронное копирование данных из одного стрима в другой на Axum
G>Занятно. И что именно он сделает с моим кодом, если я напишу asynchronous? Это поддается осмыслению?
Позаменяет синхронные вызовы, на аналогичные им асинхронные и треды блокироваться не будут. Кроме того с помощью констркции interleave можно несколько асинхронных возовов параллельно запустить при этом не париться с синхронизацией.
Именно для таких выкрутасов и нужен язык, а не просто библиотека.
Здравствуйте, gandjustas, Вы писали:
G>>Занятно. И что именно он сделает с моим кодом, если я напишу asynchronous? Это поддается осмыслению?
G>Позаменяет синхронные вызовы, на аналогичные им асинхронные и треды блокироваться не будут. Кроме того с помощью констркции interleave можно несколько асинхронных возовов параллельно запустить при этом не париться с синхронизацией.
G>Именно для таких выкрутасов и нужен язык, а не просто библиотека.
А вот тут рядом eao197 фьючерсы весьма по делу помянул. Чем это лучше работы с фьючерсами?
Здравствуйте, Gaperton, Вы писали:
G>Здравствуйте, gandjustas, Вы писали:
G>>>Занятно. И что именно он сделает с моим кодом, если я напишу asynchronous? Это поддается осмыслению?
G>>Позаменяет синхронные вызовы, на аналогичные им асинхронные и треды блокироваться не будут. Кроме того с помощью констркции interleave можно несколько асинхронных возовов параллельно запустить при этом не париться с синхронизацией.
G>>Именно для таких выкрутасов и нужен язык, а не просто библиотека.
G>А вот тут рядом eao197 фьючерсы весьма по делу помянул. Чем это лучше работы с фьючерсами?
Декларативностью.
Здравствуйте, Gaperton, Вы писали:
G>Здравствуйте, eao197, Вы писали:
G>>>Занятно. И что именно он сделает с моим кодом, если я напишу asynchronous? Это поддается осмыслению?
E>>Если я правильно понимаю, то при вызове CopyStreamAsync сам ран-тайм произведет вызов на одной из рабочих нитей из пула. Т.е. вызывающей стороне всего лишь не придется вручную бабахаться с оформлением фьючерса.
G>Какое-то получается весьма сомнительное преимущество. Которое скорее затруднит чтение кода, чем сделает его более понятным.
да ну? Разница между синхронныи и асинхронным вариантом в одном декларативном объявлении затрудняет чтение кода?
G>Уж лучше тупо фьючерсы на уровне языка поддержать, чтоб не заставлять программиста сильно бабахаться с его оформлением, и не морочить людям голову.
Они вроде и так поддерживаются, правда я по фьючерсам не спец.
Здравствуйте, gandjustas, Вы писали:
G>>>>Занятно. И что именно он сделает с моим кодом, если я напишу asynchronous? Это поддается осмыслению?
G>>>Позаменяет синхронные вызовы, на аналогичные им асинхронные и треды блокироваться не будут. Кроме того с помощью констркции interleave можно несколько асинхронных возовов параллельно запустить при этом не париться с синхронизацией.
G>>>Именно для таких выкрутасов и нужен язык, а не просто библиотека.
G>>А вот тут рядом eao197 фьючерсы весьма по делу помянул. Чем это лучше работы с фьючерсами? G>Декларативностью.
"Декларативность" как свойство сама по себе не есть преимущество. Преимущество проявляется в контексте задачи. Тем более что самый обычный фьючерс дают ту же самую декларативность, с той разницей, что она более гранулярна, и содержит гораздо меньше магии. И это есть хорошо.
Если я в длинной функции объявил фьючерс, то я сообщаю читателю, что вот эта переменная, обращение с которой выглядит вполне гражданским образом, на самом деле скрывает под собой асинхронные вычисления. А остальные — нет. Человек видит такие места в коде.
Если я в начале длинной функции ставлю asynchronous, читатель должен ментальным сканированием догадываться о его поведении?
Здравствуйте, gandjustas, Вы писали:
G>>Какое-то получается весьма сомнительное преимущество. Которое скорее затруднит чтение кода, чем сделает его более понятным. G>да ну? Разница между синхронныи и асинхронным вариантом в одном декларативном объявлении затрудняет чтение кода?
Конечно. Точки взаимодействия не видны явно. А это читателю функции будет очень интересно знать.
Здравствуйте, Gaperton, Вы писали:
G>Здравствуйте, gandjustas, Вы писали:
G>>>>>Занятно. И что именно он сделает с моим кодом, если я напишу asynchronous? Это поддается осмыслению?
G>>>>Позаменяет синхронные вызовы, на аналогичные им асинхронные и треды блокироваться не будут. Кроме того с помощью констркции interleave можно несколько асинхронных возовов параллельно запустить при этом не париться с синхронизацией.
G>>>>Именно для таких выкрутасов и нужен язык, а не просто библиотека.
G>>>А вот тут рядом eao197 фьючерсы весьма по делу помянул. Чем это лучше работы с фьючерсами? G>>Декларативностью.
G>"Декларативность" как свойство сама по себе не есть преимущество. Преимущество проявляется в контексте задачи. Тем более что самый обычный фьючерс дают ту же самую декларативность, с той разницей, что она более гранулярна, и содержит гораздо меньше магии. И это есть хорошо.
G>Если я в длинной функции объявил фьючерс, то я сообщаю читателю, что вот эта переменная, обращение с которой выглядит вполне гражданским образом, на самом деле скрывает под собой асинхронные вычисления. А остальные — нет. Человек видит такие места в коде.
G>Если я в начале длинной функции ставлю asynchronous, читатель должен ментальным сканированием догадываться о его поведении?
asynchronous не создает неявно отложенных вычислений (именно они вроде как фьючерами называются). Все что делает asynchronous — заменяет все блокирующие вывозы на асинхронные, которые не блокируют физический поток. В принципе такое поведение должно быть по-умолчанию в агентно-ориентированной среде (без явного управления потоками), а декларативно должно отменяться.
Здравствуйте, Gaperton, Вы писали:
G>Короче, это хорошее, годное решение .
У нас аппартменты реализуются через привязку агентов к диспетчерам. Агент может быть либо пассивным (работать на одной нити вместе с другими пассивными), либо членом активной группы (каждая группа работает на своей нити, состав группы может динамически изменяться), либо активным объектом (один агент -- одна нить). За счет этого в наших приложениях могут быть сотни тысяч агентов (на тестах их число достигало 500K на машине с 2Gb RAM, в боевых системах -- до нескольких тысяч), которые работают на десятках/сотнях нитях.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Gaperton, Вы писали:
E>>Сильно сомневаюсь, по крайней мере на основании своего опыта.
G>Знаешь, по крайней мере это не плохое свойство . Автоматическая неявная синхронизация, которую мы имеем без каких-либо умственных затрат в данном случае — чем плоха?
Я не могу с ходу вспомнить ситуацию из своей практики, когда сообщение, которое нам не нужно на текущем шаге (в текущем состоянии), может потребоваться на следующем шаге (в новом состоянии). И как раз для того, чтобы не оставлять в mailbox-е сообщения, которые мы проигнорировали (и не путали карты впоследствии), у нас нет selective receive.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Gaperton, Вы писали:
G>Смотри. Вот это — асинхронный код. На "псевдокоде" пишу.
А в раннем CQG десятилетней давности (которому тогда было всего-то десять лет возраста) ваще была жесть. Она тоже построена на агентском фреймворке, весьма неплохом, но! Там в ряде прикладных объектов-агентов не было события, соответствующего завершению запроса. Его иногда бывает удивительно трудно корректно добавить, вы не поверите, парни . Например, если речь идет о готовности сети активных объектов из сотен элементов, с нетривиальной топологией, и со сложным и потенциально разным поведением и состоянием, у которых локально оптимизировано прохождение асинхронных сообщений в рамках сети . В таких случаях, объект-сервис приходилось опрашивать по таймеру, дожидаясь, пока он не станет готов. Примерно так:
G>
Не проняло? Тогда представьте, что вам надо сделать серию запросов в цикле, чтобы потом обработать их результат, и некоторые запросы могут обломиться (как сразу, так и потом) — и тогда надо корректно обработать ошибку.
Вот он, асинхронный код во всей своей всеподавляющей мощи, ломающий психику пионеров легко, как ураган сносит карточный домик, и парализующий волю ветеранов, в сердца которых ледяным сквозняком закрадывается ужас и безысходность!
И ведь, типо, по другому нельзя. Не, понятно, что можно написать обертку вокруг этого безобразия, которая будет давать нормальный event. Но оно будет выглядеть только чуть-чуть лучше. Надо решать проблему радикально. Как?
Показываю особую, файберную магию, которая обеспечивается примерно пятью сотнями строк кода в системном фреймворке, и минимальными модификациями прикладного кода. Да, eao197, это опять мой "волшебный" шедулер .
G>
В современном CQG это можно делать двумя способами, как по старинке, так и способом, описанным выше, если вызовы идут из контекста файбера. Как хотите — работают оба способа. По моему, здоровый человек без мазохистских наклонностей предпочтет второй.
Разумеется, я пишу весьма условный код, демонстрирующий стиль работы, не раскрывая никакой коммерческой тайны. Просто я хочу, чтобы проняло, чтобы вы почувствовали, что все не так просто .
Здравствуйте, eao197, Вы писали:
E>У нас аппартменты реализуются через привязку агентов к диспетчерам. Агент может быть либо пассивным (работать на одной нити вместе с другими пассивными), либо членом активной группы (каждая группа работает на своей нити, состав группы может динамически изменяться), либо активным объектом (один агент -- одна нить). За счет этого в наших приложениях могут быть сотни тысяч агентов (на тестах их число достигало 500K на машине с 2Gb RAM, в боевых системах -- до нескольких тысяч), которые работают на десятках/сотнях нитях.
Ну вот, апартменты уже есть. Дело за небольшим — добавить "файберного агента", чтобы он мог использоваться наравне с коллбэчным, и проследить, чтобы они не сожрали все адресное пространство . Они, в принципе, на 32 битах такое могут. И станет у тебя комфортно, "как в Эрланге". Ну, почти.
Здравствуйте, eao197, Вы писали:
E>Здравствуйте, Gaperton, Вы писали:
E>>>Сильно сомневаюсь, по крайней мере на основании своего опыта.
G>>Знаешь, по крайней мере это не плохое свойство . Автоматическая неявная синхронизация, которую мы имеем без каких-либо умственных затрат в данном случае — чем плоха?
E>Я не могу с ходу вспомнить ситуацию из своей практики, когда сообщение, которое нам не нужно на текущем шаге (в текущем состоянии), может потребоваться на следующем шаге (в новом состоянии). И как раз для того, чтобы не оставлять в mailbox-е сообщения, которые мы проигнорировали (и не путали карты впоследствии), у нас нет selective receive.
Избежать лика очень просто — добавляешь пустой паттерн в конец списка, и все. Это не проблема.
Если ты всегда разделяешь мэйлбоксы для разных типов сообщений, то в selective receive выраженной повседневной необходимости нет. Если тебе не важна последовательность прихода сообщений разных типов и от разных источников, конечно. Обычно она не важна.
А в решении Эрланга, в свою очередь, мэйлбоксы декларировать не нужно, они как бы "создаются" неявно и динамически. Это удобно и более гибко. В языке, где есть паттерн-матчинг, так работать удобнее. Если паттерн-матчинга в языке нет — чисто с точки зрения использования удобнее создавать много мэйлбоксов, а не пользоваться selective receive. Все просто.
Здравствуйте, Gaperton, Вы писали:
E>>У нас аппартменты реализуются через привязку агентов к диспетчерам. Агент может быть либо пассивным (работать на одной нити вместе с другими пассивными), либо членом активной группы (каждая группа работает на своей нити, состав группы может динамически изменяться), либо активным объектом (один агент -- одна нить). За счет этого в наших приложениях могут быть сотни тысяч агентов (на тестах их число достигало 500K на машине с 2Gb RAM, в боевых системах -- до нескольких тысяч), которые работают на десятках/сотнях нитях.
G>Ну вот, апартменты уже есть. Дело за небольшим — добавить "файберного агента", чтобы он мог использоваться наравне с коллбэчным, и проследить, чтобы они не сожрали все адресное пространство . Они, в принципе, на 32 битах такое могут. И станет у тебя комфортно, "как в Эрланге". Ну, почти.
Я в свое время именно так и сделал. Чтобы не лезть в работающий механизм, с одной стороны, и чтобы работа в "легаси" окружении стала более комфортной — с другой. Результатом очень доволен. И не только я. Получается более "гражданский" механизм, для использования которого не требуется высокого порога вхождения. Людям очень нравится.
G>>>Для axum сейчас не нужно больше, чем сообщения, процессы и dataflows. T>>И что получится в итоге? Беспроцессный монолитный императивный ужас, (сравнительно) непригодный к использованию в разработке? G>Вроде как процессный, но очень императивный. Основное преимущество этого ужаса в том, что он он на .NET, поэтому хорошо делается интероп.
Вот уж совсем не проблема.
T>>Но ладно итог исследований. Сейчас-то чего? То, что я вижу, не тянет больше, чем на библиотеку. Это назвали языком в силу какого-то недоразумения. G>Библиотека для этого уже существует, а вот как раз поддржка агентов и изоляция на уровне языка только в разработке.
Это я в смысле "практически всё то же самое можно получить в виде DSEL на нормальном языке".
T>>А все подхватили. G>Ну и хорошо, изучат новоые подходы в разработке. Я например после прочтения статей и примеров по Axum начал Erlang понимать, хотя его изучением и не занимался никогда.
Увы, ты начал понимать только общее для Axum и Erlang. А Erlang в целом больше этого подмножества.
(обнаружил себя в непривычной ситуации защиты Эрланга)
Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
Здравствуйте, eao197, Вы писали:
E>Я не могу с ходу вспомнить ситуацию из своей практики, когда сообщение, которое нам не нужно на текущем шаге (в текущем состоянии), может потребоваться на следующем шаге (в новом состоянии). И как раз для того, чтобы не оставлять в mailbox-е сообщения, которые мы проигнорировали (и не путали карты впоследствии), у нас нет selective receive.
Вторая причина по которй Erlang поддерживает selective-receive — горячая замена кода.
Здравствуйте, thesz, Вы писали:
G>>>>Для axum сейчас не нужно больше, чем сообщения, процессы и dataflows. T>>>И что получится в итоге? Беспроцессный монолитный императивный ужас, (сравнительно) непригодный к использованию в разработке? G>>Вроде как процессный, но очень императивный. Основное преимущество этого ужаса в том, что он он на .NET, поэтому хорошо делается интероп.
T>Вот уж совсем не проблема.
С имеративностью я прогнал. В спеке по языку написано что axum поддерживать должен все функциональные фичи C# 3.0. Правда компилятор далек еще от этого состояния.
T>>>Но ладно итог исследований. Сейчас-то чего? То, что я вижу, не тянет больше, чем на библиотеку. Это назвали языком в силу какого-то недоразумения. G>>Библиотека для этого уже существует, а вот как раз поддржка агентов и изоляция на уровне языка только в разработке. T>Это я в смысле "практически всё то же самое можно получить в виде DSEL на нормальном языке".
А зачем? С такой платформой как .NET отдельный язык может быть гораздо выгоднее, чем впихивать теже особенности в DSEL.
Кстати, есть примеры удачного создания агентной модели как DSEL в существующем языке?
T>>>А все подхватили. G>>Ну и хорошо, изучат новоые подходы в разработке. Я например после прочтения статей и примеров по Axum начал Erlang понимать, хотя его изучением и не занимался никогда. T>Увы, ты начал понимать только общее для Axum и Erlang. А Erlang в целом больше этого подмножества.
Ну давай посмотрим. В чем Erlang настолько больше?
T>(обнаружил себя в непривычной ситуации защиты Эрланга)
(а я вроде как и не против Erlang был)
Здравствуйте, gandjustas, Вы писали: G>Кстати, есть примеры удачного создания агентной модели как DSEL в существующем языке?
Не знаю, насколько там все удачно, но вот: http://rsdn.ru/forum/message/3374655.1.aspx
Здравствуйте, Mr.Cat, Вы писали:
MC>Здравствуйте, gandjustas, Вы писали: G>>Кстати, есть примеры удачного создания агентной модели как DSEL в существующем языке? MC>Не знаю, насколько там все удачно, но вот: http://rsdn.ru/forum/message/3374655.1.aspx