unit icon indicating copy to clipboard operation
unit copied to clipboard

Broken Pipe, then duplicated process

Open vlevieux opened this issue 6 years ago • 5 comments
trafficstars

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:

  • Is there a solution so that the Broken Pipe error does not crash Unit?
  • Why does not Unit kill the process which has crashed?

Thank you in advance.

vlevieux avatar Apr 25 '19 04:04 vlevieux

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.

mar0x avatar Apr 25 '19 13:04 mar0x

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"
        }
}

vlevieux avatar Apr 25 '19 19:04 vlevieux

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?

N1GHTR4NG3R avatar Jul 22 '19 05:07 N1GHTR4NG3R

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.

kbzowski avatar Nov 29 '23 15:11 kbzowski

@kbzowski

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

ac000 avatar Nov 29 '23 15:11 ac000