@@ -13,6 +13,39 @@ namespace NYdb::inline V3::NTopic {
1313namespace {
1414
1515static constexpr auto PARTITION_KEY_META_KEY = " __partition_key" ;
16+ static constexpr size_t DESCRIBE_TOPIC_ATTEMPTS = 3 ;
17+ static constexpr TDuration DESCRIBE_TOPIC_RETRY_DELAY = TDuration::MilliSeconds(100 );
18+
19+ TDescribeTopicResult DescribeTopicWithRetries (
20+ TTopicClient::TImpl* client,
21+ const std::string& path,
22+ const TDescribeTopicSettings& settings,
23+ const TDbDriverStatePtr& dbDriverState,
24+ const std::string& logPrefix) {
25+ for (size_t attempt = 1 ; attempt <= DESCRIBE_TOPIC_ATTEMPTS ; ++attempt) {
26+ auto result = client->DescribeTopic (path, settings).GetValueSync ();
27+ if (result.IsSuccess () && !result.GetTopicDescription ().GetPartitions ().empty ()) {
28+ return result;
29+ }
30+
31+ if (attempt == DESCRIBE_TOPIC_ATTEMPTS ) {
32+ return result;
33+ }
34+
35+ TStringBuilder message;
36+ message << logPrefix << " DescribeTopic returned " ;
37+ if (result.IsSuccess ()) {
38+ message << " no partitions" ;
39+ } else {
40+ message << " status " << result.GetStatus ();
41+ }
42+ message << " , retry attempt " << attempt;
43+ LOG_LAZY (dbDriverState->Log , TLOG_DEBUG , message);
44+ Sleep (DESCRIBE_TOPIC_RETRY_DELAY );
45+ }
46+
47+ Y_UNREACHABLE ();
48+ }
1649
1750} // namespace
1851
@@ -1609,12 +1642,16 @@ TProducer::TProducer(
16091642 }
16101643
16111644 TDescribeTopicSettings describeTopicSettings;
1612- auto topicConfig = client-> DescribeTopic ( settings.Path_ , describeTopicSettings). GetValueSync ( );
1645+ auto topicConfig = DescribeTopicWithRetries ( client. get (), settings.Path_ , describeTopicSettings, DbDriverState, LogPrefix () );
16131646 auto partitions = topicConfig.GetTopicDescription ().GetPartitions ();
16141647 std::sort (partitions.begin (), partitions.end (), [](const auto & a, const auto & b) -> bool {
16151648 return a.GetPartitionId () < b.GetPartitionId ();
16161649 });
16171650
1651+ if (partitions.empty ()) {
1652+ ythrow TContractViolation (" Topic has no partitions" );
1653+ }
1654+
16181655 auto partitionChooserStrategy = settings.PartitionChooserStrategy_ ;
16191656 auto strategy = topicConfig.GetTopicDescription ().GetPartitioningSettings ().GetAutoPartitioningSettings ().GetStrategy ();
16201657 auto autoPartitioningEnabled = (strategy != EAutoPartitioningStrategy::Disabled &&
@@ -1658,6 +1695,7 @@ TProducer::TProducer(
16581695 case TProducerSettings::EPartitionChooserStrategy::Bound:
16591696 PartitioningKeyHasher = settings.PartitioningKeyHasher_ ;
16601697 PartitionChooser = std::make_unique<TBoundPartitionChooser>(this );
1698+
16611699 for (size_t i = 0 ; i < partitions.size (); ++i) {
16621700 const auto & partition = partitions[i];
16631701 if (i > 0 && !partition.GetFromBound ().has_value () && !partition.GetToBound ().has_value ()) {
@@ -2259,7 +2297,9 @@ std::pair<std::uint32_t, std::string> TProducer::TBoundPartitionChooser::ChooseP
22592297TProducer::THashPartitionChooser::THashPartitionChooser (std::vector<std::uint32_t >&& partitions)
22602298 : Partitions(std::move(partitions))
22612299{
2262- Y_ABORT_UNLESS (!Partitions.empty (), " THashPartitionChooser requires at least one partition" );
2300+ if (Partitions.empty ()) {
2301+ ythrow TContractViolation (" THashPartitionChooser requires at least one partition" );
2302+ }
22632303}
22642304
22652305std::pair<std::uint32_t , std::string> TProducer::THashPartitionChooser::ChoosePartition (const std::string_view key) {
0 commit comments