From a4408b5ac4ec10421bf9a7d5bf277946ec9f786e Mon Sep 17 00:00:00 2001 From: Rutger Broekhoff Date: Thu, 10 Sep 2026 10:59:59 +0200 Subject: Timing and slow locale negotation fixes --- server/src/srv.cpp | 88 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 79 insertions(+), 9 deletions(-) (limited to 'server/src/srv.cpp') diff --git a/server/src/srv.cpp b/server/src/srv.cpp index f79da33..adfef18 100644 --- a/server/src/srv.cpp +++ b/server/src/srv.cpp @@ -51,12 +51,43 @@ auto gpx_parse_error() noexcept -> std::error_code class gpx_parse_result { + chrono::steady_clock::duration init_parse_dur_; + chrono::steady_clock::duration put_parse_dur_; + chrono::steady_clock::duration finish_parse_dur_; std::variant res_; public: auto set_exception(std::exception_ptr ex) noexcept { res_ = ex; } auto set_gpx_file(gpx::file&& f) noexcept { res_ = std::move(f); } + auto init_parse_duration(chrono::steady_clock::duration dur) noexcept + { + init_parse_dur_ = dur; + } + [[nodiscard]] auto init_parse_duration() const noexcept + -> chrono::steady_clock::duration + { + return init_parse_dur_; + } + auto put_parse_duration(chrono::steady_clock::duration dur) noexcept + { + put_parse_dur_ = dur; + } + [[nodiscard]] auto put_parse_duration() const noexcept + -> chrono::steady_clock::duration + { + return put_parse_dur_; + } + auto finish_parse_duration(chrono::steady_clock::duration dur) noexcept + { + finish_parse_dur_ = dur; + } + [[nodiscard]] auto finish_parse_duration() const noexcept + -> chrono::steady_clock::duration + { + return finish_parse_dur_; + } + auto unwrap() -> gpx::file&& { return std::visit( @@ -82,11 +113,15 @@ struct readable_gpx_body { gpx::reader r_; util::not_null res_; + std::inplace_vector buf_; public: template explicit reader(bhttp::header&, value_type& v) : res_{&v} { + res_->init_parse_duration({}); + res_->put_parse_duration({}); + res_->finish_parse_duration({}); } // The following methods (which are called by Beast) are marked @@ -99,6 +134,7 @@ struct readable_gpx_body init(boost::optional /* n */, beast::error_code& ec) noexcept -> void { + auto const init_start = chrono::steady_clock::now(); try { r_.init(); @@ -109,23 +145,38 @@ struct readable_gpx_body res_->set_exception(std::current_exception()); ec = gpx_parse_error(); } + res_->init_parse_duration(chrono::steady_clock::now() - init_start); } auto put(beast::concepts::const_buffer_sequence auto b, beast::error_code& ec) noexcept -> std::size_t { + auto const put_start = chrono::steady_clock::now(); auto total = 0uz; try { for (auto it = net::buffer_sequence_begin(b); it != net::buffer_sequence_end(b); it++) { - r_.put( - std::string_view{ - static_cast(it->data()), it->size() - }); - total += it->size(); + auto cur_in_buf = net::const_buffer{*it}; + while (cur_in_buf.size() > 0) + { + auto to_read = + std::min(cur_in_buf.size(), buf_.max_size() - buf_.size()); + buf_.append_range( + std::span{ + static_cast(cur_in_buf.data()), to_read + }); + cur_in_buf += to_read; + total += to_read; + + if (buf_.size() == buf_.max_size()) + { + r_.put(std::string_view{buf_}); + buf_.clear(); + } + } } ec = {}; } @@ -134,13 +185,23 @@ struct readable_gpx_body res_->set_exception(std::current_exception()); ec = gpx_parse_error(); } + res_->put_parse_duration( + res_->put_parse_duration() + + (chrono::steady_clock::now() - put_start)); return total; } auto finish(beast::error_code& ec) noexcept { + auto const finish_start = chrono::steady_clock::now(); try { + if (buf_.size() > 0) + { + r_.put(std::string_view{buf_}); + buf_.clear(); + } + res_->set_gpx_file(r_.finish()); ec = {}; } @@ -149,6 +210,7 @@ struct readable_gpx_body res_->set_exception(std::current_exception()); ec = gpx_parse_error(); } + res_->finish_parse_duration(chrono::steady_clock::now() - finish_start); } }; }; @@ -168,12 +230,18 @@ auto handler::handle_process_gpx(l0_ctx ctx, http::readable_request r) auto const before_read_gpx = chrono::steady_clock::now(); auto req = co_await http::read_request(ctx, std::move(r)); - gpx_file = std::move(req->body().unwrap()); l.debug( - "Read GPX request body in {}", + "Read GPX request body in {}; init took {}, actual parsing {}, " + "finishing {}", chrono::duration{ chrono::steady_clock::now() - before_read_gpx + }, + chrono::duration{req->body().init_parse_duration()}, + chrono::duration{req->body().put_parse_duration()}, + chrono::duration{ + req->body().finish_parse_duration() }); + gpx_file = std::move(req->body().unwrap()); } catch (std::exception& ex) { @@ -251,8 +319,10 @@ auto server::make_global_middleware(config::http_server const& cfg) { return http:: middleware_compose( - http::trace_id_middleware, - http::cors_middleware(cfg.allow_origins)); + http::expose_content_language_middleware, + middleware_compose( + http::expose_trace_id_middleware, + http::cors_middleware(cfg.allow_origins))); } server::server( -- cgit v1.3