Difegue / LANraragi

Web application for archival and reading of manga/doujinshi. Lightweight and Docker-ready for NAS/servers.
https://lrr.tvc-16.science
MIT License
2.18k stars 153 forks source link

SIGINT handler called multiple times #1051

Open alethiophile opened 1 month ago

alethiophile commented 1 month ago

LRR Version and OS v0.9.21, Linux, installed from source

Bug Details I notice that the SIGINT handler is called multiple times when a SIGINT is received. This seems to be the result of 1. the add_sigint_handler subroutine being called multiple times (once per request in the before_dispatch hook), and 2. the handler set by that subroutine calling the old handler. This results in the handler being updated multiple times, each one calling the one prior to it in a chain, before finally it reaches the end of the chain and calls (I assume) the original handler set by the framework or the development server.

The handler appears to be called three or four times. Meanwhile, the before_dispatch hook is called once per request, meaning there are at least a few dozen calls per browser page load (fetching API data, image thumbnails, etc). I don't have a strong understanding of why these numbers are different; there's probably some non-determinism involved with worker processes and so on.

This seems unlikely to cause many practical issues, other than a bit of log pollution. All that the SIGINT handler is doing is killing worker processes, and if multiple kill calls get made, the later ones will probably just fail harmlessly. (I suppose the exception would be if a new process is started on that PID between calls, but that would be a very unlikely race condition.) However, it's still untidy, and would be better fixed.

One obvious solution would be to just set the sigint handler in the startup subroutine, and leave the before_dispatch hook out of it entirely. However, I assume there was a reason why the before_dispatch hook was used in the first place, rather than this more obvious method. The other option would just be to set a flag the first time the handler is set, and check for it later.