flask socket-io, sometimes client calls freeze the server - python

I occasionally have a problem with flask socket-io freezing, and I have no clue how to fix it.
My client connects to my socket-io server and performs some chat sessions. It works nicely. But for some reason, sometimes from the client side, there is some call that blocks the whole server (The server is stuck in the process, and all other calls are frozen). What is strange is that the server can be blocked as long as the client side app is not totally shutdown.This is an ios-app / web page, and I must totally close the app or the safari page. Closing the socket itself, and even deallocating it doesn't resolve the problem. When the app is in the background, the sockets are closed and deallocated but the problem persists.
This is a small server, and it deals with both html pages and the socket-server so I have no idea if it is the socket itself or the html that blocks the process. But each time the server was freezing, the log showed some socket calls.
Here is how I configured my server:
socketio = SocketIO(app, ping_timeout=5)
socketio.run(app, host='0.0.0.0', port=5001, debug=True, ssl_context=context)
So my question is:
What can freeze the server (this seems to happen when I leave the app or web-site open for a long time while doing nothing). If I use the services normally the server never freezes. And how I can prevent it from happening (Even if I don't know what causing this, is there a way to blindly stop my server from being stuck at a call?
Thanks you for the answers

According to your comment above, you are using the Flask development web server, without the help of an asynchronous framework such as eventlet or gevent. Besides this option being highly inefficient, you should know that this web server is not battle tested, it is meant for short lived tests during development. I'm not sure it is able to run for very long, specially under the unusual conditions Flask-SocketIO puts it through, which regular Flask apps do not exercise. I think it is quite possible that you are hitting some obscure bug in Werkzeug that causes it to hang.
My recommendation is that you install eventlet and try again. All you need to do is pip install eventlet, and assuming you are not passing an explicit async_mode argument, then just by installing this package Flask-SocketIO should configure itself to use it.
I would also remove the explicit timeout setting. In almost all cases, the defaults are sufficient to maintain a healthy connection.

Related

Flask flashes appear on development server, but not with uWSGI/Nginx

I have been learning Flask by making a little website and using the built in flask server that runs with python. I have a page where you press a button, and it flashes a message using the flash system inside of flask. These flashes work fine when I am using the built in flask server on my windows machine. However, I have deployed the website to a Linux server, using uWSGI which goes through Nginx. My issue is that when I access this server, the flashes don't work. Most things like loading pages work fine on both servers, but flashing is broken. I don't see any error messages from uWSGI's logs.
The code I am using for the flash is implemented as follows:
flash("Made new post.")
return redirect(url_for("posts"))
The redirect takes me to the correct page, and if I run a print() statement before the redirect the statements are clearly being reached, the flash just doesn't do anything.
The main other issue I am running into is with sessions and trying to store session variables. Nothing happens when I try to do this either. (but it works on my personal machine)
Any ideas why this might be, or at least a way to get an error message from uWSGI?
To properly set cookies (cookies are what make message Flashing work), both nginx and the Flask application need to agree on the server name.
So make sure your server_name in nginx.conf matches SERVER_NAME (or
SESSION_COOKIE_DOMAIN, if set) in your flask configuration.
There are also limits enforced by nginx on the size of cookies, but this should only be a problem if your flashed messages are really large.

Serve Flask Server Over HTTPS

I'm learning AWS and I'm currently trying to deploy a Flask API over HTTPS. I set up an EC2 instance running Apache. I've already set up SSL on the site using ELB, and I tried to deploy flask over HTTPS with the following:
if __name__ == '__main__':
context = ("server.crt", "server.key")
app.run(host="0.0.0.0",port=5000,debug=True,ssl_context=context)
However, I don't think the site is even starting the Flask server properply, as even though everything loads and I receive a message that Flask is running on https://0.0.0.0:5000/, sending a simple GET request over the browser doesn't work as the request just never loads and it eventually times out. It's almost behaving as if there is no server running on port 5000.
On the other hand, when I ran this program over http instead of https, it worked perfectly fine. Can anyone help me out in terms of what I should do? Thank you.
Based on the comments.
The solution to the issue was termination HTTPS connections on the ELB. This way, the communication between ELB and EC2 instance can be conducted using HTTP which is simple and easier to manage on the instances.

Python application freezes, only CTRL-C helps

I have a Python app that uses websockets and gevent. It's quite a big application in my personal experience.
I've encountered a problem with it: when I run it on Windows (with 'pipenv run python myapp'), it can (suddenly but very rarily) freeze, and stop accepting messages. If I then enter CTRL+C in cmd, it starts reacting to all the messages, that were issued when it was hanging.
I understand, that it might block somewhere, but I don't know how to debug theses types of errors, because I don't see anything in the code, that could do it. And it happens very rarily on completely different stages of the application's runtime.
What is the best way to debug it? And to actually see what goes behind the scenes? My logs show no indication of a problem.
Could it be an error with cmd and not my app?
Your answer may be as simple as adding timeouts to some of your spawns or gevent calls. Gevent is still single threaded, and so if an IO bound resource hangs, it can't context switch until it's been received. Setting a timeout might help bypass these issues and move your app forward?

Running a flask server

So, probably a dumb question, but I am beginning to learn all this so your feedback will be valuable for me.
The question is: In flask documentation it says start the flask server by entering the command 'python hello.py' and I do it successfully to see the output on localhost:5000. Now, I have a shared hosting plan and if I upload this file over there will i need to initiate the server over there as well like this? If so, when I close the terminal over there, will the flask server shut down (because when I close the terminal on my computer it shuts down the flask server and the results are no more available on localhost:5000)?.. It basically suggests me that I have to keep running the terminal all the time..please tell me what is the basic idea here? Thanks.
What you're asking is how you deploy your app. There are many options, that will depend on your needs, your hosting service, etc.
You should check the flask docs for the options. http://flask.pocoo.org/docs/deploying/
In essence, you'll have your flask app running as a local service on the server, so it's not shut down when you close the terminal, and an HTTP server that somehow proxies requests to that service. I guess the most popular is uWSGI with nginx.
When you upload your code to a remote host, you will need to provide a way to start the server and get things running. How this works is host- and software-dependent. As an example, here is some documentation for how you would fire Flask up on Heroku.

any python socket server framework?

I'm looking for a python socket server framework - not to handle http, but to handle tcp sockets. I've done it myself, but adding all the features is tedious. This framework would handle thread pooling, socket setup, signal handling, etc.
A big feature is code-reloading. If I use apache/mod_python, or django, or whatever, I don't have to restart the server to get it to use new/changed code. Anybody know how that's done?
thanks!
Colin
Twisted is the usual suspect. Reloading in the case of mod_wsgi is easy since only the WSGI server needs to be restarted, not the whole web server (not that restarting the web server is all that hard, mind you...).
Use Apache, mod_wsgi in daemon mode and follow these guidelines.
Update: I mentioned Apache because you did in your question - I assumed you were talking about a web application that also acted as a socket server.
The Python library has socket servers (see the documentation). AFAIK you can't do hot code reloading in Python without potentially losing packets, for that you would need something specifically designed for hot code reloading, such as Erlang, or else just have a dumb socket receiver which receives and queues packets, and a smarter backend process which does code reloading and packet handling. In that case, your receiver would be acting as a proxy.

Categories