Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Как прервать выполнения зависшей функции / 25 сообщений из 34, страница 1 из 2
22.05.2020, 22:24
    #39960899
Jonnik
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прервать выполнения зависшей функции
Есть функция которая запускается раз в пол часа.
Она в свою очередь запускает до сотни других функций.

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

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

Можно в потоке проверять зависло или не зависло. Но я не знаю как завершить работу зависшей функции. А запускать эту функции в потоке не хочу, врятли она будет в нем адекватно работать, а переделать ее под поток займет много времени.
Может есть вариант проще.
...
Рейтинг: 0 / 0
22.05.2020, 22:27
    #39960900
Vizit0r
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прервать выполнения зависшей функции
искать заведомо кривой костыль для подпирания такого же заведомо кривого кода...отличный вариант.
...
Рейтинг: 0 / 0
22.05.2020, 22:35
    #39960907
Док
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прервать выполнения зависшей функции
Jonnik
переделать ее под поток займет много времени.

Не так уж и много. Если сделать ее выполнение через synchronize / queue , то она должна выполняться в контексте основного потока. Там ее можно будет обернуть в многочисленные try..except/try..finally, понаставить флажков ... вообщем, для велосипедостроения куча возможностей :)
...
Рейтинг: 0 / 0
22.05.2020, 22:56
    #39960914
Jonnik
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прервать выполнения зависшей функции
Док
Jonnik
переделать ее под поток займет много времени.

Не так уж и много. Если сделать ее выполнение через synchronize / queue , то она должна выполняться в контексте основного потока. Там ее можно будет обернуть в многочисленные try..except/try..finally, понаставить флажков ... вообщем, для велосипедостроения куча возможностей :)


Там 30 000 строк. Я не уверен, что это будет так уже быстро ее адаптировать для потока.
Поэтому и спрашиваю. Может есть другой способ.
...
Рейтинг: 0 / 0
22.05.2020, 23:00
    #39960916
Vlad F
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прервать выполнения зависшей функции
Док,

Per anus ad astra.))
Зачем ему в таком случае поток вообще?))
...
Рейтинг: 0 / 0
22.05.2020, 23:05
    #39960917
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прервать выполнения зависшей функции
JonnikНапример потерялась связь с сервером бд и еще куча непредвиденных причин. В результате
процесс останавливается и не идет дальше.

В этот момент к нему удобно подключиться отладчиком, посмотреть на эту непредвиденную
причину и сделать её предвиденной, не вызывающей зависание. Повторять до полного упокоения
непредвиденных причин.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
22.05.2020, 23:12
    #39960919
Док
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прервать выполнения зависшей функции
Jonnik
Там 30 000 строк. Я не уверен, что это будет так уже быстро ее адаптировать для потока.
Поэтому и спрашиваю. Может есть другой способ.

если функция останавливает основной поток, то 1) либо внутри функции нужно предусматривать выход из нее по наступлении определенных условий, 2) либо делать ее в потоке. Но и там в потоке придется делать п.1

Vlad F
Зачем ему в таком случае поток вообще?))

ты у меня спрашиваешь? Я предположил, что это не так сложно, пока не узнал про 30К строк кода :)

Vlad F
Per anus ad astra.))

а вот удивительно, но в жизни делание некоторых вещей per anus - самый оптимальный вариант
...
Рейтинг: 0 / 0
22.05.2020, 23:29
    #39960928
Vlad F
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прервать выполнения зависшей функции
Док,

1) У тебя, потому что это ты ему такие советы советуешь.))
2) Ещё раз, - зачем тогда ему этот фейковый поток вообще, если его потом предлагается проецировать на основной и отслеживаться уже в нем? Пусть тогда сразу в основном и отлаживается.
...
Рейтинг: 0 / 0
22.05.2020, 23:43
    #39960933
Jonnik
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прервать выполнения зависшей функции
Dimitry Sibiryakov

JonnikНапример потерялась связь с сервером бд и еще куча непредвиденных причин. В результате
процесс останавливается и не идет дальше.

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


Это не совсем вариант так как есть ошибки самих компонентов, которые происходят редко.
Например закончились ресурсы GDI. У меня нет желания решать вопрос почему на каком-то этапе прорисовки окна с DevExpress в редких случаях вылетает такая ошибка и все останавливается.
Или почему эксель может вылететь 10 способами. (Это хоть можно предусматреть)

Но проще убить этот процесс и начать заново.
...
Рейтинг: 0 / 0
23.05.2020, 00:06
    #39960939
Michael Longneck
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прервать выполнения зависшей функции
Отдельно сервис, отдельно воркер в другом процессе. Сборщик мусора раз в n времени прошёлся по запущенным воркерам и убил зависшие
...
Рейтинг: 0 / 0
23.05.2020, 00:18
    #39960946
Dmitry Arefiev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прервать выполнения зависшей функции
Все сводится к смытию ? Но сколько не смывай, оно не тонет ... Так и будет висеть в памяти ...

Надо:
* для БД ставить таймауты
* для файлов Эксель использовать нативные либы, выкидывающие исключения
* проверять доступность файла
и тд

... и писать код обрабатывающий исключения, который знает как восстанавливаться ...
...
Рейтинг: 0 / 0
23.05.2020, 01:27
    #39960964
rgreat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прервать выполнения зависшей функции
Сделать .Free у работающего TThread - работает.

Жестокий путь. ;)
...
Рейтинг: 0 / 0
23.05.2020, 01:55
    #39960967
ъъъъъ
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прервать выполнения зависшей функции
Jonnik
Есть функция которая запускается раз в пол часа.
Она в свою очередь запускает до сотни других функций.

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

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

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


А если зависнет та функция, которая запускает эти твои зависающие функции?
...
Рейтинг: 0 / 0
23.05.2020, 03:31
    #39960976
northener
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прервать выполнения зависшей функции
Jonnik
Есть функция которая запускается раз в пол часа.
Она в свою очередь запускает до сотни других функций.

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

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

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


Не было у этого проекта нормального Архитектора (с) ЮЗ
...
Рейтинг: 0 / 0
23.05.2020, 11:08
    #39960995
x1ca4064
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прервать выполнения зависшей функции
Jonnik

Может есть вариант проще.


Есть, но жуткий 22040439 , лучше в отдельном процессе
...
Рейтинг: 0 / 0
23.05.2020, 12:20
    #39961010
Jonnik
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прервать выполнения зависшей функции
Я ищю быстрый способ закрыть эту проблему.
Советовать писать более правильный код это не совсем по делу. Не зная всей информации по задачи. За пару лет были устранены почти все возможные ошибки. Но остались такие, которые не связаны с моим кодом. И у меня нет желания тратить месяц на решение низкоуровневых ошибок. Бывают ошибки которые раз в пол года возникают. И ты еще попробуй их потом воссоздать потом, что бы исправить.
В данной задаче проще выключить зависший процесс и запустить его заново.
А именно в потоке проверять зависло или нет. И если зависло, то просто перезапустить приложение.
Решается максимум за пару часов.
Я думал есть более простой и элегантный способ.

Все, всем спасибо.
...
Рейтинг: 0 / 0
23.05.2020, 19:05
    #39961141
Док
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прервать выполнения зависшей функции
Vlad F,

Вон, видишь, народ вообще пришёл к выводу вместе с автором, что проще тихо похоронить всю функцию с результатом в доп.потоке, не разбирая причин. А ты на меня за невинные предложения наезжаешь ;)
...
Рейтинг: 0 / 0
23.05.2020, 20:35
    #39961169
Vlad F
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прервать выполнения зависшей функции
Док
Vlad F,

Вон, видишь, народ вообще пришёл к выводу вместе с автором, что проще тихо похоронить всю функцию с результатом в доп.потоке, не разбирая причин. А ты на меня за невинные предложения наезжаешь ;)

В доппроцессе, Док, в доппроцессе. И, прошу заметить, безо всякого Sinchronize().
От чего, впрочем, все эти новые предложения не становяться менее ректальными, имхо.))
...
Рейтинг: 0 / 0
23.05.2020, 21:36
    #39961181
cptngrb
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прервать выполнения зависшей функции
Jonnik, если ты думаешь, что в потоке этого же приложения ты сможешь перезапустить задачу, то "Бывают ошибки которые раз в пол года возникают." может и не получиться, а может и получиться. Убивать только другим процессом. А если в твоем монстре много всего системного, то ОС может повиснуть раз в 3 года и тогда только кнопочкой Reset
...
Рейтинг: 0 / 0
23.05.2020, 21:43
    #39961184
ъъъъъ
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прервать выполнения зависшей функции
Надо просто баги искать и править, а не херню выдумывать.
...
Рейтинг: 0 / 0
24.05.2020, 03:25
    #39961236
northener
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прервать выполнения зависшей функции
ъъъъъ
Надо просто баги искать и править, а не херню выдумывать.

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

Конечно можно предложить радикальное решение. Выбросить старый код на помойку и написать новый. Уже продуманный с учетом опыта (если конечно этот опыт хоть чему-то научил). Но если это реальный проект, то "где деньги, Зин?".

P.S. Не могу сказать что сам в этом отношении безгрешен. Но принимать радикальные решения приходилось.
...
Рейтинг: 0 / 0
09.10.2020, 17:48
    #40007050
softwarer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прервать выполнения зависшей функции
ъъъъъ
Надо просто баги искать и править, а не херню выдумывать.

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

По опыту доведения подобной задачи до безупречного состояния:

  • Каждый экземпляр боевой функциональности - в отдельном потоке. В основном потоке только диспетчер и интерфейс. В принципе, в отдельные процессы, скорее всего, ещё лучше, но мне хватило и без этого.
  • Вылизать и обвесить fulldebugmod-ом всю работу с памятью
  • Более-менее критичные объекты, в первую очередь connection-ы - в общий пул, оттуда выдавать их потокам, зная, какой куда выдан
  • Вся синхронизация - на объектах, обладающих таймаутом. Никаких "буду ждать до бесконечности пока что-то не случится"
  • В начале работы чистить контекст, не ожидая, что он будет "новый с листа". При соединении с БД - запускать отстрел предыдущей сессии, которая, возможно, зависла и не отключилась. При работе с диском - чистить временные файлы, которые могли остаться от предыдущего раза. И так далее.
  • Тщательно проработать проблемные ситуации на предмет "а должны ли они останавливать основую функциональность". Та же чистка временных файлов, если вдруг завершилась неудачей - наплевать в лог и идти дальше
  • Проблемы, которые можно проверить заранее - проверить заранее
  • Если поток завис - по тайм-ауту отстрелить его через TerminateThread, по возможности почистить его ресурсы, пользуясь информацией из пула и следя, чтобы наведённые ошибки при чистке не имели шанса похоронить приложение.
...
Рейтинг: 0 / 0
09.10.2020, 19:11
    #40007081
YuRock
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прервать выполнения зависшей функции
softwarer
Вся синхронизация - на объектах, обладающих таймаутом. Никаких "буду ждать до бесконечности пока что-то не случится"
Где это возможно - да. Но плохо, когда после таймаута выполнится то, что ожидалось до истечения таймаута. Этот баг и его последствия будет сложнее исправить, чем зависания.

softwarer
Если поток завис - по тайм-ауту отстрелить его через TerminateThread, по возможности почистить его ресурсы
Мда... Кстати, а как определить, что поток завис?
...
Рейтинг: 0 / 0
09.10.2020, 19:14
    #40007082
Соколинский Борис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прервать выполнения зависшей функции
YuRock
Мда... Кстати, а как определить, что поток завис?
Из потока периодически отсылать сообщение "не убивай, я еще жив!" основному.
...
Рейтинг: 0 / 0
09.10.2020, 19:21
    #40007086
YuRock
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прервать выполнения зависшей функции
Соколинский Борис
YuRock
Мда... Кстати, а как определить, что поток завис?
Из потока периодически отсылать сообщение "не убивай, я еще жив!" основному.
Если поток очень занят ожиданием или какой-то важной операцией (особенно, выполняемой другой библиотекой, например запрос к базе), то у него не будет времени отправить...
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Как прервать выполнения зависшей функции / 25 сообщений из 34, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]