Re[13]: Замена кода "на лету"
От: Aen Sidhe Россия Просто блог
Дата: 18.06.09 17:28
Оценка:
Здравствуйте, Cyberax, Вы писали:

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


C>>>Разница с С# тут будет в чисто процессуальных вопросах.

IT>>Т.е. замена кода на лету возможна не только в Эрланге, а практически везде. Почему же тогда считается, что эта фича есть только в нём?
C>Потому, что в Эрланге она намного мощнее. Тут я это уже объяснял.

оффтопный вопрос про Erlang. Чисто академический интерес.
Есть метод:
void M()
{
  a = 1;
  b = 2; {x}
  c = a + b; {y}
}


Предположим, что у нас выполняется код в точке {x} и в этот момент (до начала выполнения {y}) мы подменяем код на

void M()
{
  a = 1;
  b = 2; 
  c = a - b;
}


Чему равно c?

А если подменить на вот такой код:
void M()
{
  d = "abc";
  b = "def"; {x}
  c = a + b; {y}
}


Чему тут будет равно с? (для упрощения представим, что вместо + для строк мы написали валидную по синтаксису Эрланга конкатенацию строк, с числами же — обычные арифметические операции с 32битными числами).
С уважением, Анатолий Попов.
ICQ: 995-908
Re[14]: Замена кода "на лету"
От: Aen Sidhe Россия Просто блог
Дата: 18.06.09 17:30
Оценка:
Здравствуйте, Aen Sidhe, Вы писали:

Следует читать так:

AS>
AS>void M()
AS>{
AS>  d = "abc";
AS>  b = "def"; {x}
AS>  c = d + b; {y}
AS>}
AS>
С уважением, Анатолий Попов.
ICQ: 995-908
Re[14]: Замена кода "на лету"
От: Курилка Россия http://kirya.narod.ru/
Дата: 18.06.09 17:35
Оценка: 4 (1)
Здравствуйте, Aen Sidhe, Вы писали:

AS>оффтопный вопрос про Erlang. Чисто академический интерес.

[cut]

AS>Чему тут будет равно с? (для упрощения представим, что вместо + для строк мы написали валидную по синтаксису Эрланга конкатенацию строк, с числами же — обычные арифметические операции с 32битными числами).


Единицей гранулярности замены является модуль, единицей "переключения" является функция (плюс ещё есть "ньюанс", что должно быть написано полное имя module:function(...)), поэтому описываемая тобой ситуация произойти не может. Т.е. программист (если он понимает эрланг) знает, где именно может быть "переключение версии" (с этой же целью можно использовать "внутренние вызовы", если логика, которая может быть переключена не умещается в 1 функцию).
Re[15]: Замена кода "на лету"
От: Курилка Россия http://kirya.narod.ru/
Дата: 18.06.09 17:41
Оценка:
Здравствуйте, Курилка, Вы писали:

К>Единицей гранулярности замены является модуль, единицей "переключения" является функция (плюс ещё есть "ньюанс", что должно быть написано полное имя module:function(...)), поэтому описываемая тобой ситуация произойти не может. Т.е. программист (если он понимает эрланг) знает, где именно может быть "переключение версии" (с этой же целью можно использовать "внутренние вызовы", если логика, которая может быть переключена не умещается в 1 функцию).


И ещё функция это единица переключения контекста планировщика, точней выполнение функции называется редукцией и процессы переключаются по-моему через 100 редукций. А загрузка кода — это же тоже будет процесс, насколько я понимаю. Поэтому "вклиниться" в выполнение функции (как это делает планировщик ОС) по-моему нельзя стандартными средствами.
Re[15]: Замена кода "на лету"
От: Aen Sidhe Россия Просто блог
Дата: 18.06.09 18:00
Оценка:
Здравствуйте, Курилка, Вы писали:

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


AS>>оффтопный вопрос про Erlang. Чисто академический интерес.

К>[cut]

AS>>Чему тут будет равно с? (для упрощения представим, что вместо + для строк мы написали валидную по синтаксису Эрланга конкатенацию строк, с числами же — обычные арифметические операции с 32битными числами).


К>Единицей гранулярности замены является модуль, единицей "переключения" является функция (плюс ещё есть "ньюанс", что должно быть написано полное имя module:function(...)), поэтому описываемая тобой ситуация произойти не может. Т.е. программист (если он понимает эрланг) знает, где именно может быть "переключение версии" (с этой же целью можно использовать "внутренние вызовы", если логика, которая может быть переключена не умещается в 1 функцию).


Большое спасибо за разъяснение, теперь всё понятно.
С уважением, Анатолий Попов.
ICQ: 995-908
Re[14]: Замена кода "на лету"
От: Cyberax Марс  
Дата: 18.06.09 18:01
Оценка:
Здравствуйте, Aen Sidhe, Вы писали:

AS>Чему тут будет равно с? (для упрощения представим, что вместо + для строк мы написали валидную по синтаксису Эрланга конкатенацию строк, с числами же — обычные арифметические операции с 32битными числами).

Подмена осуществляется в чётко определённых местах.
Sapienti sat!
Re[13]: Замена кода "на лету"
От: IT Россия linq2db.com
Дата: 18.06.09 20:30
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>Потому, что в Эрланге она намного мощнее. Тут я это уже объяснял.


Мощнее понятие недетерминированное.
Если нам не помогут, то мы тоже никого не пощадим.
Re[14]: Замена кода "на лету"
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 19.06.09 06:04
Оценка: 183 (7)
Здравствуйте, IT, Вы писали:

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


C>>Потому, что в Эрланге она намного мощнее. Тут я это уже объяснял.


IT>Мощнее понятие недетерминированное.


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

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

(Я использовал тут для ясности понятия "клиент" и "соединение". Но этот подход можно использовать и там, где таких понятий нет или они называются иначе — как, например, процесс и открытый файл на FS, если нужно обновить драйвер FS. Основной момент в тех условиях, которые в принципе требуют формулировки понятия "на лету". Если работа с чем-то идёт по методу "открыл-чихнул-закрыл", тривиально организовать момент, когда ничего не "открыто" — и вопрос о замене на лету не стоит.)

2. Возможности самого процесса перехода — как он реализован, насколько гладко и просто выглядит сам процесс перехода со всеми необходимыми действиями (в первую очередь конверсию данных существующих соединений в форму, которая необходима для новой версии).

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

1. Позволяет провести замену кода максимально быстро и прозрачно для приложения, незаметно для всех существующих соединений. На момент отработки запроса о запуске нового кода, со старым кодом будут работать только те процессы, которые уже с ним начали отрабатывать одно входное сообщение. При рекомендованной организации кода (по стандартам OTP) это доли секунды, в худшем случае единицы секунд (если отработка сообщения требует синхронного вызова чего-то длительного внешнего).
2. Содержит средства организации апгрейда (называемые relup), автоматизирующие выполнение этого процесса для широкого набора случаев.

Python'овая реализация:

1. Позволяет провести замену кода максимально быстро и прозрачно для приложения, незаметно для всех существующих соединений — но для этого требуется организация выполнения в уже известном стиле Erlang'а: чтобы один и тот же код для одного соединения выполнялся или отработкой целевых действий, или апгрейдом, но не одновременно. Иначе, возможности другие, но тоже симпатичные — можно существующие соединения отрабатывать старым кодом сколь угодно долго (и вручную разбираться с последствиями такой организации;))
2. Автоматизации апгрейда нет, надо организовывать свой закат солнца вручную именно для данного приложения.

А теперь если сравнить, например, с Java (сразу дисклеймер — все мои знания про эти её возможности только по документации) — организация кода в виде именованных классов с глобально уникальными именами (причём фиксированными в момент компиляции кода) резко усложняет возможность замены кода на лету, ибо существование двух одноимённых классов невозможно — а, значит, замена потребует
1) сохранения всех данных, хранимых в объектах этих классов, в некотором внешнем (для них) хранилище (в памяти, чтобы сохранить всякие открытые файлы)
2) собственно фазы перезагрузки кода
3) восстановления состояния из хранилища

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

Насколько я знаю, в .NET точно так же. Если ошибаюсь — исправьте, это будет мне полезно в плане оценки, куда двигать систему дальше.

На основании этих примеров можно вывести числовую оценку мощности механизма замены кода. Начнём с того, что отсутствие такой возможности оценим в 0 баллов:) Далее, возможность сосуществования старого и нового кода штатными средствами языка/среды ,оценим в 50 баллов, возможность поддержки более двух версий — в 60 баллов для языков с организацией на сообщениях и 70 — на общей памяти. (Это, конечно, грубо, потому что на сообщениях можно писать на всех;)) Стандартную поддержку замены кода соответствующим библиотечным кодом оценим в зависимости от мощности этой поддержки — до 50 баллов (Эрланговая примитивна и недостаточна для случаев конверсии межпроцессной логики, но более простые случаи исполняет "на ура", дадим 30.)

Итого: Erlang — 80 баллов. Python — 70. Java (JVM) — 10. .NET — 10. По остальным — пусть расставляют те, кто их достаточно знает и может оценить.

Достаточно это для детерминации понятия мощности данной возможности? ;)
The God is real, unless declared integer.
Re[15]: Замена кода "на лету"
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 19.06.09 07:06
Оценка:
Здравствуйте, netch80, Вы писали:

N>А теперь если сравнить, например, с Java (сразу дисклеймер — все мои знания про эти её возможности только по документации) — организация кода в виде именованных классов с глобально уникальными именами (причём фиксированными в момент компиляции кода) резко усложняет возможность замены кода на лету, ибо существование двух одноимённых классов невозможно — а, значит, замена потребует

N>1) сохранения всех данных, хранимых в объектах этих классов, в некотором внешнем (для них) хранилище (в памяти, чтобы сохранить всякие открытые файлы)
N>2) собственно фазы перезагрузки кода
N>3) восстановления состояния из хранилища

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


N>Насколько я знаю, в .NET точно так же. Если ошибаюсь — исправьте, это будет мне полезно в плане оценки, куда двигать систему дальше.


В .NET несколько другой механизм.
Единица загрузки в .NET — сборка, единица выгрузки — домен. В один домен может быть загружено несколько сборок с одинаковыми именами (если они не strongname). Кроме того есть механизм shadowcopy, который позволяет не лочить образ на диске при заргрузке кода (это обегчает деплой нового кода).

Теперь как выглядит процесс.
1)Содается новый домен, туда грузится код, с которым идет взаимодействие через IPC, если появился новый код (даже в сборке с тем же именем), то он спокойно грузится в домен и новые запросы запускаются на него, сатрый код при этом никуда не девается и клиенты продолжают работать с ним.
2)Создается счетчик загрузок для домена, когда он достигает определенного числа новые сбокри перестают грузиться в домен и создается новый домен для загрузки новых сборок.
3)Каждый домен внутри себя считает количество клиентов, так как через IPC не поддерживаются механизмы управления временем жизни. Когда домен закрыт и нету клиентов, то он выгружается.

Естественно реализацию этого всего надо делать ручками, а сложность там немаленькая.

Что касается джавы, то там тоже все не так однозначно, как написано выше. Там есть класслоадеры, которые управляют загрузкой, так вот каждый класслоадер может загрузить свою копию класса.
Re[15]: Замена кода "на лету"
От: IT Россия linq2db.com
Дата: 19.06.09 13:22
Оценка:
Здравствуйте, netch80, Вы писали:

N>Достаточно это для детерминации понятия мощности данной возможности?


Совсем другое дело.

Один вопрос. Что будет с Эрлангом, если у нового кода меняется контракт, например, изменлилось количество параметров у вызываемой функции?
Если нам не помогут, то мы тоже никого не пощадим.
Re[16]: Замена кода "на лету"
От: Курилка Россия http://kirya.narod.ru/
Дата: 19.06.09 14:04
Оценка: +1
Здравствуйте, IT, Вы писали:

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


N>>Достаточно это для детерминации понятия мощности данной возможности?


IT>Совсем другое дело.


IT>Один вопрос. Что будет с Эрлангом, если у нового кода меняется контракт, например, изменлилось количество параметров у вызываемой функции?


Это будет уже другая функция, т.е. или разработчик предусмотрит такой вариант (добавит некий "переходник") или код "отвалится".
Сколь бы не были мощны возможности какой-либо платформы потребность думать, прежде чем делать, не отменяется
Re[17]: Замена кода "на лету"
От: IT Россия linq2db.com
Дата: 19.06.09 14:06
Оценка:
Здравствуйте, Курилка, Вы писали:

К>Сколь бы не были мощны возможности какой-либо платформы потребность думать, прежде чем делать, не отменяется


Т.е. без чудес. Ну и славненько.
Если нам не помогут, то мы тоже никого не пощадим.
Re[18]: Замена кода "на лету"
От: Курилка Россия http://kirya.narod.ru/
Дата: 19.06.09 14:12
Оценка:
Здравствуйте, IT, Вы писали:

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


К>>Сколь бы не были мощны возможности какой-либо платформы потребность думать, прежде чем делать, не отменяется


IT>Т.е. без чудес. Ну и славненько.


Ты ожидал увидеть внутри вечный двигатель?
Re[15]: Замена кода "на лету"
От: Cyberax Марс  
Дата: 19.06.09 14:18
Оценка:
Здравствуйте, netch80, Вы писали:

N>А теперь если сравнить, например, с Java (сразу дисклеймер — все мои знания про эти её возможности только по документации) — организация кода в виде именованных классов с глобально уникальными именами (причём фиксированными в момент компиляции кода) резко усложняет возможность замены кода на лету, ибо существование двух одноимённых классов невозможно

Возможна, если другой одноимённый класс будет в другой ветке дерева ClassLoader'ов. Но по сути это для приложения анлогично "загрузить другую DLL".
Sapienti sat!
Re[19]: Замена кода "на лету"
От: IT Россия linq2db.com
Дата: 19.06.09 15:15
Оценка: :)
Здравствуйте, Курилка, Вы писали:

IT>>Т.е. без чудес. Ну и славненько.


К>Ты ожидал увидеть внутри вечный двигатель?


Скорее ответ на главный вопрос жизни, вселенной и всего такого
Если нам не помогут, то мы тоже никого не пощадим.
Re[16]: Замена кода "на лету"
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 20.06.09 08:10
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>В .NET несколько другой механизм.


[...]

Спасибо. Исправлю тогда цифровую оценку из предыдущего сообщения так: .NET — 35 (пока не видно ни одного средства нормальной автоматизации), JVM — 15. Всё это, конечно, на глаз и наугад (плюс/минус 10 от направления ветра), но для первичной прикидки сойдёт.

G>Единица загрузки в .NET — сборка, единица выгрузки — домен.


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

G>Естественно реализацию этого всего надо делать ручками, а сложность там немаленькая.


Угу.
The God is real, unless declared integer.
Re[16]: Замена кода "на лету"
От: Sinclair Россия https://github.com/evilguest/
Дата: 22.06.09 10:52
Оценка:
Здравствуйте, Cyberax, Вы писали:
C>Возможна, если другой одноимённый класс будет в другой ветке дерева ClassLoader'ов. Но по сути это для приложения анлогично "загрузить другую DLL".
1. Гранулярность несколько другая. Хотя, чисто теоретически, никто не запрещает размещать каждый метод в отдельной либе.
2. В "классическом" неуправляемом приложении данные существуют совершенно отдельно от кода. Это означает, что можно поменять DLL, и следующий вызов DoSomeProcessing(&myOldData) пойдёт в новый код. В Java инстанс объекта жестко связан с классом; выгрузить класс, для которого есть достижимые экземпляры, афаик, нельзя. Это не проблема для stateless-приложений, но для стейтфул это тупик: сколько нового кода ни грузи, существующие объекты будут по-прежнему процесситься старым.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[17]: Замена кода "на лету"
От: Cyberax Марс  
Дата: 22.06.09 11:08
Оценка:
Здравствуйте, Sinclair, Вы писали:

C>>Возможна, если другой одноимённый класс будет в другой ветке дерева ClassLoader'ов. Но по сути это для приложения анлогично "загрузить другую DLL".

S>1. Гранулярность несколько другая. Хотя, чисто теоретически, никто не запрещает размещать каждый метод в отдельной либе.
Гранулярность примерно одинаковая. Т.е. непрактично для большинства случаев.

S>2. В "классическом" неуправляемом приложении данные существуют совершенно отдельно от кода. Это означает, что можно поменять DLL, и следующий вызов DoSomeProcessing(&myOldData) пойдёт в новый код.

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

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

S>В Java инстанс объекта жестко связан с классом; выгрузить класс, для которого есть достижимые экземпляры, афаик, нельзя. Это не проблема для stateless-приложений, но для стейтфул это тупик: сколько нового кода ни грузи, существующие объекты будут по-прежнему процесситься старым.

Да, я про это и говорю.
Sapienti sat!
Re[18]: Замена кода "на лету"
От: Sinclair Россия https://github.com/evilguest/
Дата: 22.06.09 11:26
Оценка:
Здравствуйте, Cyberax, Вы писали:
C>Гранулярность примерно одинаковая. Т.е. непрактично для большинства случаев.
В каком-то смысле да. Там, где динамические класслоадеры используются в полный рост — в вебприложениях — ничуть не хуже себя ведут и ISAPI.

C>Обычный паттерн для перегружаемых unmanaged-приложений — это экспорт функциональности из библиотеки через абстрактные классы (или их аналог), так что тут особой разницы с Java нет.

Есть. Абстрактный класс — это структура VMT; его реализация — состав VMT. Подменив библиотеку, мы получим при myOldObject.VirtualMethod() вызов нового кода — из-за того, что указатель на VMT теперь указывает куда надо. Ну, то есть это как я понимаю смысл вопроса — на практике такое я не применял никогда; обычно плагинные неуправляемые приложения всё же убивают экземпляры при перезагрузке плагинов.

C>Да, я про это и говорю.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[19]: Замена кода "на лету"
От: Cyberax Марс  
Дата: 22.06.09 11:30
Оценка:
Здравствуйте, Sinclair, Вы писали:

C>>Гранулярность примерно одинаковая. Т.е. непрактично для большинства случаев.

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

C>>Обычный паттерн для перегружаемых unmanaged-приложений — это экспорт функциональности из библиотеки через абстрактные классы (или их аналог), так что тут особой разницы с Java нет.

S>Есть. Абстрактный класс — это структура VMT; его реализация — состав VMT. Подменив библиотеку, мы получим при myOldObject.VirtualMethod() вызов нового кода — из-за того, что указатель на VMT теперь указывает куда надо.
Ты что? Ссылка на VMT сохраняется в каждом объекте, при загрузке новой библиотеки новые объекты будут получать ссылку на новую VMT, а старые так и будут со старой таблицей работать.

S>Ну, то есть это как я понимаю смысл вопроса — на практике такое я не применял никогда; обычно плагинные неуправляемые приложения всё же убивают экземпляры при перезагрузке плагинов.

Не обязательно.
Sapienti sat!
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.