Skip to content

Commit aee9cee

Browse files
authored
Merge Miss Code from LTS 1.2.0
1 parent 3078a83 commit aee9cee

File tree

34 files changed

+6737
-111
lines changed

34 files changed

+6737
-111
lines changed

include/ylt/coro_io/client_pool.hpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
#include <ylt/util/expected.hpp>
4444

4545
#include "async_simple/Future.h"
46+
#include "async_simple/coro/Mutex.h"
4647
#include "coro_io.hpp"
4748
#include "detail/client_queue.hpp"
4849
#include "io_context_pool.hpp"
@@ -156,7 +157,13 @@ class client_pool : public std::enable_shared_from_this<
156157
auto new_eps_ptr =
157158
std::make_shared<std::vector<asio::ip::tcp::endpoint>>(
158159
std::move(eps));
159-
self->eps_.store(std::move(new_eps_ptr), std::memory_order_release);
160+
auto is_lock = self->dns_cache_update_mutex_.tryLock();
161+
// store should'nt need lock ,but tsan show a data race here,
162+
// so we add a try lock here
163+
if (is_lock) [[likely]] {
164+
self->eps_.store(std::move(new_eps_ptr), std::memory_order_release);
165+
self->dns_cache_update_mutex_.unlock();
166+
}
160167
}
161168
}
162169
}
@@ -609,6 +616,7 @@ class client_pool : public std::enable_shared_from_this<
609616
std::atomic<bool> is_alive_ = true;
610617
std::atomic<uint64_t> timepoint_;
611618
ylt::util::atomic_shared_ptr<std::vector<asio::ip::tcp::endpoint>> eps_;
619+
async_simple::coro::Mutex dns_cache_update_mutex_;
612620
};
613621

614622
template <typename client_t,

include/ylt/metric/counter.hpp

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,17 @@ enum class op_type_t { INC, DEC, SET };
1515

1616
#ifdef CINATRA_ENABLE_METRIC_JSON
1717
struct json_counter_metric_t {
18-
std::vector<std::string_view> labels;
18+
std::vector<std::pair<std::string_view, std::string_view>> labels;
1919
std::variant<int64_t, double> value;
2020
};
2121
YLT_REFL(json_counter_metric_t, labels, value);
2222
struct json_counter_t {
2323
std::string_view name;
2424
std::string_view help;
2525
std::string_view type;
26-
std::vector<std::string_view> labels_name;
2726
std::vector<json_counter_metric_t> metrics;
2827
};
29-
YLT_REFL(json_counter_t, name, help, type, labels_name, metrics);
28+
YLT_REFL(json_counter_t, name, help, type, metrics);
3029
#endif
3130

3231
template <typename value_type>
@@ -51,9 +50,12 @@ class basic_static_counter : public static_metric {
5150
default_label_value_(dupli_count_) {}
5251

5352
void inc(value_type val = 1) {
54-
if (val <= 0) {
53+
if (val < 0) {
5554
return;
5655
}
56+
if (!has_change_.load(std::memory_order::relaxed)) [[unlikely]] {
57+
has_change_.store(true, std::memory_order::relaxed);
58+
}
5759
default_label_value_.inc(val);
5860
}
5961

@@ -87,14 +89,10 @@ class basic_static_counter : public static_metric {
8789

8890
json_counter_t counter{name_, help_, metric_name()};
8991

90-
counter.labels_name.reserve(static_labels_.size());
91-
for (auto &[k, _] : static_labels_) {
92-
counter.labels_name.emplace_back(k);
93-
}
9492
counter.metrics.resize(1);
9593
counter.metrics[0].labels.reserve(static_labels_.size());
96-
for (auto &[k, _] : static_labels_) {
97-
counter.metrics[0].labels.emplace_back(k);
94+
for (auto &[k, v] : static_labels_) {
95+
counter.metrics[0].labels.emplace_back(k, v);
9896
}
9997
counter.metrics[0].value = value;
10098
iguana::to_json(counter, str);
@@ -268,10 +266,6 @@ class basic_dynamic_counter
268266
void serialize_to_json(std::string &str) override {
269267
auto map = Base::copy();
270268
json_counter_t counter{Base::name_, Base::help_, Base::metric_name()};
271-
counter.labels_name.reserve(Base::labels_name().size());
272-
for (auto &e : Base::labels_name()) {
273-
counter.labels_name.emplace_back(e);
274-
}
275269
to_json(counter, map, str);
276270
}
277271

@@ -282,9 +276,9 @@ class basic_dynamic_counter
282276
auto &val = e->value;
283277
json_counter_metric_t metric;
284278
size_t index = 0;
285-
metric.labels.reserve(k.size());
279+
assert(Base::labels_name().size() == k.size());
286280
for (auto &label_value : k) {
287-
metric.labels.emplace_back(label_value);
281+
metric.labels.emplace_back(Base::labels_name()[index++], label_value);
288282
}
289283
metric.value = val.load(std::memory_order::relaxed);
290284
counter.metrics.push_back(std::move(metric));

include/ylt/metric/summary.hpp

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,32 @@
1717
namespace ylt::metric {
1818
#ifdef CINATRA_ENABLE_METRIC_JSON
1919
struct json_summary_metric_t {
20-
std::vector<std::string_view> labels;
21-
std::vector<float> quantiles_value;
20+
std::vector<std::pair<std::string_view, std::string_view>> labels;
21+
std::vector<std::pair<float, float>> quantiles;
2222
uint64_t count;
2323
double sum;
2424
};
25-
YLT_REFL(json_summary_metric_t, labels, quantiles_value, count, sum);
25+
YLT_REFL(json_summary_metric_t, labels, quantiles, count, sum);
2626
struct json_summary_t {
2727
std::string_view name;
2828
std::string_view help;
2929
std::string_view type;
30-
const std::vector<std::string>& labels_name;
31-
const std::vector<double>& quantiles_key;
3230
std::vector<json_summary_metric_t> metrics;
3331
};
34-
YLT_REFL(json_summary_t, name, help, type, labels_name, quantiles_key, metrics);
32+
YLT_REFL(json_summary_t, name, help, type, metrics);
3533
#endif
3634

35+
namespace detail {
36+
template <typename O, typename K, typename V>
37+
inline void vector_combine(O& result, const K& vec1, const V& vec2) {
38+
assert(vec1.size() == vec2.size());
39+
result.reserve(vec1.size());
40+
for (std::size_t i = 0; i < vec1.size(); ++i) {
41+
result.emplace_back(vec1[i], vec2[i]);
42+
}
43+
}
44+
} // namespace detail
45+
3746
class summary_t : public static_metric {
3847
public:
3948
summary_t(std::string name, std::string help, std::vector<double> quantiles,
@@ -42,8 +51,11 @@ class summary_t : public static_metric {
4251
quantiles_(std::move(quantiles)),
4352
impl_(quantiles_,
4453
std::chrono::duration_cast<std::chrono::seconds>(max_age)) {
45-
if (!std::is_sorted(quantiles_.begin(), quantiles_.end()))
54+
if (!std::is_sorted(quantiles_.begin(), quantiles_.end())) {
4655
std::sort(quantiles_.begin(), quantiles_.end());
56+
}
57+
auto iter = std::unique(quantiles_.begin(), quantiles_.end());
58+
quantiles_.erase(iter, quantiles_.end());
4759
}
4860

4961
summary_t(std::string name, std::string help, std::vector<double> quantiles,
@@ -54,8 +66,11 @@ class summary_t : public static_metric {
5466
quantiles_(std::move(quantiles)),
5567
impl_(quantiles_,
5668
std::chrono::duration_cast<std::chrono::seconds>(max_age)) {
57-
if (!std::is_sorted(quantiles_.begin(), quantiles_.end()))
69+
if (!std::is_sorted(quantiles_.begin(), quantiles_.end())) {
5870
std::sort(quantiles_.begin(), quantiles_.end());
71+
}
72+
auto iter = std::unique(quantiles_.begin(), quantiles_.end());
73+
quantiles_.erase(iter, quantiles_.end());
5974
}
6075

6176
void observe(float value) {
@@ -119,16 +134,14 @@ class summary_t : public static_metric {
119134
return;
120135
}
121136

122-
json_summary_t summary{name_, help_, metric_name(), labels_name(),
123-
quantiles_};
137+
json_summary_t summary{name_, help_, metric_name()};
124138
json_summary_metric_t metric;
125-
126-
metric.quantiles_value = get_rates(metric.sum, metric.count);
139+
auto rates = get_rates(metric.sum, metric.count);
140+
detail::vector_combine(metric.quantiles, quantiles_, rates);
127141
if (metric.count == 0 && !has_refreshed_.load(std::memory_order_relaxed)) {
128142
return;
129143
}
130-
metric.labels.reserve(labels_value_.size());
131-
for (auto& e : labels_value_) metric.labels.emplace_back(e);
144+
detail::vector_combine(metric.labels, labels_name(), labels_value_);
132145
summary.metrics.push_back(std::move(metric));
133146
iguana::to_json(summary, str);
134147
}
@@ -229,8 +242,7 @@ class basic_dynamic_summary
229242
if (map.empty()) {
230243
return;
231244
}
232-
json_summary_t summary{Base::name_, Base::help_, Base::metric_name(),
233-
Base::labels_name(), quantiles_};
245+
json_summary_t summary{Base::name_, Base::help_, Base::metric_name()};
234246
summary.metrics.reserve(map.size());
235247
for (size_t i = 0; i < map.size(); ++i) {
236248
auto& labels_value = map[i]->label;
@@ -244,9 +256,8 @@ class basic_dynamic_summary
244256
json_summary_metric_t& metric = summary.metrics.back();
245257
metric.count = count;
246258
metric.sum = sum;
247-
metric.quantiles_value = std::move(rates);
248-
metric.labels.reserve(labels_value.size());
249-
for (auto& e : labels_value) metric.labels.emplace_back(e);
259+
detail::vector_combine(metric.quantiles, quantiles_, rates);
260+
detail::vector_combine(metric.labels, Base::labels_name(), labels_value);
250261
}
251262
iguana::to_json(summary, str);
252263
}

include/ylt/reflection/member_count.hpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,20 @@ template <typename T>
7272
constexpr bool optional = !expected<T> && optional_impl<T>::value;
7373
#endif
7474

75+
template <typename T>
76+
struct pair_impl : std::false_type {};
77+
78+
template <typename F, typename S>
79+
struct pair_impl<std::pair<F, S>> : std::true_type {};
80+
81+
#if __cpp_concepts >= 201907L
82+
template <typename T>
83+
concept pair = pair_impl<T>::value;
84+
#else
85+
template <typename T>
86+
constexpr bool pair = pair_impl<T>::value;
87+
#endif
88+
7589
namespace internal {
7690
#if __cpp_concepts >= 201907L
7791
template <typename Type>

include/ylt/reflection/user_reflect_macro.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#pragma once
2+
#include <array>
23
#include <string_view>
34
#include <tuple>
45
#include <type_traits>

include/ylt/standalone/cinatra/coro_http_client.hpp

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "brzip.hpp"
3434
#endif
3535
#include "cinatra_log_wrapper.hpp"
36+
#include "error.hpp"
3637
#include "http_parser.hpp"
3738
#include "multipart.hpp"
3839
#include "picohttpparser.h"
@@ -294,12 +295,6 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {
294295
*/
295296
async_simple::coro::Lazy<resp_data> connect(
296297
std::string uri, std::vector<asio::ip::tcp::endpoint> *eps = nullptr) {
297-
if (should_reset_) {
298-
reset();
299-
}
300-
else {
301-
should_reset_ = true;
302-
}
303298
resp_data data{};
304299
bool no_schema = !has_schema(uri);
305300
std::string append_uri;
@@ -355,7 +350,7 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {
355350
data = co_await connect(u, eps);
356351
}
357352
if (socket_->is_timeout_) {
358-
co_return resp_data{std::make_error_code(std::errc::timed_out), 404};
353+
co_return resp_data{make_error_code(http_errc::connect_timeout), 404};
359354
}
360355
if (!data.net_err) {
361356
data.status = 200;
@@ -1090,7 +1085,7 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {
10901085
async_simple::coro::Lazy<bool> reconnect(resp_data &data, uri_t u) {
10911086
data = co_await connect(u);
10921087
if (socket_->is_timeout_) {
1093-
data = resp_data{std::make_error_code(std::errc::timed_out), 404};
1088+
data = resp_data{make_error_code(http_errc::connect_timeout), 404};
10941089
}
10951090
if (data.net_err) {
10961091
co_return false;
@@ -1106,7 +1101,7 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {
11061101
}
11071102
#endif
11081103
if (socket_->is_timeout_) {
1109-
ec = std::make_error_code(std::errc::timed_out);
1104+
ec = make_error_code(http_errc::request_timeout);
11101105
}
11111106
}
11121107

@@ -1377,7 +1372,7 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {
13771372
co_await handle_read(ec, size, is_keep_alive, std::move(ctx), method);
13781373
} while (0);
13791374
if (ec && socket_->is_timeout_) {
1380-
ec = std::make_error_code(std::errc::timed_out);
1375+
ec = make_error_code(http_errc::request_timeout);
13811376
}
13821377
handle_result(data, ec, is_keep_alive);
13831378
co_return data;
@@ -2014,6 +2009,12 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {
20142009
if (eps == nullptr) {
20152010
eps = &eps_tmp;
20162011
}
2012+
if (should_reset_) {
2013+
reset();
2014+
}
2015+
else {
2016+
should_reset_ = true;
2017+
}
20172018
if (socket_->has_closed_) {
20182019
auto time_out_guard =
20192020
timer_guard(this, conn_timeout_duration_, "connect timer");
@@ -2054,7 +2055,7 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {
20542055
}
20552056
#endif
20562057
if (socket_->is_timeout_) {
2057-
ec = std::make_error_code(std::errc::timed_out);
2058+
ec = make_error_code(http_errc::connect_timeout);
20582059
co_return resp_data{ec, 404};
20592060
}
20602061

@@ -2199,7 +2200,7 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {
21992200
sock, read_buf, ws.left_header_len(), has_init_ssl);
22002201
ec) {
22012202
if (socket_->is_timeout_) {
2202-
co_return resp_data{std::make_error_code(std::errc::timed_out), 404};
2203+
co_return resp_data{make_error_code(http_errc::request_timeout), 404};
22032204
}
22042205
data.net_err = ec;
22052206
data.status = 404;
@@ -2463,7 +2464,6 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {
24632464
#endif
24642465
std::string redirect_uri_;
24652466
bool enable_follow_redirect_ = false;
2466-
bool enable_timeout_ = false;
24672467
std::chrono::steady_clock::duration conn_timeout_duration_ =
24682468
std::chrono::seconds(30);
24692469
std::chrono::steady_clock::duration req_timeout_duration_ =
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#pragma once
2+
#include <string>
3+
#include <system_error>
4+
5+
namespace cinatra {
6+
enum class http_errc { connect_timeout = 2025, request_timeout };
7+
8+
class http_error_category : public std::error_category {
9+
public:
10+
const char* name() const noexcept override { return "coro_http_error"; }
11+
12+
std::string message(int ev) const override {
13+
switch (static_cast<http_errc>(ev)) {
14+
case http_errc::connect_timeout:
15+
return "Connect timeout";
16+
case http_errc::request_timeout:
17+
return "Request timeout";
18+
default:
19+
return "Unknown error";
20+
}
21+
}
22+
};
23+
24+
inline cinatra::http_error_category& category() {
25+
static cinatra::http_error_category instance;
26+
return instance;
27+
}
28+
29+
inline std::error_code make_error_code(http_errc e) {
30+
return {static_cast<int>(e), category()};
31+
}
32+
33+
inline bool operator==(const std::error_code& code, http_errc ec) {
34+
return code.value() == (int)ec;
35+
}
36+
37+
} // namespace cinatra

0 commit comments

Comments
 (0)