@@ -206,20 +206,20 @@ def start(self, port: int) -> None:
206
206
207
207
# Start the IOLoop in a separate thread
208
208
def start_metrics_loop ():
209
- loop = tornado .ioloop .IOLoop ()
210
- loop .make_current ()
209
+ self . ioloop = tornado .ioloop .IOLoop ()
210
+ self . ioloop .make_current ()
211
211
212
212
# Set up periodic updates in this IOLoop
213
213
def periodic_update_wrapper ():
214
214
if hasattr (self , "_periodic_update" ):
215
215
self ._periodic_update ()
216
216
# Schedule next update in 30 seconds
217
- loop .call_later (30 , periodic_update_wrapper )
217
+ self . ioloop .call_later (30 , periodic_update_wrapper )
218
218
219
219
# Start periodic updates
220
- loop .call_later (30 , periodic_update_wrapper )
220
+ self . ioloop .call_later (30 , periodic_update_wrapper )
221
221
222
- loop .start ()
222
+ self . ioloop .start ()
223
223
224
224
self .thread = threading .Thread (target = start_metrics_loop , daemon = True )
225
225
self .thread .start ()
@@ -234,12 +234,16 @@ def stop(self) -> None:
234
234
self .http_server .stop ()
235
235
self .http_server = None
236
236
237
+ if hasattr (self , 'ioloop' ) and self .ioloop :
238
+ # Stop the IOLoop
239
+ self .ioloop .add_callback (self .ioloop .stop )
240
+ self .ioloop = None
241
+
237
242
if self .thread and self .thread .is_alive ():
238
- # Note: Tornado IOLoop doesn't have a clean stop method
239
- # The thread will exit when the process ends
240
- pass
243
+ # Wait for thread to finish (with timeout)
244
+ self .thread .join (timeout = 1.0 )
241
245
242
- self .server_app .log .info (f"Metrics server stopped on port { self . port } " )
246
+ self .server_app .log .info (f"Metrics server stopped on port { getattr ( self , ' port' , 'unknown' ) } " )
243
247
244
248
245
249
def start_metrics_server (server_app , port : int ) -> PrometheusMetricsServer :
0 commit comments