diff options
author | Alexander Smirnov <alex@ydb.tech> | 2025-03-04 13:27:53 +0000 |
---|---|---|
committer | Alexander Smirnov <alex@ydb.tech> | 2025-03-04 13:27:53 +0000 |
commit | ad0b83372abbcedc2887412cfdd967ea22b7148e (patch) | |
tree | d24fee47ed2aef834af220ac137f5a0e26ed4678 /library/cpp | |
parent | 31ac77ec345d18126d79b7797bef365c9068d999 (diff) | |
parent | 040bd4000eeec19eab31a023f72c3c06494ce92d (diff) | |
download | ydb-ad0b83372abbcedc2887412cfdd967ea22b7148e.tar.gz |
Merge pull request #15226 from ydb-platform/merge-libs-250302-1120
Diffstat (limited to 'library/cpp')
-rw-r--r-- | library/cpp/http/simple/http_client.h | 25 | ||||
-rw-r--r-- | library/cpp/neh/http_common.cpp | 27 | ||||
-rw-r--r-- | library/cpp/neh/http_common.h | 3 | ||||
-rw-r--r-- | library/cpp/neh/https.cpp | 32 | ||||
-rw-r--r-- | library/cpp/tdigest/tdigest.cpp | 44 | ||||
-rw-r--r-- | library/cpp/tdigest/tdigest.h | 10 | ||||
-rw-r--r-- | library/cpp/tdigest/tdigest.proto | 1 | ||||
-rw-r--r-- | library/cpp/tld/tlds-alpha-by-domain.txt | 4 | ||||
-rw-r--r-- | library/cpp/yt/error/error.cpp | 32 | ||||
-rw-r--r-- | library/cpp/yt/error/error.h | 10 |
10 files changed, 134 insertions, 54 deletions
diff --git a/library/cpp/http/simple/http_client.h b/library/cpp/http/simple/http_client.h index 224be58a245..86a8cb4e994 100644 --- a/library/cpp/http/simple/http_client.h +++ b/library/cpp/http/simple/http_client.h @@ -267,11 +267,13 @@ TKeepAliveHttpClient::THttpCode TKeepAliveHttpClient::DoRequestReliable(const T& const bool haveNewConnection = CreateNewConnectionIfNeeded(); const bool couldRetry = !haveNewConnection && i == 0; // Actually old connection could be already closed by server, // so we should try one more time in this case. - try { - cancellation.Future().Subscribe([&](auto&) { - Connection->Shutdown(); - }); + TManualEvent cancellationEndEvent; + cancellation.Future().Subscribe([&](auto&) { + Connection->Shutdown(); + cancellationEndEvent.Signal(); + }); + try { Connection->Write(raw); THttpCode code = ReadAndTransferHttp(*Connection->GetHttpInput(), output, outHeaders); @@ -280,20 +282,29 @@ TKeepAliveHttpClient::THttpCode TKeepAliveHttpClient::DoRequestReliable(const T& } return code; } catch (const TSystemError& e) { + if (cancellation.IsCancellationRequested()) { + cancellationEndEvent.WaitI(); + cancellation.ThrowIfCancellationRequested(); + } Connection.Reset(); - cancellation.ThrowIfCancellationRequested(); if (!couldRetry || e.Status() != EPIPE) { throw; } } catch (const THttpReadException&) { // Actually old connection is already closed by server + if (cancellation.IsCancellationRequested()) { + cancellationEndEvent.WaitI(); + cancellation.ThrowIfCancellationRequested(); + } Connection.Reset(); - cancellation.ThrowIfCancellationRequested(); if (!couldRetry) { throw; } } catch (const std::exception&) { + if (cancellation.IsCancellationRequested()) { + cancellationEndEvent.WaitI(); + cancellation.ThrowIfCancellationRequested(); + } Connection.Reset(); - cancellation.ThrowIfCancellationRequested(); throw; } } diff --git a/library/cpp/neh/http_common.cpp b/library/cpp/neh/http_common.cpp index 7ae466c31a0..23ed6a2889f 100644 --- a/library/cpp/neh/http_common.cpp +++ b/library/cpp/neh/http_common.cpp @@ -231,5 +231,32 @@ namespace NNeh { return NeedGetRequestFor(scheme) || NeedPostRequestFor(scheme); } } + + HttpCodes GetHttpCode(const IRequest::TResponseError& error) { + switch (error) { + case IRequest::TResponseError::BadRequest: + return HttpCodes::HTTP_BAD_REQUEST; + case IRequest::TResponseError::Forbidden: + return HttpCodes::HTTP_FORBIDDEN; + case IRequest::TResponseError::NotExistService: + return HttpCodes::HTTP_NOT_FOUND; + case IRequest::TResponseError::TooManyRequests: + return HttpCodes::HTTP_TOO_MANY_REQUESTS; + case IRequest::TResponseError::InternalError: + return HttpCodes::HTTP_INTERNAL_SERVER_ERROR; + case IRequest::TResponseError::NotImplemented: + return HttpCodes::HTTP_NOT_IMPLEMENTED; + case IRequest::TResponseError::BadGateway: + return HttpCodes::HTTP_BAD_GATEWAY; + case IRequest::TResponseError::ServiceUnavailable: + return HttpCodes::HTTP_SERVICE_UNAVAILABLE; + case IRequest::TResponseError::BandwidthLimitExceeded: + return HttpCodes::HTTP_BANDWIDTH_LIMIT_EXCEEDED; + case IRequest::TResponseError::MaxResponseError: + ythrow yexception() << TStringBuf("unknow type of error"); + + Y_UNREACHABLE(); + } + } } diff --git a/library/cpp/neh/http_common.h b/library/cpp/neh/http_common.h index 69659ba907f..acefe80c37f 100644 --- a/library/cpp/neh/http_common.h +++ b/library/cpp/neh/http_common.h @@ -7,6 +7,7 @@ #include <util/stream/mem.h> #include <util/stream/output.h> #include <library/cpp/deprecated/atomic/atomic.h> +#include <library/cpp/http/misc/httpcodes.h> #include "location.h" #include "neh.h" @@ -298,4 +299,6 @@ namespace NNeh { bool IsHttpScheme(TStringBuf scheme); } + + HttpCodes GetHttpCode(const IRequest::TResponseError&); } diff --git a/library/cpp/neh/https.cpp b/library/cpp/neh/https.cpp index f1a2ec9e7e7..ece7d3cf2d1 100644 --- a/library/cpp/neh/https.cpp +++ b/library/cpp/neh/https.cpp @@ -1394,37 +1394,7 @@ namespace NNeh { return; } - switch (*error) { - case IRequest::TResponseError::BadRequest: - os << HttpCodeStrEx(HttpCodes::HTTP_BAD_REQUEST); - break; - case IRequest::TResponseError::Forbidden: - os << HttpCodeStrEx(HttpCodes::HTTP_FORBIDDEN); - break; - case IRequest::TResponseError::NotExistService: - os << HttpCodeStrEx(HttpCodes::HTTP_NOT_FOUND); - break; - case IRequest::TResponseError::TooManyRequests: - os << HttpCodeStrEx(HttpCodes::HTTP_TOO_MANY_REQUESTS); - break; - case IRequest::TResponseError::InternalError: - os << HttpCodeStrEx(HttpCodes::HTTP_INTERNAL_SERVER_ERROR); - break; - case IRequest::TResponseError::NotImplemented: - os << HttpCodeStrEx(HttpCodes::HTTP_NOT_IMPLEMENTED); - break; - case IRequest::TResponseError::BadGateway: - os << HttpCodeStrEx(HttpCodes::HTTP_BAD_GATEWAY); - break; - case IRequest::TResponseError::ServiceUnavailable: - os << HttpCodeStrEx(HttpCodes::HTTP_SERVICE_UNAVAILABLE); - break; - case IRequest::TResponseError::BandwidthLimitExceeded: - os << HttpCodeStrEx(HttpCodes::HTTP_BANDWIDTH_LIMIT_EXCEEDED); - break; - case IRequest::TResponseError::MaxResponseError: - ythrow yexception() << TStringBuf("unknow type of error"); - } + os << HttpCodeStrEx(GetHttpCode(*error)); } public: diff --git a/library/cpp/tdigest/tdigest.cpp b/library/cpp/tdigest/tdigest.cpp index 145cef78e10..3d3772a9dee 100644 --- a/library/cpp/tdigest/tdigest.cpp +++ b/library/cpp/tdigest/tdigest.cpp @@ -3,45 +3,52 @@ #include <library/cpp/tdigest/tdigest.pb.h> #include <cmath> +#include <util/generic/yexception.h> // TODO: rewrite to https://github.com/tdunning/t-digest/blob/master/src/main/java/com/tdunning/math/stats/MergingDigest.java -TDigest::TDigest(double delta, double k) +TDigest::TDigest(double delta, double k, bool supportsNaN) : N(0) , Delta(delta) , K(k) + , SupportsNaN(supportsNaN) { } -TDigest::TDigest(double delta, double k, double firstValue) - : TDigest(delta, k) +TDigest::TDigest(double delta, double k, double firstValue, bool supportsNaN) + : TDigest(delta, k, supportsNaN) { AddValue(firstValue); } -TDigest::TDigest(TStringBuf serializedDigest) +TDigest::TDigest(TStringBuf serializedDigest, bool supportsNaN) : N(0) + , SupportsNaN(supportsNaN) { NTDigest::TDigest digest; Y_ABORT_UNLESS(digest.ParseFromArray(serializedDigest.data(), serializedDigest.size())); Delta = digest.delta(); K = digest.k(); + HasNaN = SupportsNaN && digest.nans(); for (int i = 0; i < digest.centroids_size(); ++i) { const NTDigest::TDigest::TCentroid& centroid = digest.centroids(i); Update(centroid.mean(), centroid.weight()); } } -TDigest::TDigest(const TDigest* digest1, const TDigest* digest2) +TDigest::TDigest(const TDigest* digest1, const TDigest* digest2, bool supportsNaN) : N(0) , Delta(std::min(digest1->Delta, digest2->Delta)) , K(std::max(digest1->K, digest2->K)) + , SupportsNaN(supportsNaN) + , HasNaN(supportsNaN && (digest1->HasNaN || digest2->HasNaN)) { Add(*digest1); Add(*digest2); } void TDigest::Add(const TDigest& otherDigest) { + Y_ENSURE(SupportsNaN == otherDigest.SupportsNaN); for (auto& it : otherDigest.Centroids) Update(it.Mean, it.Count); for (auto& it : otherDigest.Unmerged) @@ -49,7 +56,8 @@ void TDigest::Add(const TDigest& otherDigest) { } TDigest TDigest::operator+(const TDigest& other) { - TDigest T(Delta, K); + Y_ENSURE(SupportsNaN == other.SupportsNaN); + TDigest T(Delta, K, SupportsNaN); T.Add(*this); T.Add(other); return T; @@ -92,6 +100,12 @@ void TDigest::MergeCentroid(TVector<TCentroid>& merged, double& sum, const TCent } void TDigest::Update(double x, double w) { + if (SupportsNaN) { + if (std::isnan(x)) { + HasNaN = true; + return; + } + } AddCentroid(TCentroid(x, w)); if (Unmerged.size() >= K / Delta) { Compress(); @@ -136,8 +150,17 @@ void TDigest::AddValue(double value) { double TDigest::GetPercentile(double percentile) { Compress(); - if (Centroids.empty()) + if (Centroids.empty()) { + if (HasNaN) { + return std::numeric_limits<double>::quiet_NaN(); + } return 0.0; + } + + if (HasNaN && percentile >= 1.0) { + return std::numeric_limits<double>::quiet_NaN(); + } + // This algorithm uses C=1/2 with 0.5 optimized away // See https://en.wikipedia.org/wiki/Percentile#First_Variant.2C double x = percentile * N; @@ -159,6 +182,9 @@ double TDigest::GetPercentile(double percentile) { double TDigest::GetRank(double value) { Compress(); + if (SupportsNaN && std::isnan(value)) { + return 1.0; + } if (Centroids.empty()) { return 0.0; } @@ -189,6 +215,10 @@ TString TDigest::Serialize() { NTDigest::TDigest digest; digest.set_delta(Delta); digest.set_k(K); + if (HasNaN) { + digest.set_nans(HasNaN); + } + for (const auto& it : Centroids) { NTDigest::TDigest::TCentroid* centroid = digest.add_centroids(); centroid->set_mean(it.Mean); diff --git a/library/cpp/tdigest/tdigest.h b/library/cpp/tdigest/tdigest.h index 715620258c5..22c87e63c33 100644 --- a/library/cpp/tdigest/tdigest.h +++ b/library/cpp/tdigest/tdigest.h @@ -36,6 +36,8 @@ class TDigest { double N; double Delta; double K; + bool SupportsNaN = false; + bool HasNaN = false; void Add(const TDigest& otherDigest); void AddCentroid(const TCentroid& centroid); @@ -47,10 +49,10 @@ protected: void Update(double x, double w = 1.0); public: - TDigest(double delta = 0.01, double k = 25); - TDigest(double delta, double k, double firstValue); - TDigest(TStringBuf serializedDigest); - TDigest(const TDigest* digest1, const TDigest* digest2); // merge + TDigest(double delta = 0.01, double k = 25, bool supportsNaN = false); + TDigest(double delta, double k, double firstValue, bool supportsNaN = false); + TDigest(TStringBuf serializedDigest, bool supportsNaN = false); + TDigest(const TDigest* digest1, const TDigest* digest2, bool supportsNaN = false); // merge TString Serialize(); diff --git a/library/cpp/tdigest/tdigest.proto b/library/cpp/tdigest/tdigest.proto index 4a2db3e638c..abd8b821cc4 100644 --- a/library/cpp/tdigest/tdigest.proto +++ b/library/cpp/tdigest/tdigest.proto @@ -8,4 +8,5 @@ message TDigest { optional double Weight = 2; } repeated TCentroid Centroids = 3; + optional bool Nans = 4; } diff --git a/library/cpp/tld/tlds-alpha-by-domain.txt b/library/cpp/tld/tlds-alpha-by-domain.txt index fc48570eaf9..b534e60ce4d 100644 --- a/library/cpp/tld/tlds-alpha-by-domain.txt +++ b/library/cpp/tld/tlds-alpha-by-domain.txt @@ -1,4 +1,4 @@ -# Version 2025022200, Last Updated Sat Feb 22 07:07:01 2025 UTC +# Version 2025030100, Last Updated Sat Mar 1 07:07:02 2025 UTC AAA AARP ABB @@ -627,7 +627,6 @@ KAUFEN KDDI KE KERRYHOTELS -KERRYLOGISTICS KERRYPROPERTIES KFH KG @@ -691,7 +690,6 @@ LIMITED LIMO LINCOLN LINK -LIPSY LIVE LIVING LK diff --git a/library/cpp/yt/error/error.cpp b/library/cpp/yt/error/error.cpp index 636d7d81fc4..f097697cd6a 100644 --- a/library/cpp/yt/error/error.cpp +++ b/library/cpp/yt/error/error.cpp @@ -29,6 +29,8 @@ void FormatValue(TStringBuilderBase* builder, TErrorCode code, TStringBuf spec) constexpr TStringBuf ErrorMessageTruncatedSuffix = "...<message truncated>"; +TError::TEnricher TError::Enricher_; + //////////////////////////////////////////////////////////////////////////////// class TError::TImpl @@ -275,15 +277,20 @@ TError::TErrorOr(const std::exception& ex) *this = TError(NYT::EErrorCode::Generic, TRuntimeFormat{ex.what()}); } YT_VERIFY(!IsOK()); + Enrich(); } TError::TErrorOr(std::string message, TDisableFormat) : Impl_(std::make_unique<TImpl>(std::move(message))) -{ } +{ + Enrich(); +} TError::TErrorOr(TErrorCode code, std::string message, TDisableFormat) : Impl_(std::make_unique<TImpl>(code, std::move(message))) -{ } +{ + Enrich(); +} TError& TError::operator = (const TError& other) { @@ -632,6 +639,20 @@ std::optional<TError> TError::FindMatching(const THashSet<TErrorCode>& codes) co }); } +void TError::RegisterEnricher(TEnricher enricher) +{ + // NB: This daisy-chaining strategy is optimal when there's O(1) callbacks. Convert to a vector + // if the number grows. + if (Enricher_) { + Enricher_ = [first = std::move(Enricher_), second = std::move(enricher)] (TError& error) { + first(error); + second(error); + }; + } else { + Enricher_ = std::move(enricher); + } +} + TError::TErrorOr(std::unique_ptr<TImpl> impl) : Impl_(std::move(impl)) { } @@ -643,6 +664,13 @@ void TError::MakeMutable() } } +void TError::Enrich() +{ + if (Enricher_) { + Enricher_(*this); + } +} + //////////////////////////////////////////////////////////////////////////////// TError& TError::operator <<= (const TErrorAttribute& attribute) & diff --git a/library/cpp/yt/error/error.h b/library/cpp/yt/error/error.h index 8b459d0beb8..92f19bc398a 100644 --- a/library/cpp/yt/error/error.h +++ b/library/cpp/yt/error/error.h @@ -219,6 +219,13 @@ public: template <CErrorNestable TValue> TError operator << (const std::optional<TValue>& rhs) const &; + // The |enricher| is called during TError construction and before TErrorOr<> construction. Meant + // to enrich the error, e.g. by setting generic attributes. The |RegisterEnricher| method is not + // threadsafe and is meant to be called from single-threaded bootstrapping code. Multiple + // enrichers are supported and will be called in order of registration. + using TEnricher = std::function<void(TError&)>; + static void RegisterEnricher(TEnricher enricher); + private: class TImpl; std::unique_ptr<TImpl> Impl_; @@ -226,8 +233,11 @@ private: explicit TErrorOr(std::unique_ptr<TImpl> impl); void MakeMutable(); + void Enrich(); friend class TErrorAttributes; + + static TEnricher Enricher_; }; //////////////////////////////////////////////////////////////////////////////// |