3

I've been working on a garage door automation application for the Raspberry Pi that will allow you to remote open/close the garage door as well as check the status of the door (whether open or closed). I've posted the code up on GitHub here: Link to GitHub.

From time to time, it seems that the application is simply unreachable over my network as if Flask has simply stopped responding to web requests. I can still, however, SSH into my pi just fine when this happens. A reboot brings the web interface back, with no issues.

After doing some reading, as I understand it, the built-in webserver in Flask is really not robust and shouldn't be used in a production environment, so I decided that I would try to setup Gunicorn and nginx to handle the job instead. I modified the code and tried running Gunicorn. Unfortunately, Gunicorn seems to report errors with the Threading library (which I'm using to check the status of the door in the background). Here is some of the output from Gunicorn when I try to run it:

pi@raspi-4:~/garage-pi $ sudo gunicorn app:app
[2016-07-17 11:06:08 +0000] [745] [INFO] Starting gunicorn 19.6.0
[2016-07-17 11:06:08 +0000] [745] [INFO] Listening at: http://127.0.0.1:8000 (745)
[2016-07-17 11:06:08 +0000] [745] [INFO] Using worker: sync
[2016-07-17 11:06:08 +0000] [750] [INFO] Booting worker with pid: 750
[2016-07-17 11:06:08 +0000] [750] [INFO] Worker exiting (pid: 750)
Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/lib/python2.7/threading.py", line 810, in __bootstrap_inner
    self.run()
  File "/usr/lib/python2.7/threading.py", line 763, in run
    self.__target(*self.__args, **self.__kwargs)
  File "/home/pi/garage-pi/app.py", line 21, in checkdoorstate
    if (RPi.GPIO.input(18) == True and door_state != True):
AttributeError: 'NoneType' object has no attribute 'GPIO'

With all of that said, I'm out of my depth here, and wanted to know if this setup is at all possible, or will I continue to have issues with using the Threading Python library with Gunicorn? Any thoughts on how to resolve this issue?

Many thanks in advance.

Ben Parmeter
  • 49
  • 2
  • 11
  • Does the flask server work with `python .py`? – hjpotter92 Jul 17 '16 at 18:36
  • hjpotter92 - Yes, this works just fine and is what I've got deployed right now. However, after some time, it seems that the app fails to respond to web requests after a few days. I can still SSH in, and the python process is still running. – Ben Parmeter Jul 17 '16 at 18:54
  • Where is the RPi library installed? Does Gunicorn know how to find it? Another issue I see is your app.py. Running this file using your Gunicorn command "app:app" will load the app from the "app = Flask(__name__)" line, but on the bottom of the file you are calling exit and cleanup on RPi.GPIO. Take a look on this page how to properly run Flask app using Gunicorn. https://www.digitalocean.com/community/tutorials/how-to-serve-flask-applications-with-gunicorn-and-nginx-on-ubuntu-14-04 – Boris Jul 18 '16 at 03:01
  • @Boris - Actually, I'm not sure where the RPi library is installed since it just comes pre-installed with the Raspbian OS. I'll take a look at the linked page to see if I can reach any new conclusions. – Ben Parmeter Jul 18 '16 at 05:39
  • Even after properly launching the application via Gunicorn, it seems there are still issues with the Threading module and Gunicorn. Was starting to look at Gevent to see if there was a "proper" way to have a background thread while using Gunicorn. Still haven't gotten that to work. Seems like Gevent threads are blocking. Any help here would be greatly appreciated. – Ben Parmeter Jul 28 '16 at 18:10
  • did you find any way of running background threads with gunicorn ? – keisar Aug 04 '17 at 07:23
  • @keisar - Nope, never did find a solution. Just went with separate processes that communicate via JSON files. – Ben Parmeter Aug 10 '17 at 19:31
  • hi, i just using gunicorn but i can run my discord bot inside gunicorn with a flask, everyone can help me? i don't fine any good reference – perymerdeka Apr 08 '21 at 16:34

1 Answers1

0

You can start your app with multiple workers or async workers with Gunicorn. Gunicorn with gevent async worker

gunicorn server:app -k gevent --worker-connections 1000

Gunicorn 1 worker 12 threads:

gunicorn server:`app -w 1 --threads 12

Gunicorn with 4 workers (multiprocessing):

gunicorn server:app -w 4

More information on Flask concurrency in this post: How many concurrent requests does a single Flask process receive?.

Source

Amit Tripathi
  • 7,003
  • 6
  • 32
  • 58
Umar Hayat
  • 4,300
  • 1
  • 12
  • 27
  • 1
    Umar, you should credit others when you copy an answer https://stackoverflow.com/a/35839360/1972493 – Joe Aug 18 '20 at 13:36