# 我修复了一个可能导致机器人进程永远运行的关闭竞态条件 🐞

发布日期:2026-07-30 10:02:21  浏览量 :0
发布日期:2026-07-30 10:02:21  
0

这是为 *DEV 的夏季漏洞清除活动:清理阵容** 由 Sentry 提供支持。*

项目概述

我维护着 StayPresent,这是一个开源的 Python 包,旨在帮助开发者在 Render、Railway、Koyeb 和 Heroku 等平台上保持机器人程序和后台服务的持续运行。

该库会在一个或多个机器人进程旁边启动一个轻量级的 Web 服务器,对这些进程进行监控,并在它们崩溃时自动重启。由于它专为长期运行的应用程序设计,因此可靠性远比添加新功能重要得多。

在开发 v1.5.10 版本期间,我发现了一个微妙的关闭竞态条件,这可能导致在应用程序本应退出后,仍有进程在运行。

代码仓库:

https://github.com/StayElite/StayPresent

漏洞修复或性能改进

该漏洞在被监控的机器人程序崩溃时出现。

StayPresent 在生成替换进程之前,会等待一段可配置的重新启动延迟时间。在该延迟期间,监控线程处于不可中断的 time.sleep() 睡眠状态。

如果用户在该重新启动窗口期间按下 Ctrl+C 或主机发送了 SIGTERM 信号,关闭流程将在监控线程仍处于睡眠状态时开始。

当睡眠结束时,监控线程可能会在关闭流程已经清理完所有已知进程之后,仍然创建一个全新的机器人进程。

由于监控线程被特意设置为非守护线程,这可能导致应用程序无限期地等待一个本不应启动的进程。

尽管该竞态条件仅在非常特定的时间窗口内发生,但它影响了优雅关闭——这是任何长期运行服务中最重要的部分之一。

解决方案包括两项更改:

  • 将不可中断的重新启动延迟替换为可中断的等待。
  • 将机器人进程的重启与关闭序列同步,确保一旦关闭开始,就无法创建新进程。

经过这些更改后,关闭操作会立即中断任何挂起的重启,并保证在应用程序终止期间不会创建孤立的机器人进程。

代码

GitHub 代码仓库

https://github.com/StayElite/StayPresent

发布版本

v1.5.10

提交 / 拉取请求

https://github.com/StayElite/StayPresent/commit/1210148731ed8e3146bb4ccd36a931b58c9705d8

我的改进

在修复此问题时,我希望在不引入不必要复杂性的情况下保留现有的重启行为。

挑战不在于重启崩溃的机器人程序,而在于确保重启逻辑和关闭逻辑永远不会相互干扰。

为了验证修复效果,我反复测试了以下场景:

  • 机器人在关闭前立即崩溃。
  • 在重启退避期间按下 Ctrl+C。
  • 在多个被监控的机器人程序活跃时发送 SIGTERM 信号。
  • 重复的崩溃/重启循环。
  • 在进程健康状态下进行正常的优雅关闭。

最终实现确保了关闭操作始终优先于重启进程。

除了解决竞态条件本身外,这也提高了在生产环境中部署 StayPresent 时的信心,因为在这些环境中,干净的进程终止至关重要。

免责声明:本文内容来自互联网,该文观点不代表本站观点。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,请到页面底部单击反馈,一经查实,本站将立刻删除。

分享到:

长按或扫码识别 分享给好友

长按或扫码识别 分享给好友
关于我们
热门推荐
合作伙伴
免责声明:本站部分资讯来源于网络,如有侵权请及时联系客服,我们将尽快处理
Copyright © 2025-2027 ToB产业网址导航 公安备案 浙公网安备33010602013138号 浙ICP备16025413号-9
支持 反馈 关注 数据