Re[5]: Ещё одно сравнение с участием Эрланга
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 20.06.07 18:18
Оценка:
Здравствуйте, Gaperton, Вы писали:

E>>Горазд ты примеры из документации дергать.


G>Я так понял, тебе понятно, насколько этот код на плюсах возрастет в объеме. Или нет?


Если бы мне потребовалось делать такой парсинг раз или два, или даже три, то объем был бы существенно больше.
А вот если бы мне нужно было это делать гораздо больше раз, то написал бы библиотеку, которая делала бы приблизительно следующее:
void
packet_header_t::load( oess_1::io::istream_t & in )
  {
    in >> bits( IP_VERSION, 4 )
       >> bits( HLen, 4 )
       >> bits( SrvcType, 8 )
       >> bits( TotLen, 16 )
       >> bits( ID, 16 )
       >> bits( Flgs, 3 )
       >> bits( FragOff, 13 )
       ... и так далее...
  }

или бы вообще сделал генератор, который бы парсинг подобных пакетов генерировал по DSL-описаниям.

G> { Stream1, ServiceType, SourceAddrTon, SourceAddr, ... ] = parse( Stream, [ string, 2, 4, ... ] ),

G>здесь я задаю параметрами partition как мне выделять из потока (поток это бинари) — строку или число (размер в байтах). Функция parse пишется один раз. Написать?

Зачем же.

G>Чтение я могу разбить на несколько строк — на столько, сколько захочу. Если у меня будут разные опции форматов с числовыми аргументами, я определю манипуляторы, например:


G>unsigned-int( N ) -> { unsigned-int, N }.


G>{ Stream1, X, Y } = parse( Stream, [ unsigned-int( 4 ), string ] )


G>А еще я могу задавать жутко хитрые манипуляторы, например такие

G>{ Stream1, X, { Y, Z } } = parse( Stream, [ string, fun( << A:3, B:5, ?MY_CONSTANT, _/binary >> ) -> { A, B } end ] ).

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


G>OptParms = parse( StreamN, opt_parms() );


G>Вот так, дружище. Не слишком страшно получается? И заметь, никакого ООП и перегруженных операторов.


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

G>>>Кстати, эксцепшены, которые ты бросаешь в С++, тебе придется бросать ручками. И ручками постоянно паковать туда символическую информацию. Также крайне любопытно, что ты будешь делать при вылете эксцепшна в потоке. Ну поймал ты его наверху в тред-функции — типа классно, let it crash и все такое. Что будем делать с потоком? А что будешь делать с его примитивами синхронизации, на котором стоят в блокировке другие потоки?


E>>А про понятие exception safety за пределами C++ никто не знает, надо полагать?


G>Угу, а как насчет разделяемых данных, которые остались в нецелостном состоянии? И все-таки, что именно ты предлагаешь делать с потоком?


Какие данные в нецелостном состоянии, если обеспечивается exception safety?

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


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[6]: Ещё одно сравнение с участием Эрланга
От: Gaperton http://gaperton.livejournal.com
Дата: 20.06.07 21:19
Оценка:
Здравствуйте, eao197, Вы писали:

E>Здравствуйте, Gaperton, Вы писали:


E>>>Горазд ты примеры из документации дергать.


G>>Я так понял, тебе понятно, насколько этот код на плюсах возрастет в объеме. Или нет?


E>Если бы мне потребовалось делать такой парсинг раз или два, или даже три, то объем был бы существенно больше.

E>А вот если бы мне нужно было это делать гораздо больше раз, то написал бы библиотеку, которая делала бы приблизительно следующее:
E>
E>void
E>packet_header_t::load( oess_1::io::istream_t & in )
E>  {
E>    in >> bits( IP_VERSION, 4 )
       >>> bits( HLen, 4 )
       >>> bits( SrvcType, 8 )
       >>> bits( TotLen, 16 )
       >>> bits( ID, 16 )
       >>> bits( Flgs, 3 )
       >>> bits( FragOff, 13 )
E>       ... и так далее...
E>  }
E>


Выглядит неплохо. Только маленький вопрос. Как этот код поведет себя, если IP_VERSION не совпадет? В Эрланговском примере работает pattern-matching и проверится следующий паттерн. А у тебя? Эксцепшн? IP_VERSION — это ведь константа. Это чрезвычайно существенный момент.

E>или бы вообще сделал генератор, который бы парсинг подобных пакетов генерировал по DSL-описаниям.

Это не фокус в любом языке. DSL на каждый писк — не выход. Кстати, можно просто воспользоваться генератором ASN.1.

G>>Вот так, дружище. Не слишком страшно получается? И заметь, никакого ООП и перегруженных операторов.


E>Та же самая херня, мягко говоря. Смена шила на мыло. Тем более, что ООП и наследование часто помогает повторно использовать уже готовые куски кода.


Похоже, конечно. Но далеко не тоже самое. Кстати, мне тут пришла идея получше. Смотри:

{ RestOfStream, [
   String1,
   << Number:7, Num2:9 >>,      здесь разбирается бинарис длиной в два байта
   String2,
   CompoundType ] } = parse( Stream, [ string, 2, string, my_module:my_parse_fun/1 ] ),


функция разбора потока имеет сигнатуру { RestOfStream, Data } = parse( Stream ), и я их могу каскадировать. Повторно использую уже готовые куски кода, и читабельность повыше — сразу виден формат пакета, в отличии от случая перекрытых >>> — затрахаешься по коду структуру пакета восстанавливать.

G>>>>Кстати, эксцепшены, которые ты бросаешь в С++, тебе придется бросать ручками. И ручками постоянно паковать туда символическую информацию. Также крайне любопытно, что ты будешь делать при вылете эксцепшна в потоке. Ну поймал ты его наверху в тред-функции — типа классно, let it crash и все такое. Что будем делать с потоком? А что будешь делать с его примитивами синхронизации, на котором стоят в блокировке другие потоки?


E>>>А про понятие exception safety за пределами C++ никто не знает, надо полагать?


G>>Угу, а как насчет разделяемых данных, которые остались в нецелостном состоянии? И все-таки, что именно ты предлагаешь делать с потоком?


E>Какие данные в нецелостном состоянии, если обеспечивается exception safety?


Разделяемые между тредами данные — которые должны меняться транзакционно. Знаешь, зачем в базе данных транзакции есть? Вот тут почти то же самое. А эксцепшн может вылететь в любой момент. Работа с нецелостными данными приведет к падению других потоков, которые с ними работают. И приплыли.

E>А с потоком -- по необходимости. Или поток тихо и мирно завершается. Либо в потоке есть бесконечный цикл, который поймав исключение рестартует операции потока.

Полных гарантий безопасности ты при таком подходе дать не можешь. Поэтому, не можешь и применять до конца подход лет ит крэш.
Re[7]: Ещё одно сравнение с участием Эрланга
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 21.06.07 05:44
Оценка: +1
Здравствуйте, Gaperton, Вы писали:

E>>
E>>void
E>>packet_header_t::load( oess_1::io::istream_t & in )
E>>  {
E>>    in >> bits( IP_VERSION, 4 )
       >>>> bits( HLen, 4 )
       >>>> bits( SrvcType, 8 )
       >>>> bits( TotLen, 16 )
       >>>> bits( ID, 16 )
       >>>> bits( Flgs, 3 )
       >>>> bits( FragOff, 13 )
E>>       ... и так далее...
E>>  }
E>>


G>Выглядит неплохо. Только маленький вопрос. Как этот код поведет себя, если IP_VERSION не совпадет? В Эрланговском примере работает pattern-matching и проверится следующий паттерн. А у тебя? Эксцепшн? IP_VERSION — это ведь константа. Это чрезвычайно существенный момент.


Поскольку в плюсах нет ПМ, то там подход к распознаванию чего-нибудь совсем другой. В плюсах сначала нужно будет вытащить из потока весь объект packet_header_t (или какой-нибудь другой), или часть объекта, а затем с помощью switch-ей или if-ов определять, что это за оно.

G>Похоже, конечно. Но далеко не тоже самое. Кстати, мне тут пришла идея получше. Смотри:


G>
G>{ RestOfStream, [
G>   String1,
G>   << Number:7, Num2:9 >>,      здесь разбирается бинарис длиной в два байта
G>   String2,
G>   CompoundType ] } = parse( Stream, [ string, 2, string, my_module:my_parse_fun/1 ] ),
G>


G>функция разбора потока имеет сигнатуру { RestOfStream, Data } = parse( Stream ), и я их могу каскадировать. Повторно использую уже готовые куски кода, и читабельность повыше — сразу виден формат пакета, в отличии от случая перекрытых >>> — затрахаешься по коду структуру пакета восстанавливать.


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

E>>Какие данные в нецелостном состоянии, если обеспечивается exception safety?


G>Разделяемые между тредами данные — которые должны меняться транзакционно. Знаешь, зачем в базе данных транзакции есть? Вот тут почти то же самое. А эксцепшн может вылететь в любой момент. Работа с нецелостными данными приведет к падению других потоков, которые с ними работают. И приплыли.


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

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


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[7]: Ещё одно сравнение с участием Эрланга
От: Cyberax Марс  
Дата: 21.06.07 05:48
Оценка:
Gaperton wrote:
> Разделяемые между тредами данные — которые должны меняться
> транзакционно. Знаешь, зачем в базе данных транзакции есть? Вот тут
> почти то же самое. А эксцепшн может вылететь в любой момент. Работа с
> нецелостными данными приведет к падению других потоков, которые с ними
> работают. И приплыли.
Именно для работы с такими данными и придумали exception safety в С++.
Выделяется несколько гарантий по безопасности: no-throw (исключения
никогда не будут бросаться), weak exception guarantee (после броска
исключения объект нельзя дальше использовать, но его можно корректно
удалить), strong exception guarantee (после броска исключений операция
будет откачена).

Можно писать так, что будет соблюдаться сильная гарантия. Это совсем не
сложно, кстати.
Posted via RSDN NNTP Server 2.1 beta
Sapienti sat!
Re[8]: Ещё одно сравнение с участием Эрланга
От: Gaperton http://gaperton.livejournal.com
Дата: 21.06.07 06:22
Оценка:
Здравствуйте, eao197, Вы писали:

G>>Похоже, конечно. Но далеко не тоже самое. Кстати, мне тут пришла идея получше. Смотри:


G>>
G>>{ RestOfStream, [
G>>   String1,
G>>   << Number:7, Num2:9 >>,      здесь разбирается бинарис длиной в два байта
G>>   String2,
G>>   CompoundType ] } = parse( Stream, [ string, 2, string, my_module:my_parse_fun/1 ] ),
G>>


G>>функция разбора потока имеет сигнатуру { RestOfStream, Data } = parse( Stream ), и я их могу каскадировать. Повторно использую уже готовые куски кода, и читабельность повыше — сразу виден формат пакета, в отличии от случая перекрытых >>> — затрахаешься по коду структуру пакета восстанавливать.


E>Вот что мне не нравится в подобных декларативных вещах, что при наличии большого количества полей в PDU нужно писать большие туплы прямо в коде для того, чтобы принять результат работы parse. Можешь показать, как от этого дублирования описаний избавиться в Erlang-е


Принять можно без тупла. Можно просто — Result = parse( Stream ), а разобрать его потом. Далее — не обязательно большой разбирать тупо сразу целиком.

{_,_,_,Res1,_,Res2} = ...

{_,Res1,Res2,_,_,_} = ...

Можно и так. Третье — в моем примере тупл состоит из двух элементов, а далее идет список. Так что все еще лучше. Ты можешь разобрать ровно столько, сколько тебе надо.
{ ResStream, [ String1, << Number:16 >> | Tail ] } = parse( Stream, Format ),
А Tail — потом.

E>>>Какие данные в нецелостном состоянии, если обеспечивается exception safety?


G>>Разделяемые между тредами данные — которые должны меняться транзакционно. Знаешь, зачем в базе данных транзакции есть? Вот тут почти то же самое. А эксцепшн может вылететь в любой момент. Работа с нецелостными данными приведет к падению других потоков, которые с ними работают. И приплыли.


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


E>А того, чтобы от исключения портились разделяемые данные -- такого я не помню. Хотя, может это потому, что у меня взаимодействие между потоками на обмене сообщениями строится.
Re[8]: Ещё одно сравнение с участием Эрланга
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 21.06.07 07:12
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>Можно писать так, что будет соблюдаться сильная гарантия. Это совсем не

C>сложно, кстати.

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


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[9]: Ещё одно сравнение с участием Эрланга
От: Константин Л. Франция  
Дата: 21.06.07 08:34
Оценка:
Здравствуйте, Gaperton, Вы писали:

[]

E>>Вот что мне не нравится в подобных декларативных вещах, что при наличии большого количества полей в PDU нужно писать большие туплы прямо в коде для того, чтобы принять результат работы parse. Можешь показать, как от этого дублирования описаний избавиться в Erlang-е


G>Принять можно без тупла. Можно просто — Result = parse( Stream ), а разобрать его потом. Далее — не обязательно большой разбирать тупо сразу целиком.


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

[]
Re[9]: Ещё одно сравнение с участием Эрланга
От: Курилка Россия http://kirya.narod.ru/
Дата: 21.06.07 10:22
Оценка:
Здравствуйте, eao197, Вы писали:

E>Здравствуйте, Cyberax, Вы писали:


C>>Можно писать так, что будет соблюдаться сильная гарантия. Это совсем не

C>>сложно, кстати.
E>Временами сложно. И дорого.
E>Хотя это проблема не только в C++, она есть и в языках со сборкой мусора.

Ммм, в Эрланге?
Re[10]: Ещё одно сравнение с участием Эрланга
От: Курилка Россия http://kirya.narod.ru/
Дата: 21.06.07 10:31
Оценка:
Здравствуйте, Константин Л., Вы писали:

КЛ>Здравствуйте, Gaperton, Вы писали:


G>>Принять можно без тупла. Можно просто — Result = parse( Stream ), а разобрать его потом. Далее — не обязательно большой разбирать тупо сразу целиком.


КЛ>Ну так какая разница, сейчас или потом. Тебе говорят о том, что, фактически, при каждом разборе ты снова будешь писать "декларацию" тупла.


И?
Сравним:
1. "псевдокод" явы
class X{
public int x;
public int y
}
//...
 X x = func();
 System.out.println(x.y);
 System.out.println(x.x);


2. "псеводкод" эрланга
{X, Y} = func(),
io:format("~p~n", X),
io:format("~p~n", Y).


В первом случае тебе нужно знать и хранить в голове структуру класса, какие там поля и т.п.
В эрланге ты можешь сделать то же самое, если поставить Tuple = func(), но если ты "запаттернматчишь", то дальше по коду тебе не нужны подробности структуры тупла, ты работаешь с конкретными данными, которые тебя интересуют в конкретный момент.
Т.е. таким образом ты локализуешь объём сложности данных, участвующих в логике приложения.
Всё, конечно, есть только лишь сугубо моё мнение
Re[10]: Ещё одно сравнение с участием Эрланга
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 21.06.07 10:32
Оценка:
Здравствуйте, Курилка, Вы писали:

E>>Временами сложно. И дорого.

E>>Хотя это проблема не только в C++, она есть и в языках со сборкой мусора.

К>Ммм, в Эрланге?


Теоритически, думается, и в Эрланге возможно. Например, процесс A должен отослать процессу B два сообщения, только при получении второго сообщения у процесса B будет о процессе A целостная информации. После отсылки первого сообщения процесс A умирает по исключению. Если не предпринимать специальных действий в процессе B, то он, не дождавшись второго сообщения от A, будет владеть некорректной информацией.

Кстати, хочу поинтересоваться у Эрланговедов -- как в Эрланге обстоит дело с освобождением ресурсов при исключениях. Скажем, в C++ и D есть RAII, деструктор может завершить начатые операции. А в Эрланге как? Начинаем транзакцию в БД, к примеру, затем процесс падает. Кто будет транзакцию откатывать? В какой момент?


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[3]: Ещё одно сравнение с участием Эрланга
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 21.06.07 10:39
Оценка: +1
Здравствуйте, VladD2, Вы писали:

VD>Небольшая поправка. 1С — это Жлабэйсик с русифицированным синтаксисом. ДСЛ-я там не ма. Они просто преоставляют готовую библоитеку доступа к предметно-ориентированному хранилищу данных. В общем, Эксес переросток.

Все же предметно — объектно ориентированному. Пусть и с поздним связыванием (хотя легко статически типизацировать). Резко увеличивающему скорость разработки. Нужно учитывать и встроенные средства аля объектных запросов (сложные выборки бух запросов) и вывод отчетов ввиде таблиц где указываются переменные функции итд. Это намного больше чем Эксес иначе сам Эксес легко перерос бы 1С .
и солнце б утром не вставало, когда бы не было меня
Re[11]: Ещё одно сравнение с участием Эрланга
От: Курилка Россия http://kirya.narod.ru/
Дата: 21.06.07 10:42
Оценка:
Здравствуйте, eao197, Вы писали:


E>Теоритически, думается, и в Эрланге возможно. Например, процесс A должен отослать процессу B два сообщения, только при получении второго сообщения у процесса B будет о процессе A целостная информации. После отсылки первого сообщения процесс A умирает по исключению. Если не предпринимать специальных действий в процессе B, то он, не дождавшись второго сообщения от A, будет владеть некорректной информацией.


Ну и пусть себе владеет, делов-то
Задача может решаться след. образом: есть некий диспетчер приложения B, который ловит сообщения, на каждое полученное Первое создаёт процесс, ведёт список процессов, Второе сообщение пересылает уже созданному процессу, плюс периодически список чекать на "таймаут".
Или другой вариант А посылает сообщение, диспетчер создаёт процесс, этот процесс посылает ответ с подтверждением и своим pid, и сам "садится" в receive (с таймаутом), и ждёт там, никому не мешая, пока не сдохнет.

Про транзакции не готов ответить, кроме мнезии там их нигде не видел.
Re[11]: Ещё одно сравнение с участием Эрланга
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 21.06.07 10:43
Оценка: +1
Здравствуйте, Курилка, Вы писали:

К>1. "псевдокод" явы

К>
К>class X{
К>public int x;
К>public int y
К>}
К>//...
К> X x = func();
К> System.out.println(x.y);
К> System.out.println(x.x);
К>


К>2. "псеводкод" эрланга

К>
К>{X, Y} = func(),
К>io:format("~p~n", X),
К>io:format("~p~n", Y).
К>


К>В первом случае тебе нужно знать и хранить в голове структуру класса, какие там поля и т.п.

К>В эрланге ты можешь сделать то же самое, если поставить Tuple = func(), но если ты "запаттернматчишь", то дальше по коду тебе не нужны подробности структуры тупла, ты работаешь с конкретными данными, которые тебя интересуют в конкретный момент.
К>Т.е. таким образом ты локализуешь объём сложности данных, участвующих в логике приложения.
К>Всё, конечно, есть только лишь сугубо моё мнение

В случае {X,Y} = func() тебе нужно знать, что func() возвращает именно тупл из двух элементов. И знать, какой элемент тупла что обозначает и чем является. Что соответствует знанию структуры класса X в Java. Только в статичести типизированных языках это знание декларируется описанием класса X, а вот в динамически-типизированных языках одной декларации:
func() -> {X, Y}

мало, если X и Y не атомарные значения, а какие-нибудь агрегаты (списки или туплы, а еще хуже -- списки туплов со списками внутри).

А если увеличить количество полей в X с двух до двадцати (обычное дело для телекома). И сделать половину из них необязательными.

А если в конкретный момент меня интересует поле X, а затем, спустя какое-то время мне потребуется еще и поле Z, то в ООП языках я могу сделать что-то вроде:
PDU pdu = parsePdu();
if( pdu.fieldOne == SOMETHING )
  // Здесь не известно, что потребуется process()-у из pdu.
  process( pdu );
...
void process( PDU pdu )
  {
    pdu.fieldThree() ...
  }

В Erlang-е для этого придется делать что?


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[11]: Ещё одно сравнение с участием Эрланга
От: aka50 Россия  
Дата: 21.06.07 10:46
Оценка:
Здравствуйте, eao197, Вы писали:

E>Здравствуйте, Курилка, Вы писали:


E>>>Временами сложно. И дорого.

E>>>Хотя это проблема не только в C++, она есть и в языках со сборкой мусора.

К>>Ммм, в Эрланге?


E>Теоритически, думается, и в Эрланге возможно. Например, процесс A должен отослать процессу B два сообщения, только при получении второго сообщения у процесса B будет о процессе A целостная информации. После отсылки первого сообщения процесс A умирает по исключению. Если не предпринимать специальных действий в процессе B, то он, не дождавшись второго сообщения от A, будет владеть некорректной информацией.


Перед посылкой можно залинковать себя на таргет процесс и получить уведомление, что процесс сдох. Т.к. нет состояния, то и откатывать ничего не надо (у нас есть начальный объект и есть незавершенный, т.е. мы просто выбросим незавершенный). На актерах да без состояния, Жень, реально делается все достаточно легко. Особенно если учесть что они очень дешевые. А в С++/Java/... нужно прилагать усилия, чтобы гарантировать транзакционность (фактически руками или костылями создавать копии объектов, а в erlang это встроенно в язык, ибо он функционален).

E>Кто будет транзакцию откатывать? В какой момент?

Я не эрланговед , только учусь, но мне пока видиться — один актер — одна транзакция. Т.е. есть некий transaction manager, он собственно стартует эти актеры-транзакции, он же за ними и следит. И самое замечаетельное, что этот manager может быть удаленным.
Re[12]: Ещё одно сравнение с участием Эрланга
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 21.06.07 10:46
Оценка:
Здравствуйте, Курилка, Вы писали:

E>>Теоритически, думается, и в Эрланге возможно. Например, процесс A должен отослать процессу B два сообщения, только при получении второго сообщения у процесса B будет о процессе A целостная информации. После отсылки первого сообщения процесс A умирает по исключению. Если не предпринимать специальных действий в процессе B, то он, не дождавшись второго сообщения от A, будет владеть некорректной информацией.


К>Ну и пусть себе владеет, делов-то

К>Задача может решаться след. образом: есть некий диспетчер приложения B, который ловит сообщения, на каждое полученное Первое создаёт процесс, ведёт список процессов, Второе сообщение пересылает уже созданному процессу, плюс периодически список чекать на "таймаут".
К>Или другой вариант А посылает сообщение, диспетчер создаёт процесс, этот процесс посылает ответ с подтверждением и своим pid, и сам "садится" в receive (с таймаутом), и ждёт там, никому не мешая, пока не сдохнет.



Ага, а после этого говорят, что обеспечение целостности данных в C++ при исключениях -- сложное дело!

Шутка


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[12]: Ещё одно сравнение с участием Эрланга
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 21.06.07 10:53
Оценка:
Здравствуйте, aka50, Вы писали:

E>>Теоритически, думается, и в Эрланге возможно. Например, процесс A должен отослать процессу B два сообщения, только при получении второго сообщения у процесса B будет о процессе A целостная информации. После отсылки первого сообщения процесс A умирает по исключению. Если не предпринимать специальных действий в процессе B, то он, не дождавшись второго сообщения от A, будет владеть некорректной информацией.


A>Перед посылкой можно залинковать себя на таргет процесс и получить уведомление, что процесс сдох. Т.к. нет состояния, то и откатывать ничего не надо (у нас есть начальный объект и есть незавершенный, т.е. мы просто выбросим незавершенный). На актерах да без состояния, Жень, реально делается все достаточно легко. Особенно если учесть что они очень дешевые. А в С++/Java/... нужно прилагать усилия, чтобы гарантировать транзакционность (фактически руками или костылями создавать копии объектов, а в erlang это встроенно в язык, ибо он функционален).


Так я же специально оговорку сделал: если не предпринимать специальных действий. А установить линк на процесс A -- это есть специальное действие.

E>>Кто будет транзакцию откатывать? В какой момент?

A>Я не эрланговед , только учусь, но мне пока видиться — один актер — одна транзакция. Т.е. есть некий transaction manager, он собственно стартует эти актеры-транзакции, он же за ними и следит. И самое замечаетельное, что этот manager может быть удаленным.

Я о другом: например, мне нужно зафиксировать в БД две записи, скажем, снятие денег с одного счета и внесение на другой счет. Пусть транзакцию начинает менеджер, который стартует актера-исполнителя и завершает транзакцию после окончания работы актера исполнителя. Т.е. менеджер условно говоря, владеет туплом {TRX_ID, Pid}, где TRX_ID -- это идентификатор транзакции, а Pid -- актер-исполнитель. Если падает исполнитель, то понятно, что менеджер откатит транзакцию. А если падает сам менеджер?


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[13]: Ещё одно сравнение с участием Эрланга
От: Cyberax Марс  
Дата: 21.06.07 10:58
Оценка:
Здравствуйте, eao197, Вы писали:

E>Я о другом: например, мне нужно зафиксировать в БД две записи, скажем, снятие денег с одного счета и внесение на другой счет. Пусть транзакцию начинает менеджер, который стартует актера-исполнителя и завершает транзакцию после окончания работы актера исполнителя. Т.е. менеджер условно говоря, владеет туплом {TRX_ID, Pid}, где TRX_ID -- это идентификатор транзакции, а Pid -- актер-исполнитель. Если падает исполнитель, то понятно, что менеджер откатит транзакцию. А если падает сам менеджер?

Если оно делается в пределах одной базы — то целостность состояния гарантируется железом (т.е. для последней стадии коммита будут использованы гарантировано атомарные операции).

Если же тут участвуют две базы — то требуется протокол двухфазного коммита. Так чтобы в случае чего можно было перезапустить менеджер транзакций и возобновить все.
Sapienti sat!
Re[12]: Ещё одно сравнение с участием Эрланга
От: Курилка Россия http://kirya.narod.ru/
Дата: 21.06.07 11:14
Оценка:
Здравствуйте, eao197, Вы писали:

[cut]
E>В Erlang-е для этого придется делать что?

Ну как вариант — использовать рекорды (читай сишные структуры).
Re[13]: Ещё одно сравнение с участием Эрланга
От: Курилка Россия http://kirya.narod.ru/
Дата: 21.06.07 11:23
Оценка:
Здравствуйте, eao197, Вы писали:

[cut]

E>Ага, а после этого говорят, что обеспечение целостности данных в C++ при исключениях -- сложное дело!


E>Шутка


А если чуть серьёзней? Моделирование на процессах тебе кажется сильно сложным?
И ещё мысль — в случае такого моделирования ты разделяешь именно участки алгоритма, которые могут "отвалиться", т.е. уделяешь внимание участкам кода.
Тогда как для обеспечения целостности на плюсах, тебе надо рассуждать уже не только об участках кода, но и о самих, данных, как там что клинится и т.п.
Т.е. область в рамках которой надо "ковыряться" однозначно увеличивается.
Хотя, наверное, это итак понятно.
Re[13]: Ещё одно сравнение с участием Эрланга
От: aka50 Россия  
Дата: 21.06.07 11:23
Оценка:
Здравствуйте, eao197, Вы писали:

E>Здравствуйте, aka50, Вы писали:


E>Так я же специально оговорку сделал: если не предпринимать специальных действий. А установить линк на процесс A -- это есть специальное действие.

Это может входить в API менеджера транзакций или процессов.

E>Если падает исполнитель, то понятно, что менеджер откатит транзакцию. А если падает сам менеджер?

Ну в данном случае можно так же спросить: а если упадет серверная ось?
Если серьезно, то варианта 2:
1. Писать этого менеджера очень аккуратно в exception safe стиле (т.е. отказаться для этого модуля от let it crash)
2. Заиметь мета-менеджера, который пасет любые другие менеджеры и выполянется специальные rollback и рестартует упавших (его правда тоже придется писать как в пп1)
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.