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.
This commit is contained in:
Ali Mohammad Pur 2021-05-12 04:26:25 +04:30 committed by Linus Groh
parent afa98fcb55
commit 8419ddb4d8
Notes: sideshowbarker 2024-07-18 18:19:08 +09:00
2 changed files with 13 additions and 3 deletions

View file

@ -7,6 +7,7 @@
#include <AK/Debug.h>
#include <LibCompress/Gzip.h>
#include <LibCompress/Zlib.h>
#include <LibCore/Event.h>
#include <LibCore/TCPSocket.h>
#include <LibHTTP/HttpResponse.h>
#include <LibHTTP/Job.h>
@ -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;
}

View file

@ -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<IterationDecision()> read) { read(); };
virtual void timer_event(Core::TimerEvent&) override;
enum class State {
InStatus,