summaryrefslogtreecommitdiffstats
path: root/server/src/srv.cpp
diff options
context:
space:
mode:
authorRutger Broekhoff2026-09-10 10:59:59 +0200
committerRutger Broekhoff2026-09-10 10:59:59 +0200
commita4408b5ac4ec10421bf9a7d5bf277946ec9f786e (patch)
tree0a5214580a1557b3eb85f0a3ab0e15c5c9ec9f50 /server/src/srv.cpp
parent4031e77edd2abd694114be698312d086bce6b425 (diff)
downloadroutemon-a4408b5ac4ec10421bf9a7d5bf277946ec9f786e.tar.gz
routemon-a4408b5ac4ec10421bf9a7d5bf277946ec9f786e.zip
Timing and slow locale negotation fixesHEADmain
Diffstat (limited to 'server/src/srv.cpp')
-rw-r--r--server/src/srv.cpp88
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
52class gpx_parse_result 52class 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
56public: 59public:
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
258server::server( 328server::server(