How does apache runs a application when a request comes in? - python

I have a python web application running on apache2 deployed with mod_wsgi. The application has a thread continuously running. This thread is a ZeroMQ thread and listening to a port in loop. The application is not maintaining session. Now if I open the browser and sends a request to the apache server the data is accepted for the first time. Now when second time I send the request It shows Internal server error. When I checked the error log file for traceback, It shows the ZMQError:- The address already in use.
Does apache reloads the application on each request sent from the browser since so that the ZeroMQ thread is being created everytime and being assigned the port but since the port has already been assigned it shows error....

It looks like your application is using zmq to bind to some port.
As you have suspected already, each request can be run as independent process, thus competing in access to the port to bind to.
There can be so called workers, each running one process processing http/wsgi requests, and each trying to bind.
You shall redesign your app not to use bind, but connect, this will probably require having another process with zeromq serving something you do with that (but this last line is dependent on what you do in your app).

Related

Keep Flask with RabbitMQ app running on IIS

When my Flask app is launched, it starts a RabbitMQ consumer on a new thread. The consumer should keep running regardless of requests/responses and wait for incoming messages. Everything works fine when running locally and also when I deploy the app on linux.
Unfortunatly, due to some third-party dependencies I must deploy the app on a Windows server. I am able to configure IIS to serve the app using wfastcgi, but it seems that after some time with no activity the app gets shutdown until the next HTTP request, when it is automatically initalized again. This behaviour would not bother me normally, but it in this case the RabbitMQ consumer is also closed every time and then the incoming messages from the queue are not recieved.
Is there a way to keep the app running infinitly?
I saw some settings in IIS like Activity Timeout, Idle Timeout, etc. but I don't know which one is relevant. Also, what if I want the app to keep running and consuming messages from RabbitMQ even if there are no requests for a very long time, e.g. months or years?

Get nodejs server to trigger a python script

I have a node.js server running on a Raspberry Pi 3 B+. (I'm using node because I need the capabilities of a bluetooth library that works well).
Once the node server picks up a message from a bluetooth device, I want it to fire off an event/command/call to a different python script running on the same device.
What is the best way to do this? I've looked into spawning child processes and running the script in them, but that seems messy... Additionally, should I set up a socket between them and stream data through it? I imagine this is done often, what is the consensus solution?
Running a child process is how you would run a python script. That's how you do it from nodejs or any other program (besides a python program).
There are dozens of options for communicating between the python script and the nodejs program. The simplest would be stdin/stdout which are automatically set up for you when you create the child process, but you could also give the nodejs app a local http server that the python script could communicate with or vice versa.
Or, set up a regular socket between the two.
If, as you now indicate in a comment, your python script is already running, then you may want to use a local http server in the nodejs app and the python script can just send an http request to that local http server whenever it has some data it wants to pass to the nodejs app. Or, if you primarily want data to flow the opposite direction, you can put the http server in the python app and have the nodejs server send data to the python app.
If you want good bidirectional capabilities, then you could also set up a socket.io connection between the two and then you can easily send messages either way at any time.

Flask allows multiple server instances to listen on the same port

I have been using flask and noticed this unusual behavior.
My flask application is set to run on port 5000 in my machine (It has only one network card).
When I attempt to start more than one instance of the same flask application in my machine.
What I Expected:
A port address in use error when attempting to start the next instance bound on the same port.
What actually happened:
They all start successfully and bind to the same port. This kind of behavior is not expected with most conventional servers that I have used.
Thankfully however, only one process out of the 'n' processes is triggered when a REST API call is made to the server.
Operating System: Windows
Can someone please explain why this behavior occurs, and how can I ensure that flask doesn't start the process successfully in such a case.
netstat -aon | find "5000"
TCP 127.0.0.1:5000 0.0.0.0:0 LISTENING 37036
TCP 127.0.0.1:5000 0.0.0.0:0 LISTENING 5024
TCP 127.0.0.1:5000 0.0.0.0:0 LISTENING 61684
The above are the 3 process that are running in parallel.
Additional Notes:
I am using this in a virtualenv.
The way I have written my flask invocation.
if __name__ == "__main__":
main()
app.run(port=5000)
Running the code as python3 <filename>.py at the command prompt.
This is likely Windows specific behavior and how they manage sockets. On Windows, you can have multiple processes bind to the same port for listening. This was found to cause a lot of security issues, so Windows released updates that can prevent a port from being hi-jacked by another process via the SO_EXCLUSIVEADDRUSE socket flag. You can read more about it at https://learn.microsoft.com/en-us/windows/desktop/winsock/so-exclusiveaddruse
From what I can see by reading through the flask development server code, there is no way for a user to set the SO_EXCLUSIVEADDRUSE flag.

flask socket-io, sometimes client calls freeze the server

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.

Raspberry Pi python app and nodejs socketio communication

My requirement is to communicate socketio with nodejs server to Raspberry Pi running a local Python app. Please help me. I can find ways of communication with web app on google but is there any way to communicate with Python local app with above mentioned requirements.
It's unclear exactly which part you need help with. To make a socket.io connection work, you do the following:
Run a socket.io server on one of your two computers. Make sure it is listening on a known port (it can share a port with a web server if desired).
On the other computer, get a socket.io client library and use that to make a socket.io connection to the other computer.
Register message handlers on both computers for whatever custom messages you intend to send each way and write the code to process those incoming messages.
Write the code to send messages to the other computer at the appropriate time.
Socket.io client and server libraries exist for both node.js and python so you can either type of library for either type of system.
The important things to understand are that you must have a socket.io server up and running. The other endpoint then must connect to that server. Once the connection is up and running, you can then send message from either end to the other end.
For example, you could set up a socket.io server on node.js. Then, use a socket.io client library for python to make a socket.io connection to the node.js server. Then, once the connection is up and running, you are free to send messages from either end to the other and, if you have, message handlers listening for those specific messages, they will be received by the other end.

Categories