http: Make server shutdown more robust #31929

pull hodlinator wants to merge 4 commits into bitcoin:master from hodlinator:2025/02/stop_http_robust changing 3 files +46 −21
  1. hodlinator commented at 3:32 pm on February 21, 2025: contributor
    • Instead of hanging indefinitely, use timeouts and abort when HTTP connections take unreasonably long to close.
    • Add request id with logging to be able to discover which one is stuck.
    • Ensure we always free libevent HTTP.
    • Improve documentation around libevent behavior.

    Should help debug #31894.

  2. doc http: Improve documentation around (libevent) HTTP shutdown behavior 1350087f9a
  3. http: Ensure eventHTTP is always freed
    There is a race between ThreadHTTP exiting and our queuing of the freeing-event (event_base_once).
    
    Additional free was useful in 709 of 962 runs.
    757de96db5
  4. http: Abort with clear error instead of hanging forever
    Could happen when connection doesn't complete for some reason.
    
    Output early warning to give clue about what's up.
    
    Prior check+log message before even starting to wait was a bit too eager to hint at something being wrong.
    a00dfd2046
  5. DrahtBot commented at 3:33 pm on February 21, 2025: contributor

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    Code Coverage & Benchmarks

    For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/31929.

    Reviews

    See the guideline for information on the review process. A summary of reviews will appear here.

  6. DrahtBot added the label RPC/REST/ZMQ on Feb 21, 2025
  7. fanquake commented at 3:49 pm on February 21, 2025: member
    0Assertion failed: (evb), function WriteReply, file httpserver.cpp, line 682.
    1Error processing input "/Users/runner/work/bitcoin/bitcoin/ci/scratch/qa-assets/fuzz_corpora/http_request/83149a7e3abd937c7bc67fa55b9a4fc9338e3d8c"
    2
    3⚠️ Failure generated from target with exit code 1: ['/Users/runner/work/bitcoin/bitcoin/ci/scratch/build-aarch64-apple-darwin23.6.0/src/test/fuzz/fuzz', PosixPath('/Users/runner/work/bitcoin/bitcoin/ci/scratch/qa-assets/fuzz_corpora/http_request')]
    
  8. DrahtBot added the label CI failed on Feb 21, 2025
  9. DrahtBot commented at 5:05 pm on February 21, 2025: contributor

    🚧 At least one of the CI tasks failed. Debug: https://github.com/bitcoin/bitcoin/runs/37612857743

    Try to run the tests locally, according to the documentation. However, a CI failure may still happen due to a number of reasons, for example:

    • Possibly due to a silent merge conflict (the changes in this pull request being incompatible with the current code in the target branch). If so, make sure to rebase on the latest commit of the target branch.

    • A sanitizer issue, which can only be found by compiling with the sanitizer and running the affected test.

    • An intermittent issue.

    Leave a comment here, if you need help tracking down a confusing failure.

  10. http: Add logged request ids
    Could aid debugging when an HTTP request gets stuck at shutdown.
    24558c2cf1
  11. hodlinator force-pushed on Feb 21, 2025
  12. DrahtBot removed the label CI failed on Feb 22, 2025
  13. in src/httpserver.cpp:559 in 24558c2cf1
    564-        // that evhttp_free does not need to be called again after the handling
    565-        // of unfinished request connections that follows.
    566-        event_base_once(eventBase, -1, EV_TIMEOUT, [](evutil_socket_t, short, void*) {
    567+        // Schedule a callback to call evhttp_free in the event base thread, as
    568+        // otherwise eventHTTP often keeps internal events alive, meaning
    569+        // aforementioned thread would never run out of events and exit.
    


    hodlinator commented at 3:24 pm on February 22, 2025:

    To verify the improved accuracy of the documentation here one can apply:

     0diff --git a/src/httpserver.cpp b/src/httpserver.cpp
     1index 52fa8463d2..a3efaa2579 100644
     2--- a/src/httpserver.cpp
     3+++ b/src/httpserver.cpp
     4@@ -557,6 +557,10 @@ void StopHTTPServer()
     5         // Schedule a callback to call evhttp_free in the event base thread, as
     6         // otherwise eventHTTP often keeps internal events alive, meaning
     7         // aforementioned thread would never run out of events and exit.
     8+        while (true) {
     9+            event_base_dump_events(eventBase, stderr);
    10+            std::this_thread::sleep_for(5s);
    11+        }
    12         if (event_base_once(eventBase, -1, EV_TIMEOUT, [](evutil_socket_t, short, void*) {
    13             evhttp_free(eventHTTP);
    14             eventHTTP = nullptr;
    

    Run bitcoind, and then send the stop-RPC from bitcoin-cli. It gave me the following log:

     02025-02-22T15:18:19Z [http] Stopping HTTP server
     12025-02-22T15:18:19Z [http] Waiting for HTTP worker threads to exit
     2Inserted events:
     32025-02-22T15:18:19Z [http] Exited http event loop
     4  0x555556947a50 [fd  11] Read Persist Internal
     5Active events:
     62025-02-22T15:18:19Z net thread exit
     72025-02-22T15:18:20Z msghand thread exit
     8Inserted events:
     9  0x555556947a50 [fd  11] Read Persist Internal
    10Active events:
    11Inserted events:
    12  0x555556947a50 [fd  11] Read Persist Internal
    13Active events:
    14Inserted events:
    15  0x555556947a50 [fd  11] Read Persist Internal
    16Active events:
    17<repeated until killing the process>
    
  14. hodlinator commented at 3:28 pm on February 22, 2025: contributor
    The fuzz-failure was me underestimating a default-initialized argument. Fixed in 2nd push.

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2025-02-22 21:13 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me