nginx / unit

NGINX Unit - universal web app server - a lightweight and versatile open source server that simplifies the application stack by natively executing application code across eight different programming language runtimes.
https://unit.nginx.org
Apache License 2.0
5.33k stars 323 forks source link

Broken Pipe, then duplicated process #248

Open vlevieux opened 5 years ago

vlevieux commented 5 years ago

Hello

Context: I am running a python Flask application with Nginx Unit which sends continuously Server-Sent-Event (SSE) to a client. There is a timeout to avoid infinite loops in the application. It's a streaming application.

Problem: When the client closes the browser while the application is still sending SSE, Nginx Unit has the following error :

2019/04/25 04:36:43 [error] 1679#1684 *26 writev(26, 2) failed (32: Broken pipe)

Then, Unit creates another process for this application but does not kill the previous one.

# This one has crashed.
nginx-u+  1690  0.0  2.7 119852 27772 ?        S    04:32   0:00 unit: "stream_log_app" application
# This one has been started after the other crashed.
nginx-u+  1734  0.0  2.6 109148 26688 ?        S    04:35   0:00 unit: "stream_log_app" application

After that, the application is not reachable. I have to kill the process that has crashed. (kill -9 1690), then the second process becomes reachable.

Questions:

Thank you in advance.

mar0x commented 5 years ago

Hello,

Currently Unit does not notifies applications about "client disconnection". This why such a "streaming" servers will not work properly.

Your application is not crashed. It is unaware about client disconnection and keep sending infinite response to Unit. Second instance is started to serve another request. Most likely because it is configured so (need to check the config to be 100% sure). From the current Unit perspective application is alive and generating the response. When it finishes, it can be stopped or next request will be passed to it.

For now there is no solution to support your application, sorry. We need to think how to redesign communication between Unit and application to support streaming.

vlevieux commented 5 years ago

Thank you, for your answer @mar0x . I hope to see this feature implemented in future updates.

You were exactly right. If I only use 1 process, the process becomes blocked until it has reached my custom timeout and does not crash.

I know that Flask applications have a threaded option that is enabled by default which works with Werkzeug Web server when developing and testing Flask applications. But the PEP 333 states:

Thread support, or lack thereof, is also server-dependent.

Then I think, correct me if I am wrong, that Unit only uses by default one single process (a process that could be considered as a process with a single thread) for each WSGI application, then Unit does not support multithreading natively.

This is the configuration that I used:

{
    "listeners": {
        "*:8082": {
            "pass": "applications/stream_log_app"
        }
    },
    "applications": {
        "stream_log_app": {
            "group": "nginx-unit",
            "home": "/opt/unit/stream_log_app/venv/",
            "module": "service",
            "path": "/opt/unit/stream_log_app/",
            "type": "python 3.5",
            "user": "nginx-unit"
        }
}
N1GHTR4NG3R commented 5 years ago

Running php7.3-fpm On a Unit / Wordpress install also gives a broken pipe (32) - Which leaves this in the log:

2019/07/21 08:13:02 [alert] 13112#13112: 2 open socket #20 left in connection 5 2019/07/21 08:13:02 [alert] 13112#13112: aborting 2019/07/21 08:29:13 [alert] 13186#13186: 2 open socket #20 left in connection 5 2019/07/21 08:29:13 [alert] 13186#13186: aborting 2019/07/21 08:58:38 [alert] 13353#13353: 21 open socket #20 left in connection 8 2019/07/21 08:58:38 [alert] 13353#13353: aborting 2019/07/21 09:02:14 [alert] 13480#13480: 2 open socket #20 left in connection 5 2019/07/21 09:02:14 [alert] 13480#13480: aborting 2019/07/21 10:16:27 [alert] 14325#14325: *8 open socket #19 left in connection 4 2019/07/21 10:16:27 [alert] 14325#14325: aborting

Would this be related?

kbzowski commented 8 months ago

I have notice similar behaviour in my nodejs app:

2023/11/29 15:01:45 [info] 208#235 *265 writev(37, 2) failed (32: Broken pipe)
2023/11/29 15:05:02 [info] 208#235 *409 writev(37, 2) failed (32: Broken pipe)
2023/11/29 15:06:03 [info] 208#235 *473 writev(37, 2) failed (32: Broken pipe)
2023/11/29 15:09:53 [info] 208#235 *655 writev(37, 2) failed (32: Broken pipe)
2023/11/29 15:10:12 [info] 208#235 *671 writev(37, 2) failed (32: Broken pipe)
2023/11/29 15:12:23 [info] 208#235 *786 writev(37, 4) failed (32: Broken pipe)

Any tips on how to debug the problem? This is a typical REST API - no streaming. In my case, application is still reachable. There is only one instance of the app.

ac000 commented 8 months ago

@kbzowski

These messages do not necessarily indicate an actual issue. Are you seeing some actual misbehaviour in your application?