Visitar URL original
Reserved file descriptors to guarantee response during EMFILE · Issue #1089 · yesodweb/wai · GitHub
Skip to content

Reserved file descriptors to guarantee response during EMFILE #1089

Open

Description

@steve-chavez

Problem

On PostgREST, we run two Warp servers. One the API server in one port with high traffic and an Admin server on another port with low traffic. The latter is mostly in charge of responding to health checks.

When EMFILE occurs during high traffic, the Admin server can get blocked and not reply to health checks; this can lead to orchestrators like Kubernetes to restart the process thinking it's malfunctioning.

Proposal

Reserve some file descriptors so the Admin server always responds. There was an idea on:

From what I read, Nginx opens a couple of /dev/null fds. Once it catches EMFILE it closes one of them and retries. This is, of course, racy and one needs to be careful not to consume freed fd somewhere else by accident.
PostgREST/postgrest#5078 (comment)

Activity

  1. kazu-yamamoto commented on Jul 19, 2026

    @kazu-yamamoto
    Contributor

    Does this still occur on warp 3.4.14 or later?
    In #1084, you said this bug has been fixed.

  2. steve-chavez commented on Jul 19, 2026

    @steve-chavez
    Author

    @kazu-yamamoto This is a different problem than #1084. #1084 was about ensuring a Warp server keeps responding to requests after another Warp server reaches EMFILE.

    This is about ensuring a low-traffic Warp server can always respond to requests while another high-traffic one is stuck waiting for file descriptors to become available.

  3. kazu-yamamoto commented on Jul 19, 2026

    @kazu-yamamoto
    Contributor

    Oh, I see.

  4. Vlix commented on Jul 23, 2026

    @Vlix
    Contributor

    In short @kazu-yamamoto
    #1084 was a bugfix
    #1089 (this) is a feature request


    @steve-chavez I understand where this want is coming from, but the raciness doesn't feel very good.
    If your API server is already exhausting most of your FDs, then I feel like the reserved FDs from the Admin server will just be used by the API server the moment they are released.

    This might sound like a small addition/QoL improvement, but there are a lot of externalities to keep in mind. Not to mention race conditions and potential deadlocks/permanent FD exhaustion, if this is implemented in the wrong way.

    There's also different strategies to consider:

    • dump ALL reserved FDs to increase the chance this server can grab one for the next request
    • release a few and hope whatever else is hogging FDs doesn't grab them before your server does
    • refill reserved FDs slowly / greedily
    • (and more that will show itself when a prototype is built)

    The one thing to keep in mind, though, is that warp already "reserves` at least one FD before a connection is accepted. So on a low-traffic server, the moment the last request was accepted, it will loop until an FD is free to then be ready to accept the next connection.
    If you have k8s pinging your server, let's say every 5 min for liveliness, and the low-traffic server can't accept the connection, that means in the 5 minutes since the last "health ping" it did not get a chance at any point to grab a FD. So either whatever else also needs FDs is WAY more greedy than the low-traffic server, or it has very long requests not letting go of any FDs.
    In the former, reserved FDs wouldn't do much; in the latter case, reserved FDs might work.

    TL;DR This will probably not get any priority atm. But if anyone else would want to try their hand at this in a PR, we can see where this goes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions