Graceful shutdown when SIGTERM is received (#2286)

Only works on Unix.
This commit is contained in:
El Laggron 2019-01-23 00:28:30 +01:00 committed by Toby Harradine
parent abcf179042
commit 3b62572c89
2 changed files with 17 additions and 0 deletions

View File

@ -28,6 +28,7 @@ Paste the following and replace all instances of :code:`username` with the usern
Restart=always Restart=always
RestartSec=15 RestartSec=15
RestartPreventExitStatus=0 RestartPreventExitStatus=0
TimeoutStopSec=10
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target
@ -48,6 +49,14 @@ To set the bot to start on boot, you must enable the service, again adding the i
:code:`sudo systemctl enable red@instancename` :code:`sudo systemctl enable red@instancename`
If you need to shutdown the bot, you can use the ``[p]shutdown`` command or
type the following command in the terminal, still by adding the instance name after the **@**:
:code:`sudo systemctl stop red@instancename`
.. warning:: If the service doesn't stop in the next 10 seconds, the process is killed.
Check your logs to know the cause of the error that prevents the shutdown.
To view Reds log, you can acccess through journalctl: To view Reds log, you can acccess through journalctl:
:code:`sudo journalctl -u red@instancename` :code:`sudo journalctl -u red@instancename`

View File

@ -14,6 +14,7 @@ from redbot.core.cli import interactive_config, confirm, parse_cli_flags, ask_se
from redbot.core.core_commands import Core from redbot.core.core_commands import Core
from redbot.core.dev_commands import Dev from redbot.core.dev_commands import Dev
from redbot.core import __version__ from redbot.core import __version__
from signal import SIGTERM
import asyncio import asyncio
import logging.handlers import logging.handlers
import logging import logging
@ -110,6 +111,11 @@ def list_instances():
sys.exit(0) sys.exit(0)
async def sigterm_handler(red, log):
log.info("SIGTERM received. Quitting...")
await red.shutdown(restart=False)
def main(): def main():
description = "Red - Version {}".format(__version__) description = "Red - Version {}".format(__version__)
cli_flags = parse_cli_flags(sys.argv[1:]) cli_flags = parse_cli_flags(sys.argv[1:])
@ -139,6 +145,8 @@ def main():
if cli_flags.dev: if cli_flags.dev:
red.add_cog(Dev()) red.add_cog(Dev())
loop = asyncio.get_event_loop() loop = asyncio.get_event_loop()
if os.name == "posix":
loop.add_signal_handler(SIGTERM, lambda: asyncio.ensure_future(sigterm_handler(red, log)))
tmp_data = {} tmp_data = {}
loop.run_until_complete(_get_prefix_and_token(red, tmp_data)) loop.run_until_complete(_get_prefix_and_token(red, tmp_data))
token = os.environ.get("RED_TOKEN", tmp_data["token"]) token = os.environ.get("RED_TOKEN", tmp_data["token"])