1+ import asyncio
12import time
23
34from core .metrics import create_metrics
@@ -19,36 +20,42 @@ def create(self, args):
1920 assert self .driver is not None , "Driver is not initialized. Call set_driver() before create()."
2021 retry_no = 0
2122 while retry_no < 3 :
22- self .logger .info ("Creating topic: %s (retry no: %d)" , args .path , retry_no )
23+ self .logger .info ("Creating topic: %s (retry no: %d)" , args .topic_path , retry_no )
2324
2425 try :
2526 self .driver .topic_client .create_topic (
26- path = args .path ,
27- min_active_partitions = args .partitions_count ,
28- max_active_partitions = args .partitions_count ,
29- consumers = [args .consumer ],
27+ path = args .topic_path ,
28+ min_active_partitions = args .topic_partitions ,
29+ max_active_partitions = args .topic_partitions ,
30+ consumers = [args .topic_consumer ],
3031 )
3132
32- self .logger .info ("Topic created successfully: %s" , args .path )
33- self .logger .info ("Consumer created: %s" , args .consumer )
33+ self .logger .info ("Topic created successfully: %s" , args .topic_path )
34+ self .logger .info ("Consumer created: %s" , args .topic_consumer )
3435 return
3536
3637 except ydb .Error as e :
3738 error_msg = str (e ).lower ()
3839 if "already exists" in error_msg :
39- self .logger .info ("Topic already exists: %s" , args .path )
40+ self .logger .info ("Topic already exists: %s" , args .topic_path )
4041
4142 try :
42- description = self .driver .topic_client .describe_topic (args .path )
43- consumer_exists = any (c .name == args .consumer for c in description .consumers )
43+ description = self .driver .topic_client .describe_topic (args .topic_path )
44+ consumer_exists = any (c .name == args .topic_consumer for c in description .consumers )
4445
4546 if not consumer_exists :
46- self .logger .info ("Adding consumer %s to existing topic" , args .consumer )
47- self .driver .topic_client .alter_topic (path = args .path , add_consumers = [args .consumer ])
48- self .logger .info ("Consumer added successfully: %s" , args .consumer )
47+ self .logger .info (
48+ "Adding consumer %s to existing topic" ,
49+ args .topic_consumer ,
50+ )
51+ self .driver .topic_client .alter_topic (
52+ path = args .topic_path ,
53+ add_consumers = [args .topic_consumer ],
54+ )
55+ self .logger .info ("Consumer added successfully: %s" , args .topic_consumer )
4956 return
5057 else :
51- self .logger .info ("Consumer already exists: %s" , args .consumer )
58+ self .logger .info ("Consumer already exists: %s" , args .topic_consumer )
5259 return
5360
5461 except Exception as alter_err :
@@ -68,6 +75,65 @@ def create(self, args):
6875
6976 raise RuntimeError ("Failed to create topic" )
7077
78+ async def create_async (self , args ):
79+ assert self .driver is not None , "Driver is not initialized. Call set_driver() before create_async()."
80+ retry_no = 0
81+ while retry_no < 3 :
82+ self .logger .info ("Creating topic: %s (retry no: %d)" , args .topic_path , retry_no )
83+
84+ try :
85+ await self .driver .topic_client .create_topic (
86+ path = args .topic_path ,
87+ min_active_partitions = args .topic_partitions ,
88+ max_active_partitions = args .topic_partitions ,
89+ consumers = [args .topic_consumer ],
90+ )
91+
92+ self .logger .info ("Topic created successfully: %s" , args .topic_path )
93+ self .logger .info ("Consumer created: %s" , args .topic_consumer )
94+ return
95+
96+ except ydb .Error as e :
97+ error_msg = str (e ).lower ()
98+ if "already exists" in error_msg :
99+ self .logger .info ("Topic already exists: %s" , args .topic_path )
100+
101+ try :
102+ description = await self .driver .topic_client .describe_topic (args .topic_path )
103+ consumer_exists = any (c .name == args .topic_consumer for c in description .consumers )
104+
105+ if not consumer_exists :
106+ self .logger .info (
107+ "Adding consumer %s to existing topic" ,
108+ args .topic_consumer ,
109+ )
110+ await self .driver .topic_client .alter_topic (
111+ path = args .topic_path ,
112+ add_consumers = [args .topic_consumer ],
113+ )
114+ self .logger .info ("Consumer added successfully: %s" , args .topic_consumer )
115+ return
116+ else :
117+ self .logger .info ("Consumer already exists: %s" , args .topic_consumer )
118+ return
119+
120+ except Exception as alter_err :
121+ self .logger .warning ("Failed to add consumer: %s" , alter_err )
122+ raise
123+ elif "storage pool" in error_msg or "pq" in error_msg :
124+ self .logger .error ("YDB instance does not support topics (PersistentQueues): %s" , e )
125+ self .logger .error ("Please use YDB instance with topic support" )
126+ raise
127+ elif isinstance (e , ydb .Unavailable ):
128+ self .logger .info ("YDB instance is not ready, retrying in 5 seconds..." )
129+ await asyncio .sleep (5 )
130+ retry_no += 1
131+ else :
132+ self .logger .error ("Failed to create topic: %s" , e )
133+ raise
134+
135+ raise RuntimeError ("Failed to create topic" )
136+
71137 def run (self , args ):
72138 assert self .driver is not None , "Driver is not initialized. Call set_driver() before run()."
73139 metrics = create_metrics (args )
@@ -99,15 +165,29 @@ async def run_async(self, args):
99165 metrics .reset ()
100166
101167 def cleanup (self , args ):
102- self .logger .info ("Cleaning up topic: %s" , args .path )
168+ self .logger .info ("Cleaning up topic: %s" , args .topic_path )
103169
104170 assert self .driver is not None , "Driver is not initialized. Call set_driver() before cleanup()."
105171 try :
106- self .driver .topic_client .drop_topic (args .path )
107- self .logger .info ("Topic dropped: %s" , args .path )
172+ self .driver .topic_client .drop_topic (args .topic_path )
173+ self .logger .info ("Topic dropped: %s" , args .topic_path )
174+ except ydb .Error as e :
175+ if "does not exist" in str (e ).lower ():
176+ self .logger .info ("Topic does not exist: %s" , args .topic_path )
177+ else :
178+ self .logger .error ("Failed to drop topic: %s" , e )
179+ raise
180+
181+ async def cleanup_async (self , args ):
182+ self .logger .info ("Cleaning up topic: %s" , args .topic_path )
183+
184+ assert self .driver is not None , "Driver is not initialized. Call set_driver() before cleanup_async()."
185+ try :
186+ await self .driver .topic_client .drop_topic (args .topic_path )
187+ self .logger .info ("Topic dropped: %s" , args .topic_path )
108188 except ydb .Error as e :
109189 if "does not exist" in str (e ).lower ():
110- self .logger .info ("Topic does not exist: %s" , args .path )
190+ self .logger .info ("Topic does not exist: %s" , args .topic_path )
111191 else :
112192 self .logger .error ("Failed to drop topic: %s" , e )
113193 raise
0 commit comments