From 8419ddb4d82de3d8af010c9530f1f9abcd7ace47 Mon Sep 17 00:00:00 2001 From: Ali Mohammad Pur Date: Wed, 12 May 2021 04:26:25 +0430 Subject: [PATCH] RequestServer: Only attempt to flush() on a timer ...instead of doing so immediately. This makes RequestServer not spin as much when its client isn't fast enough to empty the download pipe. It also has the nice benefit of allowing multiple downloads to happen at the same time without one blocking the other too much. --- Userland/Libraries/LibHTTP/Job.cpp | 15 ++++++++++++--- Userland/Libraries/LibHTTP/Job.h | 1 + 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/Userland/Libraries/LibHTTP/Job.cpp b/Userland/Libraries/LibHTTP/Job.cpp index 8b67de60a1..6ead5fad10 100644 --- a/Userland/Libraries/LibHTTP/Job.cpp +++ b/Userland/Libraries/LibHTTP/Job.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -352,6 +353,14 @@ void Job::on_socket_connected() }); } +void Job::timer_event(Core::TimerEvent& event) +{ + event.accept(); + finish_up(); + if (m_buffered_size == 0) + stop_timer(); +} + void Job::finish_up() { m_state = State::Finished; @@ -382,9 +391,9 @@ void Job::finish_up() // before we can actually call `did_finish`. in a normal flow, this should // never be hit since the client is reading as we are writing, unless there // are too many concurrent downloads going on. - deferred_invoke([this](auto&) { - finish_up(); - }); + dbgln_if(JOB_DEBUG, "Flush finished with {} bytes remaining, will try again later", m_buffered_size); + if (!has_timer()) + start_timer(50); return; } diff --git a/Userland/Libraries/LibHTTP/Job.h b/Userland/Libraries/LibHTTP/Job.h index f878a4e8c5..83fcfd9613 100644 --- a/Userland/Libraries/LibHTTP/Job.h +++ b/Userland/Libraries/LibHTTP/Job.h @@ -42,6 +42,7 @@ protected: virtual bool is_established() const = 0; virtual bool should_fail_on_empty_payload() const { return true; } virtual void read_while_data_available(Function read) { read(); }; + virtual void timer_event(Core::TimerEvent&) override; enum class State { InStatus,