![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| drug007 |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 196 Регистрация: 3.11.2011 Репутация: нет Всего: 1 |
В разработке я придерживаюсь принципа "живой клетки" - она всячески сопротивляется попыткам нанести ей вред снаружи, но сразу же умирает, если что-то сломалось внутри нее. Так же и код - всячески сопротивляется попыткам сломать его например путем передачи неверных аргументов, но если внутри кода возникло недопустимое состояние, то с помощью ассерта падаем тут же (с логированием и прочим, конечно же). Это полезно, потому что заставляет устранять ошибку, а не маскировать ее.
Но это работает если десктопное приложение, например. А если демон у нас - просто падать нельзя, нужно обязательно восстанавливаться. Некоторые приложения можно в скрипте перезапускать при падании, но это не общее решение. Может кто поделиться инфой, как работают с ошибками в критическом коде? |
|||
|
||||
| konshyn |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 295 Регистрация: 19.9.2013 Репутация: нет Всего: нет |
Я в своем демоне использую модель следящего процесса. У меня запускается два процесса: один - с основной логикой, второй - следит за первым, и если что-то случается, чего не должно было случиться и привело к краху демона, то он попросту перезапускается (считанные миллисекунды).
Но такая модель хороша только тогда, когда настройка программы происходит считанные доли секунды и не хранится критическая или, хотя бы, нужная информация, которая не должна теряться. В принципе, защититься от таких ошибок, как stack overflow, segmentation fault невозможно, поэтому за все внутренние состояния отвечает программист. Поэтому такая модель, как у меня, для восстановления после падения вполне подходит. Но есть одно НО: у меня тоже есть важная информация, которую собирает мой сервис. Я просто эту информацию скидываю через каждый интервал времени на диск; этот интервал составляет 10 секунд, поэтому если вдруг случится крах программы, максимальная потеря данных составит 10 секунд. Для меня это приемлемо. Вообще, полностью отказоустойчивую систему создать нельзя. Нужно изучать обрабатыванные данные и соответственно данным допускать какие-то риски и строить соответствующую модель. До этого делал анализатор данных. Данных было много. Данные хранились в одном файле, результат в другом. Обрабатывал все данные по порциям и ставил после каждой обработанной порции отметку в третий файл. Сервис сам по себе не должен был упасть, т.к. данные были надежные. Но бывают и в таких ситуациях ошибки, и могло электричество выключиться. А обрабатывать данные заново - накладно и неприемлемо было для данной задачи. Когда тестировал, работало вполне сносно, но на продакшене не пригодилось, т.к. не было ни падений, ни внезапных выключений. Это сообщение отредактировал(а) konshyn - 14.1.2015, 13:36 -------------------- «Потому что ценность акта действия в этой стране возрастает в несколько раз». |
|||
|
||||
| drug007 |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 196 Регистрация: 3.11.2011 Репутация: нет Всего: 1 |
Полностью согласен с вашим подходом. Но у меня вопрос более низкоуровневый и сводится к тому, что я обычно использую ассерты для вылавливания недопустимых ситуаций. Это вынуждает меня исправлять нарушения в логике приложения сразу же. Но выловить их все сразу и исключить их возникновения в будущем нельзя. Если я оставлю ассерты в боевом коде, то он может упасть у пользователя, который не любит таких заморочек очень сильно, это недопустимо вообще. С другой стороны, убирать их в конечной версии приведет к тому, что невыловленная ошибка в логике может привести к тому, что все будет работать неправильно, а пользователю это нравится не больше, чем когда приложение падает. Остается в боевом коде ассерты заменять на логирование и не факт что в логах потом не придется долго разбираться восстанавливая историю, но хоть что-то. Возможно есть какие-то более красивые решения.
Второй момент с перезапуском - если причина падения не изменилась между перезапусками, то можно и в цикл попасть. Опять же я согласен что полностью надежно сделать нельзя. Просто хотелось бы ознакомиться с другими соображениями на эту тему. |
|||
|
||||
| baldina |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 32 Всего: 101 |
||||
|
||||
| drug007 |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 196 Регистрация: 3.11.2011 Репутация: нет Всего: 1 |
Если обнаружено нарушение логики, то исправить это невозможно без изменения кода, т.е. перехватывать такое исключение нет никакого смысла, а необработанное исключение тот же ассерт. Так что разницы не вижу. Тут даже не важно ассерты или исключения - это лишь механизм реализации контрактов в той или иной форме. Т.е. вопрос можно перефразировать так - оставлять ли контракты в боевом коде и если оставлять то в каком виде? |
|||
|
||||
| baldina |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 32 Всего: 101 |
то ничго не остается как сообщить пользователю и убиться. но исключение позволяет обработать эту ситуацию более удобным способом. к тому же многое зависит от архитектуры приложения: например если демон имеет несколько потоков для обработки запросов, то при крахе потока логично убивать поток а не всего демона. |
|||
|
||||
| drug007 |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 196 Регистрация: 3.11.2011 Репутация: нет Всего: 1 |
Вот ключевой момент - в сложных системах, где есть множество разных модулей с независимой логикой, но которые взаимодействуют между собой, может возникнуть нарушение логики в одном из таких модулей и этот модуль должен прекратить работу. Значит код с единой логикой должен выделяться в отдельный модуль, а модули в свою очередь должны быть отдельными процессами, чтобы они могли упасть не ломая остальных? Насколько я помню, крах потока не гарантирует что процесс остается в корректном состоянии? Ведь как минимум потоки автоматически расшаривают память процесса, по крайней мере в си и плюсах. И независимость потоков несравнима с независимостью процессов. |
|||
|
||||
| baldina |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 32 Всего: 101 |
если вы поймали исключение (равно как и сработал assert), то крах еще только собирается. дальше все зависит от логики вашего приложения. например в хроме сбой на одной закладке не влияет на другие. Это сообщение отредактировал(а) baldina - 14.1.2015, 23:05 |
|||
|
||||
| drug007 |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 196 Регистрация: 3.11.2011 Репутация: нет Всего: 1 |
Вот это принципиальный момент. Я исхожу из того, что есть ошибки и есть баги, скажем так. Если в функцию, которая делит на ноль, передается аргумент ноль - это ошибка, ее можно избежать предварительной проверкой аргументов. И если мы передадим другой аргумент, отличный от нуля все будет работать. А вот если в эту функцию передали верное число, но тем не менее в ходе ее выполнения делитель становится равным нулю - это баг в логике фукнции, исправить баг можно только переписыванием кода и нет никакой гарантии что в следующий вызов с другими аргументами вернет корректный результат. В случае ошибки к моменту выбрасывания исключения краха нет, а в случае бага крах уже произошел. Я как раз речь веду о второй ситуации. |
|||
|
||||
| konshyn |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 295 Регистрация: 19.9.2013 Репутация: нет Всего: нет |
Я так понимаю, вы хотите разработать систему оповещения, которая отслеживает Ваши же баги? -------------------- «Потому что ценность акта действия в этой стране возрастает в несколько раз». |
|||
|
||||
| drug007 |
|
||||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 196 Регистрация: 3.11.2011 Репутация: нет Всего: 1 |
У меня есть некий код:
При этом по логике я точно знаю, что x никогда не должна быть больше 1000, если y > 500. Тогда я добавляю ассерт:
в таком случае, если вдруг переменая x приняла недопустимое значение, значит была нарушена логика приложения и гарантировать корректное его состояния невозможно, поэтому я падаю в ассерте. Эта техника позволяет вылавливать (некоторые) баги быстрее, более того, она заставляет их устранять как можно быстрее, но назвать это системой оповещения я бы не смог. То есть у меня есть некие инварианты, я их проверяю в необходимых местах и падаю, когда они нарушены. Собственно вопрос в том, что в приложении с круглосуточным аптаймом падать не желательно. Вот и интересуюсь, каким образом можно решить этот вопрос. Т.е. у меня конфликт - с одной стороны, я хочу сразу явно падать в случае потери гарантий корректности приложения, чтобы а) не обманывать пользователя, б) вынудить разработчика сразу устранить проблему, а не маскировать ее. Но при этом у меня есть задача по максимуму поддерживать приложение в работоспособном состоянии. В какой-то степени это философский вопрос, но с некоторых пор он приобрел конкретное практическое значение с выражением в рублях/часах/командировках и так далее. Это сообщение отредактировал(а) drug007 - 15.1.2015, 16:46 |
||||||
|
|||||||
| konshyn |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 295 Регистрация: 19.9.2013 Репутация: нет Всего: нет |
Значит я правильно понял: Вам нужна система оповещения Ваших же багов и, если возможно, их устранение. ИИ Вам в помощь. Если серьезно - то, что Вы описали, - это ошибки программиста. И ассерты именно для этого и предназначены, чтобы в разрабатываемом коде отслеживать ошибки логики. Оставлять их на продакшене не нужно, как по мне. Исключения помогают оповестить пользователя об ошибке, этого достаточо. Если есть подозрение, что это, например, ошибка логики, то можно пропустить выполнение какой-нибудь функции и попровать снова, когда она снова будет вызвана - конечно, если это все некритично. Все ошибки логики должны находиться во время тестирования. Если приложение ОЧЕНЬ критическое, как, например, авиационное/медицинское/т.д., то тестировать нужно очень тщательно и кропотливо. Добавлено через 7 минут и 22 секунды И опять же, зависит от ситуации: если произошел сбой логики в системе торможения автомобиля, то лучше как можно быстрее попробовать снова затормозить, чем "оповестить" пользователя. А если это, к примеру, медицинское оборудование (ссылка на сбой ПО ренгеновского аппарата), то лучше закончить работу и оповестить пользователя, если это возможно - понять, что произошла ошибка. Добавлено через 7 минут и 55 секунд И в первом и во втором случаях ПО должно работать все время. Добавлено через 12 минут и 31 секунду Из ссылки какие методы были применены:
-------------------- «Потому что ценность акта действия в этой стране возрастает в несколько раз». |
|||
|
||||
| drug007 |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 196 Регистрация: 3.11.2011 Репутация: нет Всего: 1 |
я наверное, неясно излагаю. речь идет о том, что после отладки мы в релизе убираем ассерты/контракты/инварианты/прочая из кода. потому что считается, что мы все отладили. но на самом деле никто не может гарантировать этого. а значит если будет обнаружен баг при эксплуатации, то в релизе его выловить будет намного сложнее, потому что все диагностические средства мы отключили. вот и вопрос - где золотая середина, что нужно все-таки оставлять в релизе, а что нет. При чем здесь система оповещения о багах, какой ИИ?
konshyn, за ссылку спасибо, полезная штука - есть некоторые рекомендации и их наглядное обоснование. Это сообщение отредактировал(а) drug007 - 16.1.2015, 12:19 |
|||
|
||||
| konshyn |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 295 Регистрация: 19.9.2013 Репутация: нет Всего: нет |
Так необязательно убирать. для этого, например, можно вести отдельный log-файл. Если всяческие проверки не критичны (скорость, размер кода и т.п.), то просто проверять те места, где были ассерты, и если что-то произошло, то бишь ошибка логики, то вывести всю нужную информацию в этот log-файл="для своих нужд", оповестить пользователя или систему об этом и завершить работу. Понятно, что для демона падение может быть очень нежелательным,но для этого можно сделать то, что предлагал выше - отдельный процесс, который будет перезапускать процесс/поток. Проблему это не исправит, но, по крайне мере, ошибка будет залогирована, демон запустится снова и работа будет продолжена. Добавлено через 41 секунду Я понимаю, что Вы хотите сказать. Но мне кажется, что Вы ждете ответа, которого, возможно, и нет (пока что). -------------------- «Потому что ценность акта действия в этой стране возрастает в несколько раз». |
|||
|
||||
| drug007 |
|
||||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 196 Регистрация: 3.11.2011 Репутация: нет Всего: 1 |
Вот у меня такие же мысли
И тут тоже
Вот я и ищу дополнительную информацию по этому поводу. Я далеко не первый кто столкнулся с этим, поэтому хотелось бы узнать что другие думают по этому поводу. Я даже уверен, что на эту тему были научные исследования и есть какие-то методики. Большая часть из них наверняка мусор с красивыми и умными названиями, но среди мусора должен быть и бриллиант. Это сообщение отредактировал(а) drug007 - 16.1.2015, 14:44 |
||||||
|
|||||||
| baldina |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 32 Всего: 101 |
drug007, ответ кроется в вопросе: если недостаток релиза в отсутствии диагностики, её надо добавить (логи).
|
|||
|
||||
| drug007 |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 196 Регистрация: 3.11.2011 Репутация: нет Всего: 1 |
Лучше мне пока на ум ничего и не пришло. Но тут меня смущает то, что когда у тебя приложение упало в ассерте сразу понятно, где искать. А при логировании это уже не так очевидно. Т.е. роль логов резко вырастает, придется их семантику продумывать тщательно - потому что обычно логи ведутся на всякий случай по остаточному принципу... В общем логи либо оставлять в релизе диагностические средства, которые не критичны для приложения (не влияют на скорость или влияют некритично и т.д.). Получается два варианта? |
|||
|
||||
| baldina |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 32 Всего: 101 |
запишите в лог то же самое это не так очевидно. это сильно зависит от задачи (рассмотрите почтовый клиент, почтовый сервер и управление ракетами с ядерными боеголовками). drug007, у вас наверняка имеется в виду какая-то конкретная задача (или класс задач). опишите, и давайте исходить из этого. в любом случае получится компромисс, вопрос в том как расставить приоритеты. |
|||
|
||||
| xvr |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
Мне кажется, что проблема не в наличии или отсутствия логов и/или ответа на вопрос - падать или не падать. Проблема более глобальная - у вас есть проверка/assert (положим что она осталась и в релизе), и есть требование, что бы программа обладала максимальной живучестью, т.е. не падала.
Что делать если assert стработал - правильно функуционировать программа уже не может, но и падать нельзя. И что делать? Проблемы с отказами и сбоями в отвественных приложениях обычно решают дублированием, но в данном случае это не сработает - если ошибка была в программе, то и дубль так же упадет. Тут может помочь только дублирование на уровне функционала, т.е. параллельно работающая фетка с той же функциональностью, но возможно с какими то недостатками (типа недостаточной производительности или большим требованием к ресурсам), что бы при выходе из строя основной ветки ее функции мог подхватить дубль (и не упасть при этом). Конечно дубль должен быть максимально простым и дубовым. Увы не всегда такой можно сделать |
|||
|
||||
| drug007 |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 196 Регистрация: 3.11.2011 Репутация: нет Всего: 1 |
Класс задач простой - улучшить поддержку развернутого приложения, в частности упростить работу с ошибками, обнаруженными в релизе. Банально, у нас нет возможности тестировать на всем оборудовании. Определенная работа проведена по достижению воспроизводимости ошибки, чтобы логи, записанные у пользователя, позволяли однозначно воспроизвести ситуацию у нас. Теперь надо определиться с политикой, как реагировать на ошибки логики - когда мы точно знаем, что логика нарушена, но исправить ее не может. Раньше я просто ронял приложение, но сейчас есть противоречащее требование. Вот и думаю, как и волка накормить, и овец спасти. Да, вы верно описали ситуацию. Получается есть еще третий вариант - дублирующий код. Кстати, в некоторых ситуациях такой подход очень даже обоснован, спасибо за подсказку. |
|||
|
||||
| baldina |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 32 Всего: 101 |
||||
|
||||
| xvr |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
Нашел несколько статьей на эту тему:
http://www.billpetit.com/Papers/Petit019.pdf Присоединённый файл ( Кол-во скачиваний: 3 )
00056848.pdf.zip 555,79 Kb |
|||
|
||||
| xvr |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
||||
|
||||
| xvr |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
||||
|
||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |