HttpConnection: migrate connections to a dedicated scheduler

GitOrigin-RevId: 91ece928204ee732e81eaedd5e869810c5bea3b8
This commit is contained in:
Arseny Smirnov 2020-07-23 19:47:12 +03:00
parent 8132c4dfd3
commit 04667e86a7
7 changed files with 27 additions and 11 deletions

View File

@ -17,13 +17,14 @@ namespace td {
namespace detail {
HttpConnectionBase::HttpConnectionBase(State state, SocketFd fd, SslStream ssl_stream, size_t max_post_size,
size_t max_files, int32 idle_timeout)
size_t max_files, int32 idle_timeout, int32 slow_scheduler_id)
: state_(state)
, fd_(std::move(fd))
, ssl_stream_(std::move(ssl_stream))
, max_post_size_(max_post_size)
, max_files_(max_files)
, idle_timeout_(idle_timeout) {
, idle_timeout_(idle_timeout)
, slow_scheduler_id_(slow_scheduler_id) {
CHECK(state_ != State::Close);
if (ssl_stream_) {
@ -109,9 +110,18 @@ void HttpConnectionBase::loop() {
// TODO: read_next even when state_ == State::Write
bool want_read = false;
bool can_be_slow = slow_scheduler_id_ == -1;
if (state_ == State::Read) {
auto res = reader_.read_next(current_query_.get());
auto res = reader_.read_next(current_query_.get(), can_be_slow);
if (res.is_error()) {
if (res.error().message() == "SLOW") {
LOG(INFO) << "Slow HTTP connection: migrate to " << slow_scheduler_id_;
CHECK(!can_be_slow);
yield();
migrate(slow_scheduler_id_);
slow_scheduler_id_ = -1;
return;
}
live_event();
state_ = State::Write;
LOG(INFO) << res.error();

View File

@ -33,7 +33,7 @@ class HttpConnectionBase : public Actor {
protected:
enum class State { Read, Write, Close };
HttpConnectionBase(State state, SocketFd fd, SslStream ssl_stream, size_t max_post_size, size_t max_files,
int32 idle_timeout);
int32 idle_timeout, int32 slow_scheduler_id);
private:
State state_;
@ -57,6 +57,8 @@ class HttpConnectionBase : public Actor {
unique_ptr<HttpQuery> current_query_;
bool close_after_write_ = false;
int32 slow_scheduler_id_{-1};
void live_event();
void start_up() override;

View File

@ -13,8 +13,9 @@
namespace td {
HttpInboundConnection::HttpInboundConnection(SocketFd fd, size_t max_post_size, size_t max_files, int32 idle_timeout,
ActorShared<Callback> callback)
: HttpConnectionBase(State::Read, std::move(fd), SslStream(), max_post_size, max_files, idle_timeout)
ActorShared<Callback> callback, int32 slow_scheduler_id)
: HttpConnectionBase(State::Read, std::move(fd), SslStream(), max_post_size, max_files, idle_timeout,
slow_scheduler_id)
, callback_(std::move(callback)) {
}

View File

@ -28,7 +28,7 @@ class HttpInboundConnection final : public detail::HttpConnectionBase {
// void write_error(Status error);
HttpInboundConnection(SocketFd fd, size_t max_post_size, size_t max_files, int32 idle_timeout,
ActorShared<Callback> callback);
ActorShared<Callback> callback, int32 slow_scheduler_id = -1);
private:
void on_query(unique_ptr<HttpQuery> query) override;

View File

@ -25,9 +25,9 @@ class HttpOutboundConnection final : public detail::HttpConnectionBase {
virtual void on_connection_error(Status error) = 0; // TODO rename to on_error
};
HttpOutboundConnection(SocketFd fd, SslStream ssl_stream, size_t max_post_size, size_t max_files, int32 idle_timeout,
ActorShared<Callback> callback)
ActorShared<Callback> callback, int32 slow_scheduler_id = -1)
: HttpConnectionBase(HttpConnectionBase::State::Write, std::move(fd), std::move(ssl_stream), max_post_size,
max_files, idle_timeout)
max_files, idle_timeout, slow_scheduler_id)
, callback_(std::move(callback)) {
}
// Inherited interface

View File

@ -60,7 +60,7 @@ void HttpReader::init(ChainBufferReader *input, size_t max_post_size, size_t max
total_headers_length_ = 0;
}
Result<size_t> HttpReader::read_next(HttpQuery *query) {
Result<size_t> HttpReader::read_next(HttpQuery *query, bool can_be_slow) {
if (query_ != query) {
CHECK(query_ == nullptr);
query_ = query;
@ -191,6 +191,9 @@ Result<size_t> HttpReader::read_next(HttpQuery *query) {
return need_size;
}
case State::ReadContentToFile: {
if (!can_be_slow) {
return Status::Error("SLOW");
}
// save content to a file
if (temp_file_.empty()) {
auto file = open_temp_file("file");

View File

@ -27,7 +27,7 @@ class HttpReader {
public:
void init(ChainBufferReader *input, size_t max_post_size = std::numeric_limits<size_t>::max(),
size_t max_files = 100);
Result<size_t> read_next(HttpQuery *query) TD_WARN_UNUSED_RESULT; // TODO move query to init
Result<size_t> read_next(HttpQuery *query, bool can_be_slow = true) TD_WARN_UNUSED_RESULT; // TODO move query to init
HttpReader() = default;
HttpReader(const HttpReader &other) = delete;