Python – uWSGI does not restart after being idle

uWSGI does not restart after being idle… here is a solution to the problem.

uWSGI does not restart after being idle

I use UWSGI and Systemd on Ubuntu 16.

I follow the instructions under One service per app from here: http://uwsgi-docs.readthedocs.io/en/latest/Systemd.html

If I start the systemd socket and visit the site, everything works fine.
But after the idle time (specified in the ini file), the uwsgi process is terminated and further requests do not seem to restart/reactivate the process.

workers have been inactive for more than 30 seconds (1501589319-1501589288)
SIGINT/SIGQUIT received... killing workers...
worker 1 buried after 1 seconds
worker 2 buried after 1 seconds
goodbye to uWSGI.

Here is my ini file:

[uwsgi]
module = wsgi

logto = /tmp/uwsgi.log

master = true
processes = 2
cheap = true
idle = 30
die-on-idle = true

manage-script-name = true

Here is my systemd socket configuration:

[Unit]
Description=Socket for uWSGI app

[Socket]
ListenStream=/var/run/uwsgi/myapp.socket
SocketUser=www-data
SocketGroup=www-data
SocketMode=0666

[Install]
WantedBy=sockets.target

Here is my systemd service configuration:

[Unit]
Description=uWSGI app
After=syslog.target

[Service]
ExecStart=/home/myapp/venv/bin/uwsgi \
        --ini /home/myapp/uwsgi/uwsgi.ini \
        --socket /var/run/uwsgi/myapp. socket
User=www-data
Group=www-data
Restart=on-failure
KillSignal=SIGQUIT
Type=notify
StandardError=syslog
NotifyAccess=all
RuntimeDirectory=uwsgi
WorkingDirectory=/home/myapp

Solution

After fiddling with it for almost a day, I found the answer in the documentation for the relevant settings. Although because I don’t use emperor instead of the same setup, it does let me know what’s going on.

The reason socket activation works only the first time is because uwsgi overwrites the socket file created by the systemd socket.

See the green “!” Important boxes on this page:
http://uwsgi-docs.readthedocs.io/en/latest/OnDemandVassals.html

It says:

If you will define in your vassal config same socket as used by
emperor for on demand action, vassal will override that socket file.
That could lead to unexpected behaviour, for example on demand
activation of that vassal will work only once.

So in my case, I don’t have an emperor, but systemd behaves like an emperor.

So what’s the solution?

Remove the --socket parameter from ExecStart in the systemd service file.

Instead of possession

ExecStart=/home/myapp/venv/bin/uwsgi \
        --ini /home/myapp/uwsgi/uwsgi.ini \
        --socket /var/run/uwsgi/myapp.socket

I changed it

ExecStart=/home/myapp/venv/bin/uwsgi \
        --ini /home/myapp/uwsgi/uwsgi.ini

I then stopped the systemd service and sockets, executed systemctl daemon-reload and started the systemd socket again. Evrything started working as expected – systemd socket activation worked with uwsgi! 🙂

Related Problems and Solutions