diff options
| author | Rutger Broekhoff | 2026-09-10 10:59:59 +0200 |
|---|---|---|
| committer | Rutger Broekhoff | 2026-09-10 10:59:59 +0200 |
| commit | a4408b5ac4ec10421bf9a7d5bf277946ec9f786e (patch) | |
| tree | 0a5214580a1557b3eb85f0a3ab0e15c5c9ec9f50 /server/src/srv.cpp | |
| parent | 4031e77edd2abd694114be698312d086bce6b425 (diff) | |
| download | routemon-main.tar.gz routemon-main.zip | |
Diffstat (limited to 'server/src/srv.cpp')
| -rw-r--r-- | server/src/srv.cpp | 88 |
1 files changed, 79 insertions, 9 deletions
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 | |||
| 51 | 51 | ||
| 52 | class gpx_parse_result | 52 | class gpx_parse_result |
| 53 | { | 53 | { |
| 54 | chrono::steady_clock::duration init_parse_dur_; | ||
| 55 | chrono::steady_clock::duration put_parse_dur_; | ||
| 56 | chrono::steady_clock::duration finish_parse_dur_; | ||
| 54 | std::variant<std::exception_ptr, gpx::file> res_; | 57 | std::variant<std::exception_ptr, gpx::file> res_; |
| 55 | 58 | ||
| 56 | public: | 59 | public: |
| 57 | auto set_exception(std::exception_ptr ex) noexcept { res_ = ex; } | 60 | auto set_exception(std::exception_ptr ex) noexcept { res_ = ex; } |
| 58 | auto set_gpx_file(gpx::file&& f) noexcept { res_ = std::move(f); } | 61 | auto set_gpx_file(gpx::file&& f) noexcept { res_ = std::move(f); } |
| 59 | 62 | ||
| 63 | auto init_parse_duration(chrono::steady_clock::duration dur) noexcept | ||
| 64 | { | ||
| 65 | init_parse_dur_ = dur; | ||
| 66 | } | ||
| 67 | [[nodiscard]] auto init_parse_duration() const noexcept | ||
| 68 | -> chrono::steady_clock::duration | ||
| 69 | { | ||
| 70 | return init_parse_dur_; | ||
| 71 | } | ||
| 72 | auto put_parse_duration(chrono::steady_clock::duration dur) noexcept | ||
| 73 | { | ||
| 74 | put_parse_dur_ = dur; | ||
| 75 | } | ||
| 76 | [[nodiscard]] auto put_parse_duration() const noexcept | ||
| 77 | -> chrono::steady_clock::duration | ||
| 78 | { | ||
| 79 | return put_parse_dur_; | ||
| 80 | } | ||
| 81 | auto finish_parse_duration(chrono::steady_clock::duration dur) noexcept | ||
| 82 | { | ||
| 83 | finish_parse_dur_ = dur; | ||
| 84 | } | ||
| 85 | [[nodiscard]] auto finish_parse_duration() const noexcept | ||
| 86 | -> chrono::steady_clock::duration | ||
| 87 | { | ||
| 88 | return finish_parse_dur_; | ||
| 89 | } | ||
| 90 | |||
| 60 | auto unwrap() -> gpx::file&& | 91 | auto unwrap() -> gpx::file&& |
| 61 | { | 92 | { |
| 62 | return std::visit( | 93 | return std::visit( |
| @@ -82,11 +113,15 @@ struct readable_gpx_body | |||
| 82 | { | 113 | { |
| 83 | gpx::reader r_; | 114 | gpx::reader r_; |
| 84 | util::not_null<value_type*> res_; | 115 | util::not_null<value_type*> res_; |
| 116 | std::inplace_vector<char, 4096> buf_; | ||
| 85 | 117 | ||
| 86 | public: | 118 | public: |
| 87 | template <bool isRequest, bhttp::concepts::fields Fields> | 119 | template <bool isRequest, bhttp::concepts::fields Fields> |
| 88 | explicit reader(bhttp::header<isRequest, Fields>&, value_type& v) : res_{&v} | 120 | explicit reader(bhttp::header<isRequest, Fields>&, value_type& v) : res_{&v} |
| 89 | { | 121 | { |
| 122 | res_->init_parse_duration({}); | ||
| 123 | res_->put_parse_duration({}); | ||
| 124 | res_->finish_parse_duration({}); | ||
| 90 | } | 125 | } |
| 91 | 126 | ||
| 92 | // The following methods (which are called by Beast) are marked | 127 | // The following methods (which are called by Beast) are marked |
| @@ -99,6 +134,7 @@ struct readable_gpx_body | |||
| 99 | init(boost::optional<std::uint64_t> /* n */, beast::error_code& ec) noexcept | 134 | init(boost::optional<std::uint64_t> /* n */, beast::error_code& ec) noexcept |
| 100 | -> void | 135 | -> void |
| 101 | { | 136 | { |
| 137 | auto const init_start = chrono::steady_clock::now(); | ||
| 102 | try | 138 | try |
| 103 | { | 139 | { |
| 104 | r_.init(); | 140 | r_.init(); |
| @@ -109,23 +145,38 @@ struct readable_gpx_body | |||
| 109 | res_->set_exception(std::current_exception()); | 145 | res_->set_exception(std::current_exception()); |
| 110 | ec = gpx_parse_error(); | 146 | ec = gpx_parse_error(); |
| 111 | } | 147 | } |
| 148 | res_->init_parse_duration(chrono::steady_clock::now() - init_start); | ||
| 112 | } | 149 | } |
| 113 | 150 | ||
| 114 | auto | 151 | auto |
| 115 | put(beast::concepts::const_buffer_sequence auto b, | 152 | put(beast::concepts::const_buffer_sequence auto b, |
| 116 | beast::error_code& ec) noexcept -> std::size_t | 153 | beast::error_code& ec) noexcept -> std::size_t |
| 117 | { | 154 | { |
| 155 | auto const put_start = chrono::steady_clock::now(); | ||
| 118 | auto total = 0uz; | 156 | auto total = 0uz; |
| 119 | try | 157 | try |
| 120 | { | 158 | { |
| 121 | for (auto it = net::buffer_sequence_begin(b); | 159 | for (auto it = net::buffer_sequence_begin(b); |
| 122 | it != net::buffer_sequence_end(b); it++) | 160 | it != net::buffer_sequence_end(b); it++) |
| 123 | { | 161 | { |
| 124 | r_.put( | 162 | auto cur_in_buf = net::const_buffer{*it}; |
| 125 | std::string_view{ | 163 | while (cur_in_buf.size() > 0) |
| 126 | static_cast<char const*>(it->data()), it->size() | 164 | { |
| 127 | }); | 165 | auto to_read = |
| 128 | total += it->size(); | 166 | std::min(cur_in_buf.size(), buf_.max_size() - buf_.size()); |
| 167 | buf_.append_range( | ||
| 168 | std::span{ | ||
| 169 | static_cast<char const*>(cur_in_buf.data()), to_read | ||
| 170 | }); | ||
| 171 | cur_in_buf += to_read; | ||
| 172 | total += to_read; | ||
| 173 | |||
| 174 | if (buf_.size() == buf_.max_size()) | ||
| 175 | { | ||
| 176 | r_.put(std::string_view{buf_}); | ||
| 177 | buf_.clear(); | ||
| 178 | } | ||
| 179 | } | ||
| 129 | } | 180 | } |
| 130 | ec = {}; | 181 | ec = {}; |
| 131 | } | 182 | } |
| @@ -134,13 +185,23 @@ struct readable_gpx_body | |||
| 134 | res_->set_exception(std::current_exception()); | 185 | res_->set_exception(std::current_exception()); |
| 135 | ec = gpx_parse_error(); | 186 | ec = gpx_parse_error(); |
| 136 | } | 187 | } |
| 188 | res_->put_parse_duration( | ||
| 189 | res_->put_parse_duration() | ||
| 190 | + (chrono::steady_clock::now() - put_start)); | ||
| 137 | return total; | 191 | return total; |
| 138 | } | 192 | } |
| 139 | 193 | ||
| 140 | auto finish(beast::error_code& ec) noexcept | 194 | auto finish(beast::error_code& ec) noexcept |
| 141 | { | 195 | { |
| 196 | auto const finish_start = chrono::steady_clock::now(); | ||
| 142 | try | 197 | try |
| 143 | { | 198 | { |
| 199 | if (buf_.size() > 0) | ||
| 200 | { | ||
| 201 | r_.put(std::string_view{buf_}); | ||
| 202 | buf_.clear(); | ||
| 203 | } | ||
| 204 | |||
| 144 | res_->set_gpx_file(r_.finish()); | 205 | res_->set_gpx_file(r_.finish()); |
| 145 | ec = {}; | 206 | ec = {}; |
| 146 | } | 207 | } |
| @@ -149,6 +210,7 @@ struct readable_gpx_body | |||
| 149 | res_->set_exception(std::current_exception()); | 210 | res_->set_exception(std::current_exception()); |
| 150 | ec = gpx_parse_error(); | 211 | ec = gpx_parse_error(); |
| 151 | } | 212 | } |
| 213 | res_->finish_parse_duration(chrono::steady_clock::now() - finish_start); | ||
| 152 | } | 214 | } |
| 153 | }; | 215 | }; |
| 154 | }; | 216 | }; |
| @@ -168,12 +230,18 @@ auto handler::handle_process_gpx(l0_ctx ctx, http::readable_request r) | |||
| 168 | auto const before_read_gpx = chrono::steady_clock::now(); | 230 | auto const before_read_gpx = chrono::steady_clock::now(); |
| 169 | auto req = | 231 | auto req = |
| 170 | co_await http::read_request<readable_gpx_body>(ctx, std::move(r)); | 232 | co_await http::read_request<readable_gpx_body>(ctx, std::move(r)); |
| 171 | gpx_file = std::move(req->body().unwrap()); | ||
| 172 | l.debug( | 233 | l.debug( |
| 173 | "Read GPX request body in {}", | 234 | "Read GPX request body in {}; init took {}, actual parsing {}, " |
| 235 | "finishing {}", | ||
| 174 | chrono::duration<double, std::milli>{ | 236 | chrono::duration<double, std::milli>{ |
| 175 | chrono::steady_clock::now() - before_read_gpx | 237 | chrono::steady_clock::now() - before_read_gpx |
| 238 | }, | ||
| 239 | chrono::duration<double, std::milli>{req->body().init_parse_duration()}, | ||
| 240 | chrono::duration<double, std::milli>{req->body().put_parse_duration()}, | ||
| 241 | chrono::duration<double, std::milli>{ | ||
| 242 | req->body().finish_parse_duration() | ||
| 176 | }); | 243 | }); |
| 244 | gpx_file = std::move(req->body().unwrap()); | ||
| 177 | } | 245 | } |
| 178 | catch (std::exception& ex) | 246 | catch (std::exception& ex) |
| 179 | { | 247 | { |
| @@ -251,8 +319,10 @@ auto server::make_global_middleware(config::http_server const& cfg) | |||
| 251 | { | 319 | { |
| 252 | return http:: | 320 | return http:: |
| 253 | middleware_compose<http::base_ctx, http::base_ctx, http::base_ctx>( | 321 | middleware_compose<http::base_ctx, http::base_ctx, http::base_ctx>( |
| 254 | http::trace_id_middleware<http::base_ctx>, | 322 | http::expose_content_language_middleware<http::base_ctx>, |
| 255 | http::cors_middleware<http::base_ctx>(cfg.allow_origins)); | 323 | middleware_compose<http::base_ctx, http::base_ctx, http::base_ctx>( |
| 324 | http::expose_trace_id_middleware<http::base_ctx>, | ||
| 325 | http::cors_middleware<http::base_ctx>(cfg.allow_origins))); | ||
| 256 | } | 326 | } |
| 257 | 327 | ||
| 258 | server::server( | 328 | server::server( |