aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp
diff options
context:
space:
mode:
authorAlexander Smirnov <alex@ydb.tech>2025-03-04 13:27:53 +0000
committerAlexander Smirnov <alex@ydb.tech>2025-03-04 13:27:53 +0000
commitad0b83372abbcedc2887412cfdd967ea22b7148e (patch)
treed24fee47ed2aef834af220ac137f5a0e26ed4678 /library/cpp
parent31ac77ec345d18126d79b7797bef365c9068d999 (diff)
parent040bd4000eeec19eab31a023f72c3c06494ce92d (diff)
downloadydb-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.h25
-rw-r--r--library/cpp/neh/http_common.cpp27
-rw-r--r--library/cpp/neh/http_common.h3
-rw-r--r--library/cpp/neh/https.cpp32
-rw-r--r--library/cpp/tdigest/tdigest.cpp44
-rw-r--r--library/cpp/tdigest/tdigest.h10
-rw-r--r--library/cpp/tdigest/tdigest.proto1
-rw-r--r--library/cpp/tld/tlds-alpha-by-domain.txt4
-rw-r--r--library/cpp/yt/error/error.cpp32
-rw-r--r--library/cpp/yt/error/error.h10
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_;
};
////////////////////////////////////////////////////////////////////////////////