Оберон-технология: особенности и перспективы |
Тематика обсуждения: Оберон-технология. Особенности, перспективы, практическое применение.
Всего в теме 6256 сообщений
Добавить свое сообщение
Отслеживать это обсуждение Обсуждение из раздела Школа ОБЕРОНА
№ 5076 25-08-2007 04:54 | |
Ответ на »сообщение 5075« (Stargazer)
___________________________
Ответ на »сообщение 5073« (Стэн)
___________________________
...
Вопрос в следующем: Какой класс задач требует реальной динамической расширяемости? Т.е. те задачи, в которых нельзя остановить программу, чтобы изменить ее часть.
....
Разработка.
Ага. Изменяем какой-нибудь модуль не верхнего уровня и для загрузки новой версии приходится вручную отслеживать зависимости и по цепочке выгружать использующие его модули...
№ 5075 25-08-2007 02:40 | |
Ответ на »сообщение 5073« (Стэн)
___________________________
...
Вопрос в следующем: Какой класс задач требует реальной динамической расширяемости? Т.е. те задачи, в которых нельзя остановить программу, чтобы изменить ее часть.
....
Разработка.
А как "end-user" я могу задать вполне резонный вопрос - а зачем это программу останавливать? Это наверное, такой шаманский приём... А, вы по-другому не умеете? Ну-ну.
№ 5074 24-08-2007 18:52 | |
Ответ на »сообщение 5072« (Илья Ермаков)
___________________________
и позволяет модулям верхнего уровня и конкретного приложения инсталлировать в нужную точку свой обработчик исключения.
Вот есть подсистема записи DVD. Откуда приходят данные на запись ей все равно (из сети или с перфоленты). Какой обработчик, куда его инсталлировать, и чего в нем делать, чтобы корректно обработать ощибки нижележащих подсистем и не запороть болванку?
При обнаружении проблемы модуль низшего уровня может запросить обработку проблемы у инсталлированного обработчика и только если обработчик не иснталлирован, или восстановление невозможно - тогда модуль обязан сгенерировать треп нарушения инварианта.
Ты мешаешь в кучу ошибки внешнего мира (вполне запланированные) и программные ошибки (незапланированные нарушения инварианта). Все таже проблема отсутствия субтипизации...
№ 5073 24-08-2007 17:26 | |
Недавно, в очередной раз прочитал статью "Секреты модульных систем".
http://oberoncore.ru/index.php?option=com_content&task=view&id=36&Itemid=23
Там есть такая фраза:
Модульные программные системы пришли на смену монолитным программам. Смысл использования модульных систем в отличие от монолитных программ - динамическая расширяемость.
Вопрос в следующем: Какой класс задач требует реальной динамической расширяемости? Т.е. те задачи, в которых нельзя остановить программу, чтобы изменить ее часть. Подавляющее большинство клиентских приложений, которые среднестатистический пользователь использует в офисе и дома прекрасно дружат с перезапуском. Состояние между сеансами сохраняется в файлах или БД.
Теоретическую возможность динамически подключить plug-in'ы (для общего случая) - не предлагать! :-) Так как тотже FireFox позволяет подключать расширения, но при этом требует перезапуска и это не проблема...
№ 5072 23-08-2007 19:45 | |
К вопросу об обработке исключений...
Были у меня некоторые мыслишки по этому поводу... Цитирую "полуфабрикатные" мысли, из переписки.
Как только начинаем работать с сетью, возникает проблема обработки исключений. Если несетевое приложение может считать, что работает в абсолютно надежном окружении и не обязано думать об отказе оборудования и т.п., то тут все не так.
Что мы имеем в Обероне - как это мы всегда и пропагандировали, непосредственно отрабатывать "исключения" в логике кода и возвращаемых параметрах, а исключения несоблюдения контракта взаимодействия "рубить" на ASSERT-ах-предусловиях.
Однако здесь я вижу несколько иную проблему.
Существует интерфейс верхнего уровня - распределенное объектное взаимодействие и т.п. Интерфейс этого уровня должен выглядеть как абсолютно надежный, т.е. глупо протаскивать через все слои OUT ok: BOOLEAN об успехе или неуспехе коннекта с удаленным сервером. Однако получаем, что на несколько слоев ниже скрывается ненадежная сетевая среда, в которой вполне возможен отказ. При этом сценарий обработки этого отказа не может быть зашит прямо в логике кода нижнего уровня, это решение должно приниматься гораздо выше, более того, оно зависит от конкретного приложения и должно быть конфигурируемым под конкретную задачу. Таким образом, в коде нижнего уровня можно только и сделать, что вставить ASSERT о нарушении инварианта, т.е. "черный ящик" с абсолютно надежным интерфейсом в случае сбоя выбрасывает треп о том, что он не может обеспечить контракт, и дальнейшая работа невозможна. Тут-то я сначала и задумался о классической модели try-except, а затем вышел из положения другим образом.
Модуль, который может "генерировать исключения", определяет некоторый абстрактный тип, например:
NetErrorFixer = POINTER TO ABSTRACT RECORD
(f: NetErrorFixer) OnIntertactError (srv: RemoteServer; VAR s: NetStreams.Stream; OUT ok: BOOLEAN; OUT redirect: RemoteServer), NEW, ABSTRACT;
(f: NetErrorFixer) OnLinkBreak (srv: RemoteServer; VAR s: NetStreams.Stream; OUT ok: BOOLEAN; OUT redirect: RemoteServer), NEW, ABSTRACT;
(f: NetErrorFixer) OnNotResponse (srv: RemoteServer; VAR s: NetStreams.Stream; OUT ok: BOOLEAN; OUT redirect: RemoteServer), NEW, ABSTRACT
END,
и позволяет модулям верхнего уровня и конкретного приложения инсталлировать в нужную точку свой обработчик исключения. При обнаружении проблемы модуль низшего уровня может запросить обработку проблемы у инсталлированного обработчика и только если обработчик не иснталлирован, или восстановление невозможно - тогда модуль обязан сгенерировать треп нарушения инварианта.
Такой подход, как мне кажется, обладает преимуществами перед try-except - во-первых, разработчик строго фиксирует в интерфейсе типа обработчика параметры проблемы и те сценарии, которые может предпринять обработчик; во-вторых, принятие решения о том или ином поведении в случае ошибки выполняет не перехватчик верхнего уровня, а непосредсвенно код в точке проблемы, на верхний уровень всего лишь делегируется восстановление целостного состояния каких-либо проблемных объектов; в-третьих, в отличие от try-except подход явных делегатов-обработчиков способствует думанию головой, а не клепанию "глотателей ошибок". Try, на мой взгляд, должен существовать только в виде низкоуровневой процедуры, которая позволяет создать "песочницу" для выполнения какого-либо кода, который может вызвать трепы - как при выполнении команд в Оберонах, но не как средство, используемое на всех уровнях приложения.
№ 5071 23-08-2007 19:42 | |
Ответ на »сообщение 5068« (Стэн)
___________________________
Ответ на »сообщение 5066« (Илья Ермаков)
___________________________
Официальной статьи по поводу доказательства невозможности гарантировать отсутствие "повисших указателей" и "утечек памяти" еще нет? Для того, чтобы можно было сослаться в дальнейших исследованиях...
Да это вообще отнюдь не первооткрытие, в общем-то, факт известный давно... Просто для масс сей факт остался за бортом... Отсюда и "кухонные разговоры" типа "вот, там сборщик мусора... ацццтой... тармаза... для ламеров...".
По поводу ссылки на мою статью - я её как раз сегодня "пришвартовал" у нас в энциклопедии:
http://wiki.oberoncore.ru/index.php/Безопасное_управление_памятью
№ 5070 23-08-2007 19:38 | |
Ответ на »сообщение 5069« (Стэн)
___________________________
Ответ на »сообщение 5067« (Илья Ермаков)
___________________________
Вот этот вопрос мне постоянно не дает покоя. Вот появляется данное исключение. Объект не разрушился - это хорошо. Но программа-то не работает как должна! Что в этом случае делать: останавливать программу и переписывать, или есть другие варианты? Может быть какой-нибудь способ динамической адаптации?
А существует ли здесь вообще общее решение?
Сценарий обработки отказов должен вырабатываться для конкретной системы... И только обобщая опыт, можно будет потом выстроить какую-то систему рекомендаций.
Но для того, чтобы развивать эту тему, нужно в первую очередь перестать понимать исключение как "возврат результата ошибки через раскрутку стека", что ныне можно использовать сплошь и рядом. Даже, я бы сказал, первый шаг для обработки исключений - не иметь стандартных средств для этого в языке :-) А уже потом начать думать, что там можно ввести на более высоком уровне, на уровне сценариев динамической адаптации системы....
№ 5069 23-08-2007 18:08 | |
Ответ на »сообщение 5067« (Илья Ермаков)
___________________________
>>> Но вот соблюсти инвариант 1 вполне возможно - если гарантировать, что обращение по висячей ссылки ни при каких условиях не вызовет разрушения другого объекта, а только исключение.
Вот этот вопрос мне постоянно не дает покоя. Вот появляется данное исключение. Объект не разрушился - это хорошо. Но программа-то не работает как должна! Что в этом случае делать: останавливать программу и переписывать, или есть другие варианты? Может быть какой-нибудь способ динамической адаптации?
№ 5068 23-08-2007 18:01 | |
Ответ на »сообщение 5066« (Илья Ермаков)
___________________________
Вот это, на мой взгляд, очень важное утверждение:
При наличии в языке операции явного удаления динамического объекта гарантировать средствами языка или системы времени выполнения отсутствие "повисших указателей" и "утечек памяти" невозможно.
На ядерном уровне - это проблема, с которой, похоже, прийдется мириться... Однако на то оно и ядро, чтобы быть компактным и постоянным. Все алгоритмы ручного удаления можно проверить на правильность.
А вот все что выше, пользовательский уровень, где все меняется по сто раз на дню, должно быть избавлено от подобных проблем...
Официальной статьи по поводу доказательства невозможности гарантировать отсутствие "повисших указателей" и "утечек памяти" еще нет? Для того, чтобы можно было сослаться в дальнейших исследованиях...
№ 5067 23-08-2007 14:34 | |
Однако, Вы удивитесь, но сие формальное расследование я проводил не для обоснования необходимости сборки мусора (что и так было давно обосновано), а для обоснования того, как без нарушения безопасности без неё можно обходиться :-)
Это может быть нужно, если работа идёт на более низком уровне системы, ещё до того, как реализован сборщик мусора. Это может быть нужно, если требуется полная детерминированность моментов освобождения ресурсов.
И тогда не стоит зацикливаться на сборке мусора. Лучше вернуться к ручному освобождению ресурсов, правильно планируя ответственность в системе...
Инвариант 2, заявленный в пред. сообщении, мы соблюсти не сможем (утечки памяти возможны). Но вот соблюсти инвариант 1 вполне возможно - если гарантировать, что обращение по висячей ссылки ни при каких условиях не вызовет разрушения другого объекта, а только исключение.
Для этого достаточно принять, что указатель - это не просто адрес, а дескриптор, который несёт ещё и метку об объекте. И если объект уже не тот, то - исключение... При этом появляется один уровень косвенности (таблица разыменования дескрипторов), но ради надёжности с этим можно мириться. Тем более при наличии инлайна (в Блэкбоксе, кстати, инлайн на машиннокодные процедуры есть, даже и межмодульный).
Добавить свое сообщение
Отслеживать это обсуждение
Дополнительная навигация: |
|