@@ -162,6 +162,10 @@ cdef class Loop:
162
162
self ._recv_buffer_in_use = 0
163
163
164
164
err = uv.uv_loop_init(self .uvloop)
165
+ if err < 0 :
166
+ raise convert_error(err)
167
+
168
+ err = uv.uv_loop_configure(self .uvloop, uv.UV_METRICS_IDLE_TIME)
165
169
if err < 0 :
166
170
raise convert_error(err)
167
171
self .uvloop.data = < void * > self
@@ -527,6 +531,7 @@ cdef class Loop:
527
531
528
532
self ._thread_id = PyThread_get_thread_ident()
529
533
self ._running = 1
534
+ self ._loop_start_time = self ._time()
530
535
531
536
self .handler_check__exec_writes.start()
532
537
self .handler_idle.start()
@@ -628,6 +633,10 @@ cdef class Loop:
628
633
self ._default_executor = None
629
634
executor.shutdown(wait = False )
630
635
636
+ cdef uint64_t _event_loop_idle_time(self ):
637
+ """ Returns number of nanoseconds the loop has been idle"""
638
+ return uv.uv_metrics_idle_time(self .uvloop)
639
+
631
640
cdef uint64_t _time(self ):
632
641
# asyncio doesn't have a time cache, neither should uvloop.
633
642
uv.uv_update_time(self .uvloop) # void
@@ -1337,6 +1346,24 @@ cdef class Loop:
1337
1346
return self .call_later(
1338
1347
when - self .time(), callback, * args, context = context)
1339
1348
1349
+ def _event_loop_utilization (self ):
1350
+ """ Returns idle and active time in milliseconds and the percentage of
1351
+ time the event loop is active
1352
+ """
1353
+
1354
+ idle = 0.
1355
+ active = 0.
1356
+ utilization = 0.
1357
+
1358
+ if not self ._running:
1359
+ return idle, active, utilization
1360
+
1361
+ idle = self ._event_loop_idle_time() / 10 ** 6
1362
+ active = self ._time() - self ._loop_start_time - idle
1363
+ utilization = active / (active + idle)
1364
+
1365
+ return idle, active, utilization
1366
+
1340
1367
def time (self ):
1341
1368
""" Return the time according to the event loop's clock.
1342
1369
0 commit comments