0

I am using nginx and gunicorn to serve flask app. Everything is working good the ony issue is, I need to restart gunicorn after couple of hours either I haven't update any code to the server. Here are steps which I have followed.

Step-1 wsgi.py file in project's root directory.

from myproject import app

if __name__ == "__main__":
    app.run()

Step-2 Verified with server with following command which is working

  • python app.py
  • gunicorn --bind 0.0.0.0:5000 wsgi:app

Step-3 Setup gunicorn service: /etc/systemd/system/gunicorn.service

[Unit]
Description=Gunicorn API
After=network.target

[Service]
User=ubuntu
Group=www-data
WorkingDirectory=/var/www/api-setup
Environment="PATH=/var/www/api-setup/venv/bin"
ExecStart=/var/www/api-setup/venv/bin/gunicorn --workers 1 --bind unix:app.sock -m 007 wsgi:app

[Install]
WantedBy=multi-user.target

Step-4: nginx conf file: /etc/nginx/site-available/my-nginx-conf

server {
  listen 80;

  client_max_body_size 1008M;

  server_name Some.IP.Address;

  root /var/www/api-setup/;

  location / {
   proxy_pass http://unix:/var/www/api-setup/app.sock;
  }
}

After couple of hours, when I request to server, it showing error

sqlalchemy.exc.StatementError: (sqlalchemy.exc.InvalidRequestError) Can't reconnect until invalid transaction is rolled back [SQL: 'SELECT tbls.id AS.....]

and after running

sudo systemctl1 restart gunicorn

everything works good. Any thoughts would be appriciated.

Sample Code

# Save Process
@api.route('/save')
class SaveData(Resource):
@classmethod
@jwt_required
def post(self):
    try:
        # Get request payload
        data = request.json
        instance = Model.find_by_id(id)
        instance.name = 'Updated Name'
        db.session.add(instance)
        db.session.commit()

        return BaseController.send_response(response, 200)
    except Exception as e:
        db.session.rollback()
        api.abort(e.status_code, e.message)

Thanks!

nitin7805
  • 203
  • 2
  • 13
  • The server logs will likely have information on why it's going Internal Server Error. What does `journalctl -u gunicorn` show? – AKX Jun 08 '20 at 13:51
  • Hi AKX, I have Edited my question, it return sqlalchemy.exc.InvalidRequestError error. and after gunicorn restart it works good. Thanks! – nitin7805 Jun 11 '20 at 04:56
  • "Can't reconnect until invalid transaction is rolled back" is the clue. You are probably misusing database connections in your code, and something eventually happens that causes the single connection/transaction to be broken in a way that requires restart of the server. You could show the code? – AKX Jun 11 '20 at 06:12
  • Hi @AKX , Updated my question with sample code. To reproduce I have temprary removed the auto increment from primary key. When I am trying to save/update record it shows mysql error i.e id can not be null. After that all othere APIs are showing internal server untill I restart gunicorn. – nitin7805 Jul 17 '20 at 07:21
  • What is `db.session`? You're probably not using SQLAlchemy (it smells like SQLAlchemy anyway) correctly, in a way that would reset the database connection correctly for each request. – AKX Jul 17 '20 at 07:27
  • @AKX, db is instance of SQLAlchemy(). using db = SQLAlchemy() from base file. As per the documentation using db.session.add(data) and and db.session.commit() to add data and db.session.rollback() to revert data. Ref link - https://flask-sqlalchemy.palletsprojects.com/en/2.x/queries/ – nitin7805 Jul 17 '20 at 11:36
  • Hi @AKX, any idea, what could be causing that issue? I am facing this since long time. – nitin7805 Jul 20 '20 at 08:14
  • Now that you revealed you're using flask-sqlalchemy, does https://stackoverflow.com/questions/31121948/flask-sqlalchemy-cant-reconnect-until-invalid-transaction-is-rolled-back help? – AKX Jul 20 '20 at 08:27

0 Answers0