Могу ли я использовать исключения Python для обработки последствий сигналов SIGHUP для демона? - PullRequest
2 голосов
/ 31 января 2011

Я пишу простой маленький демон синхронизации файлов на python для реализации синхронизированной файловой системы между основным и дополнительным компьютером. Большая часть тяжелой работы выполняется rsync.

На первичной стороне он периодически вызывает rsync и спит несколько секунд перед повторением. На вторичной стороне он запускает rsyncd с subprocess.Popen () и выполняет .wait (), пока не завершится. Однако я хочу запустить реконфигурацию демона с SIGHUP. Мне интересно, каков наилучший способ очистки?

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

def signal_handler(signum, frame):
    raise fsync_config_exception

И

rsync_args = [rsync_binary, "--daemon", "--no-detach", "--config=%s" % (config.name) ]
p = subprocess.Popen(rsync_args)
try:
    p.wait()
    if p.returncode != 0:
        print "failed to spawn rsyncd"
        return False
except fsync_config_exception:
    print "spawn_and_monitor_rsyncd: config exceptions"
except:
    (type, value, tb) = sys.exc_info()
    print "we got %s with %s instead" % (type, value)

Однако я получаю:

we got <type 'exceptions.TypeError'> with __init__() takes exactly 2 arguments (1 given) instead

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

1 Ответ

2 голосов
/ 31 января 2011

Вы должны поднять fsync_config_exception экземпляр, а не класс.(Создайте его, используя __init__() подпись)

Однако я не предлагаю поднимать асинхронные исключения таким образом.Вам будет трудно гарантировать, что исключение возникает только тогда, когда оно может быть правильно обработано.Это также не очень хороший способ привыкнуть, так как вы не можете прерывать блокировку вызовов расширения C в контексте интерпретатора Python .... (но это не может быть проблемой для вас?)

В обработчике сигналов,Я хотел бы (скрывая детали и не зная, подходит ли это для вашего случая):

  • Установить состояние, отмечая, что текущая итерация была прервана - используйте это для маркировки, если специальная очистка в порядке
  • В обработчике сигналов убейте ожидающий процесс
  • Добавьте еще одну проверку условия после ожидания, чтобы увидеть, был ли процесс убит сигналом (с дополнительной проверкой переменной состояния, отмечающейесли SIGHUP был получен)
  • Сделайте то, что вам нужно сделать в ответ на SIGHUP
...