This is a submission for *DEV's Summer Bug Smash: Clear the Lineup** powered by Sentry.*

Project Overview

I maintain StayPresent, an open-source Python package that helps developers keep bots and background services running on platforms such as Render, Railway, Koyeb, and Heroku.

The library launches a lightweight web server alongside one or more bot processes, supervises them, and automatically restarts them if they crash. Because it's designed for long-running applications, reliability is far more important than adding new features.

During development of v1.5.10, I found a subtle shutdown race condition that could leave processes running after the application was supposed to exit.

Repository:

https://github.com/StayElite/StayPresent


Bug Fix or Performance Improvement

The bug appeared when a supervised bot crashed.

StayPresent waits for a configurable restart delay before spawning a replacement process. During that delay, the monitor thread was sleeping with an uninterruptible time.sleep().

If the user pressed Ctrl+C or the host sent SIGTERM during that restart window, shutdown would begin while the monitor thread was still asleep.

When the sleep finished, the monitor could still create a brand-new bot process after shutdown had already cleaned up every process it knew about.

Because monitor threads are intentionally non-daemon, this could leave the application waiting indefinitely for a process that should never have been started.

Although the race condition only occurred in a very specific timing window, it affected graceful shutdown—one of the most important parts of any long-running service.

The solution consisted of two changes:

  • Replacing the uninterruptible restart delay with an interruptible wait.
  • Synchronizing bot respawns with the shutdown sequence so new processes cannot be created once shutdown has started.

After these changes, shutdown immediately interrupts any pending restart and guarantees that no orphaned bot process can be created during application termination.


Code

GitHub Repository

https://github.com/StayElite/StayPresent

Release

v1.5.10

Commit / PR

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


My Improvements

While fixing this issue I wanted to preserve the existing restart behavior without introducing unnecessary complexity.

The challenge wasn't restarting crashed bots—it was ensuring that restart logic and shutdown logic could never interfere with each other.

To verify the fix I repeatedly tested scenarios including:

  • Bot crashes immediately before shutdown.
  • Ctrl+C during restart backoff.
  • SIGTERM while multiple supervised bots are active.
  • Repeated crash/restart cycles.
  • Normal graceful shutdown with healthy processes.

The final implementation guarantees that shutdown always has priority over restarting processes.

Besides solving the race condition itself, this also improves confidence when deploying StayPresent to production environments where clean process termination is essential.


Conclusion

Many bugs aren't obvious syntax mistakes—they only appear when multiple threads, signals, and process lifecycles interact at exactly the wrong moment.

This bug was one of those cases.

Fixing it made StayPresent significantly more reliable for long-running bot deployments while keeping the public API completely unchanged.

Sometimes the best feature release is the one where users never notice anything—because everything simply keeps working.