LINUX.ORG.RU

Success Exception? WTF?

 , ,


0

0

Здравствуйте мои дорогие, великие программисты, бакалавры и прочие ЛОРовцы включая умнейших анонимусов!

А вот что если я вам скажу следующее:

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

И вот есть код, в котором, где-то в дебрях, при определённых условиях требуется:

а) вывалить сообщение и сделать exit(0);

б) сделать exit(0) без каких либо сообщений вообще.

Приведу простой пример: программа выполняется по крону, и нужно, в случае штатного завершения, не засирать логи кронтаба и не слать емейлы тому, от чьего имени эта программа по крону запускается. Вот тут и пригождается кейс «б» — код завершения есть, а сообщения нет.

К чему это я? А к тому, что можно же использовать для этого исключения. А что? Исключение бросается в исключительной ситуации. Но исключительная ситуация не обязательно ошибка!

И теперь у меня есть «SuccessException(message)» и, конечно, «JustSuccessExit extends SuccessException»

А что вы думаете по этому поводу?

UPD: ПОЖАЛУЙСТА, ПРЕЖДЕ ЧЕМ НАПИСАТЬ СООБЩЕНИЕ — ПРОЧТИТЕ ВЕСЬ ТРЕД!!! СКОРЕЕ ВСЕГО ВАШ ВОПРОС ИЛИ ВАША ПРЕТЕНЗИЯ УЖЕ ОБСУЖДАЛАСЬ!

★★★★★

Последнее исправление: deep-purple (всего исправлений: 2)
Ответ на: комментарий от PRN

Твои слова не противоречат набросу, я вот и хочу и апологетов освобождения ресурсов через раскрутку исключений добиться доводов в пользу невыхода просто через exit() в крайнем случае всегда есть atexit() если уж хочется ну совсем корректно, зачем городить исключения там где они не нужны?

anonymous
()
Ответ на: комментарий от anonymous

умрет между перезапусками системы

Для этого систему надо перегружать. Что не всегда возможно если вы разрабатываете и распространяете приложение.

если его просто не удалят

Простите, а кто «вдруг» lock файл удалит o_O? У Вас там точно все нормально работает?

Давай еще пример.

Шаред мемори )))

PRN ★
()
Ответ на: комментарий от anonymous

Кстати то же самое с блокировкой файла. Если приложение при выходе не разблокировало его, то вновь запустившись обнаружит что он всё еще заблокирован. Ой!

deep-purple ★★★★★
() автор топика
Ответ на: комментарий от PRN

Шаред мемори

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

deep-purple ★★★★★
() автор топика

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

WitcherGeralt ★★
()
Ответ на: комментарий от WitcherGeralt

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

deep-purple ★★★★★
() автор топика
Ответ на: комментарий от anonymous

Потому что это сейчас нужно просто сделать exit(0) и задать соответствующие вызовы atexit. Это может измениться, банально нужно будет то же логгирование добавить. Наконец, использование atexit подразумевает наличие глобальных переменных и ссылающихся на них функций. Использование глобальных переменных ломает модель освобождения ресурсов без какой-либо на то причины. Если вас волнует затрата (мизерной) доли времени на освобождение всех ресурсов, (а не только тех, которые система не освободит сама), вы можете использовать аллокатор с noop в качестве free и подобные обертки над иными видами ресурсов.

Siborgium ★★★★★
()
Ответ на: комментарий от anonymous

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

Siborgium ★★★★★
()
Ответ на: комментарий от WitcherGeralt

Быстро не значит что плохо посрались. Мне понравилось.

deep-purple ★★★★★
() автор топика
Ответ на: комментарий от deep-purple

Тем что в нудном месте написано catch

Тебе ещё надо гарантировать, что во всей цепочке вызовов нет catch-а, который отловит твоё исключение. И чтобы гарантии сработали и через год, и через два.

Тебе какое-то говно показывали.

Ну так ничего другого и не показал ;)

А по теме, я наблюдал, когда люди делали бизнес-логику через setjmp/longjmp/exception, уверяя, что исключения - это запланированное поведение. Выглядело так, что на верхнем уровне стоял общий обработчик для 10 исключений, которые не ошибки, и в вызовах на разной глубине бросались эти исключения, которые надо было ловить на самом верху. И надо было на всех вложенных уровнях отслеживать, чтобы нужное исключение не перехватывалось с обработкой. И частенько ломалось.

Вот ты что-то поменял, дополнил. Тесты на что?

Тесты не предотвратят лапшекод.

Тем более не забывай, что работа с exception дорогостоящая операция. В данном случае тебе повезло, на тормоза не страшно, т. к. приложение завершит работу, но это не всегда так.

ma1uta ★★★
()
Ответ на: комментарий от PRN

Простите, а кто «вдруг» lock файл удалит o_O? У Вас там точно все нормально работает?

тот кто создал тот и удалит,проблем нет.

Шаред мемори )))

Тут либо она еще кому-то нужна, либо она будет высвобождена как подохнут все процессы которые ее использовали вроде же это так работало, нет?

Для этого систему надо перегружать. Что не всегда возможно если вы разрабатываете и распространяете приложение.

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

anonymous
()
Ответ на: комментарий от ma1uta

ещё надо гарантировать

Гарантировано: за счёт наследования от правильных родителей.

И частенько ломалось

Не додумали же.

Тесты не предотвратят лапшекод

Согласен. Но за себя я могу ручаться. А другие получат по лапкам линейкой. И впредь будут умнее. Тем более в документации об это будет написано.

тебе повезло, на тормоза не страшно

А я и не собираюсь использовать это гденить в циклах и тому подобное. Я ж не дебил.

deep-purple ★★★★★
() автор топика
Ответ на: комментарий от anonymous

Твои слова не противоречат набросу, я вот и хочу и апологетов освобождения ресурсов через раскрутку исключений добиться доводов в пользу невыхода просто через exit() в крайнем случае всегда есть atexit() …

Допустим, твое приложение что-то куда-то пишет. Для простоты пусть это будут рабоче данные на диск. После exit и прочего оно точно запишет все корректно? А если приложение многопоточное? После exit оно точно потом поднимится на этих корявых данных? Максиму что может exit это освободить некоторые системные ресурсы. Корректность логики программы лежит на программисте.

PRN ★
()
Ответ на: комментарий от ma1uta

Ой всё. Для какого-нибудь индивида и абстрактное хз может стать личной обидой. Проехали.

deep-purple ★★★★★
() автор топика
Ответ на: комментарий от Siborgium

понимаю, то тогда никто не будет выходить по exit() потому что это странно, мы же обсуждаем случай когда выход заведомо безопасен, топикстартер сказал что у него точно все отработало и он хочет выйти, почему нет?

anonymous
()
Ответ на: комментарий от anonymous

она будет высвобождена как подохнут все процессы которые ее использовали вроде же это так работало, нет?

Нет. Сегмент останется и будет жить до рестарта системы. А вот локи все освободятся со смертью процессов.

deep-purple ★★★★★
() автор топика
Ответ на: комментарий от anonymous

Это щас я хочу просто выйти. А что может случиться завтра? Мы будем переписывать приложение с нуля?

deep-purple ★★★★★
() автор топика
Последнее исправление: deep-purple (всего исправлений: 1)
Ответ на: комментарий от PRN

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

anonymous
()
Ответ на: комментарий от anonymous

Сегодня его система до exit все доделала, а завтра ему надо будет перед выходом что-то сделать, он будет все exit в своем коде искать и логику перед выходом копипаситить? Ну удачи ему))

PRN ★
()
Ответ на: комментарий от anonymous

Сегменты памяти точно везде между перезапусками сохраняются и доступны любым приложениям. Это же IPC. А вот насчет сброса блокировки семафора — не скажу на 100% — надо проверить. Однако, когда семафор в приложении умирает, то его ресурсы освобождаются даже при exit(0). Отсюда и без проверки следует что лок будет сброшен.

deep-purple ★★★★★
() автор топика
Ответ на: комментарий от anonymous

Даже если это зависит от реализации, то это означает, что код с exit в общем случае не переносим, а работает только на конкретных реализациях.

PRN ★
()
Ответ на: комментарий от deep-purple

он не считается за ошибку только в этом контексте, а другой неудавшийся лок уже будет ошибкой

Так в текущем решении тебе всё равно нужен будет второй тип ошибки для этого, что мешает сразу сделать нормально?

ya-betmen ★★★★★
()
Ответ на: комментарий от ya-betmen

Так я и сделал нормально — в случае «успеха» бросаю про пилотку, а в случае ошибки буду бросать что-то унаследованое от эррор.

deep-purple ★★★★★
() автор топика
Ответ на: комментарий от PRN

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

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

anonymous
()
Ответ на: комментарий от deep-purple

Да я сам такое говнище когда-то фиксил. Одна библиотека, даже не exit а abort делала, у него гарантий при выходе еще меньше. Ее писали хорошие математики, но не очень хорошие разработчики)

PRN ★
()
Ответ на: комментарий от anonymous

Это может делать только основной поток. Другие потоки ставят шареные флаги. Ты еще спроси где я сигналы перехватываю, в основном или нет.

deep-purple ★★★★★
() автор топика
Последнее исправление: deep-purple (всего исправлений: 1)
Ответ на: комментарий от deep-purple

Нет не буду, ты меня не заставишь.

anonymous
()

Что за полумеры? Шагай шире! пока галифе не треснут

Программируй на исключениях вообще все! Ведь программа твоя исключительна и уникальна, другой такой нет. А значит…! Логично? Логично!

А с учетом того, сколько шаблонов ты порвешь, это ж целое направление - Хайп Ориентрованное Программирование - ХОП!

ХОП - и в дамках! Огонь!

Крч одобряю, жги еще.

olelookoe ★★★★
()
Ответ на: комментарий от anonymous

тот кто создал тот и удалит,проблем нет.

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

Тут либо она еще кому-то нужна…

Выше, вроде ответили

PRN ★
()
Ответ на: комментарий от olelookoe

нужно построить обработку исключений таким образом, чтобы поток этой обработки имел семантику и производил полезную работу, тогда это будет действительно исключительным программированием на исключениях, пока у вас этого нет даже не зовите меня обратно :/

anonymous
()
Ответ на: комментарий от PRN

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

anonymous
()
Ответ на: комментарий от anonymous
i_want_continue:

try {
    while (true) {
        // some work
        if (condition) {
            throw iWantContinueEx(context);
        }
    }
} catch (iWantContinueEx) {
    goto i_want_continue;
}
deep-purple ★★★★★
() автор топика
Последнее исправление: deep-purple (всего исправлений: 1)
Ответ на: комментарий от deep-purple

ну это не совсем то что я имел в виду, но допустим я услышал зов? а потом такой:

  • да не… показалось.

:D

anonymous
()
Ответ на: комментарий от anonymous

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

deep-purple ★★★★★
() автор топика
Ответ на: комментарий от deep-purple

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

А если говорить серьезно, то действительно все сводится к тому, что и как делать, бездумно выходить по exit() - плохо, бездумно плодить исключения - плохо. Нет таких языковых средств, которые избавят от проблемы обдуманности тех или иных действий. На любой пример можно придумать контрпример когда решение из хорошего превратится в плохое, потому что условия поменялись.

anonymous
()
Ответ на: комментарий от deep-purple

Прочти всё. Он может быть вывален.

а) вывалить сообщение и сделать exit(0);

б) сделать exit(0) без каких либо сообщений вообще.

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

mord0d ★★★★★
()
Ответ на: комментарий от Siborgium

Надо сразу нормально код писать, чтобы этого не происходило, чтобы потом не городить 3.14-здец из костылей на микроскопах, переоборудованных в молотки. ☺

mord0d ★★★★★
()
Ответ на: комментарий от deep-purple

Так я и сделал нормально

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

ya-betmen ★★★★★
()
Ответ на: комментарий от mord0d

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

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

anonymous
()

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

примерно так работает андроид с его start/pause/resume/stop активностей и т.д. или используй какой-то другой подходящий паттерн, их сотни.

anonymous
()
Ответ на: комментарий от anonymous

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

Правильно анон вещает. :3

mord0d ★★★★★
()
Ответ на: комментарий от deep-purple

Кастните Шульмана, он поможет. Помню, когда он только освободился и устроился к нам на завод, он всех мужиков очаровал. Даже дрались из за него, такой был красавец.

Владимир

anonymous
()

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

Есть enum c кодами ошибок, есть handler их принимающий, есть на каждый код функция которую дёргает handler в соотвецтвии с ошибкой которая и принимает решение что делать дальше. Точка. Универсальное решение которое работало, работает и будет просто работать пока программирование в текущем виде вообще существует в принципе.

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

anonymous
()
Вы не можете добавлять комментарии в эту тему: топик перемещен в архив.