instead of running a second script calling python red.py every time it crashes.
should also have
!restart to re-init/login
!shutdown to shutdown
How would you run !restart if the bot is already RIP? Or am I misunderstanding?
@xnaas if the bot is already RIP, it would restart before you notice
when the bot rips, it restarts itself.
!restart would.. force a restart. like a computer would
!shutdown would.. force a shutdown. like a computer would
Would be nice. At the very least I'd kill for a systemd port of the Upstart script... 馃槢
Thanks for the clarification @irdumbs and @FishyFing.
yeah I hope to throw away all those scripts n such :3
Could you not just have the startRedLoop.bat running? It should restart when the bot rips.
@Mortiferr instead of running a second script calling python red.py every time it crashes. the loop does this. what we're saying is that on shutdown, it starts by itself again with no script
@FishyFing Oops sorry, I need to learn to read.
or rather, whenever the bot crashes it restarts on it's own and on restart the bot restarts, whereas on shutdown, the bot shuts down
For almost everything I make I use a simple bash script (found it somewhere online) that starts the program and restarts it on exit code 2, so I can use exit() to shut it down and exit(2) to restart it (don't know if this is the good way to do it, but it works, used it for PHP scripts before):
#!/bin/sh
code=2
while [ $code -eq "2" ]
do
python start.py
code=$?
done
EDIT: Doesn't work for crashes of course :/
it's an improvement but we're talking about putting this functionality into the bot itself
This is a great idea
We need to add a global error catcher (somewhere in the main red.py near the main loop, as far as I understand it) and perform the loop restart over there. Need to have a closer look
If you want to try to do it within the bot loop try to take a look at overriding on_error(). I'm starting to think we should catch our own PID and then stick the bot in a forked process so we can monitor it.
This is a nice idea.
While in most cases the bot restarting itself will be sufficient, there could always be scenario's where the bot could crash or get killed by an oomkiller on the system. By mistake, etc.
I am in favor of using systemd instead of an upstart script.
However, you'll need a modern Linux system to do this.
Below is just an example configuration I made, which should work.
It will start the bot again if Red exits with anything but 0 as its exitcode.
I hope this helps someone. :)
Create e.g. /etc/systemd/system/red-discord.service
Paste in the following, modify to fit your own environment.
[Unit]
Description=Red Discord bot
After=network.target
[Service]
User=discord
Group=discord
Type=simple
WorkingDirectory=/home/discord/Red-DiscordBot
ExecStart=/usr/bin/python3.5 /home/discord/Red-DiscordBot/red.py --no-prompt
Restart=on-failure
[Install]
WantedBy=multi-user.target
Reload systemd:
systemctl daemon-reload
Start the bot
systemctl start red-discord
@phantium there is also supervisor support, which can be found in Kowlin's guide: https://gist.github.com/Kowlin/2c7116ead68a344e5a33#file-gistfile1-txt-L15
When would you need the bot to restart itself? There may be a better way. For example if you want to restart the bot because you changed some settings, perhaps a config reload command would be better.
I was using the code below to allow me to log out proper and exit out of the loop.bat for my win tray GUI
import subprocess
import os
if os.name == "nt":
try:
p=subprocess.Popen(["startRedLoop.bat"])
pid_bat = str(p.pid)
pid_red = str(os.getpid())
if p.pid > 0:
print ("Process created with PID: ", pid_bat)
print("Python PID: ", pid_red)
f = open("red.pid","w")
f.write(pid_bat)
f.close()
exit()
except Exception as e:
print(e)
@Echo off
chcp 65001 >nul
python pid.py
def kill_red(bot):
try:
f = open("red.pid","r")
bat_pid = f.readline()
print("startRedLoop.bat: ", bat_pid)
print("active red: ", str(os.getpid()))
try:
if sys.platform == "linux" or sys.platform == "linux2":
# linux
"""
start on runlevel [2345]
stop on runlevel [016]
respawn
chdir /home/username/Red-DiscordBot
setuid username
setgid username
exec python3.5 red.py --no-prompt
post-start script
PID=`status app_name | egrep -oi '([0-9]+)$' | head -n1`
echo $PID > /home/username/Red-DiscordBot/red.pid
end script
post-stop script
rm -f /home/username/Red-DiscordBot/red.pid
end script
---------------------------------------------
#http://stackoverflow.com/questions/9972023/ubuntu-upstart-and-creating-a-pid-for-monitoring
#http://stackoverflow.com/questions/17856928/how-to-terminate-process-from-python-using-pid
#!upstart
description "Redis Server"
env USER=redis
start on startup
stop on shutdown
respawn
exec sudo -u $USER sh -c "/usr/local/bin/redis-server /etc/redis/redis.conf 2>&1 >> /var/log/redis/redis.log"
post-start script
PID=`status app_name | egrep -oi '([0-9]+)$' | head -n1`
echo $PID > /var/run/app_name.pid
end script
post-stop script
rm -f /var/run/app_name.pid
end script
"""
bot.logout()
os.popen('kill -SIGTERM '+str(bat_pid))
elif sys.platform == "darwin":
# OS X
bot.logout()
elif sys.platform == "win32":
# Windows...
bot.logout()
# Kill the proces using pywin32 and pid
import win32api
PROCESS_TERMINATE = 1
handle = win32api.OpenProcess(PROCESS_TERMINATE, False, int(bat_pid))
win32api.TerminateProcess(handle, -1)
win32api.CloseHandle(handle)
exit()
except Exception as e:
print("Kill PID error")
print (e)
return False
except Exception as e:
print("Read PID error")
print (e)
#bot.logout()
return False
how do I run bot when my pc is off?
@SunDwarf -- How do I launch my web browser if my PC is off? Hint: I don't. 馃槈
You have to host the bot on an external server if you don't want to leave your own PC on 24/7.
@xnaas Pretty sure that @SunDwarf was being sarcastic lol
Most helpful comment
For almost everything I make I use a simple bash script (found it somewhere online) that starts the program and restarts it on exit code 2, so I can use
exit()to shut it down andexit(2)to restart it (don't know if this is the good way to do it, but it works, used it for PHP scripts before):EDIT: Doesn't work for crashes of course :/