我可以使用 Python 异常来处理守护进程的 SIGHUP 信号的后果吗?

发布于 2024-10-15 07:04:32 字数 1028 浏览 4 评论 0原文

我正在用 python 编写一个简单的小型文件同步守护进程,以实现主机器和辅助机器之间的同步文件系统。大部分繁重的工作都是由 rsync 完成的。

在主端,它定期调用 rsync 并在重复之前休眠几秒钟。在辅助端,它使用 subprocess.Popen() 生成 rsyncd 并执行 .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。有人对解决此类问题的最佳方法有任何建议吗?我是否通过尝试从信号上下文中引发异常来可怕地滥用异常?

I'm writing a simple little file-syncing daemon in python to implement a synchronised file system between a primary and secondary machine. Most of the heavy lifting is done by rsync.

On the primary side it periodically calls rsync and sleeps for a few seconds before repeating. On the secondary side it spawns rsyncd with subprocess.Popen() and does a .wait() until it exits. However I want to trigger a reconfiguration of the daemon with a SIGHUP. I'm wondering what the best way of handling clean-up is.

My initial thoughts were to have the signal handler raise an exception that can trigger the clean-up:

def signal_handler(signum, frame):
    raise fsync_config_exception

And:

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)

However I get a:

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

instead of the expected fsync_config_exception. Has anyone any suggestions for the best approach to this sort of problem? I'm I hideously abusing Exceptions by trying to raise them from a signal context?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

变身佩奇 2024-10-22 07:04:32

您应该引发一个 fsync_config_exception 实例,而不是类。 (使用其 __init__() 签名实例化它)

但是,我不建议以这种方式引发异步异常。您将很难保证仅在可以正确处理异常时才引发异常。这也不是一个需要习惯的好模式,因为你不能在 Python 解释器上下文中中断阻塞的 C 扩展调用....(但这对你来说可能不是问题?)

在信号处理程序中,我会(掩盖细节)并且不知道这是否适合您的情况):

  • 设置状态,指出当前迭代已被中断 - 使用它来标记是否需要进行特殊清理
  • 在信号处理程序中,终止您正在等待的进程
  • 添加另一个条件等待后检查进程是否被信号杀死(对状态变量进行额外检查,注意是否收到 SIGHUP)
  • 响应 SIGHUP 执行您需要执行的操作

You should raise a fsync_config_exception instance, not the class. (Instantiate it using its __init__() signature)

However, I do not suggest raising asynchronous exceptions in that manner. You'll have a hard time guaranteeing that the exception is only raised when it can be properly handled. It's also not a good pattern to become accustomed to since you cannot interrupt blocking C extension calls in the Python interpreter context....(but that might not be a problem for you?)

In the signal handler, I would (glossing over details and not knowing if this is correct for your case):

  • Set state noting that the current iteration has been interrupted - use this for marking if special cleanup is in order
  • In the signal handler, kill the process that you're waiting on
  • Add another condition check after the wait to see if the process was killed by a signal (with additional check on the state variable noting if the SIGHUP was received)
  • Do what you need to do in response to the SIGHUP
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文