1313
1414from trinity .utils .ema import EMA
1515from trinity .utils .logging import HasTraceLogger
16+ from trinity .utils .percentile import Percentile
17+ from trinity .utils .stddev import StandardDeviation
1618from .constants import ROUND_TRIP_TIMEOUT
1719from .types import (
1820 TResult ,
@@ -35,8 +37,10 @@ def __init__(self) -> None:
3537 # empty responses.
3638 self .response_quality_ema = EMA (initial_value = 0 , smoothing_factor = 0.05 )
3739
38- # an EMA of the round trip request/response time
40+ # Metrics for the round trip request/response time
3941 self .round_trip_ema = EMA (initial_value = ROUND_TRIP_TIMEOUT , smoothing_factor = 0.05 )
42+ self .round_trip_99th = Percentile (percentile = 0.99 , window_size = 200 )
43+ self .round_trip_stddev = StandardDeviation (window_size = 200 )
4044
4145 # an EMA of the items per second
4246 self .items_per_second_ema = EMA (initial_value = 0 , smoothing_factor = 0.05 )
@@ -76,39 +80,43 @@ def get_stats(self) -> str:
7680 """
7781 if not self .total_msgs :
7882 return 'None'
79- avg_rtt = self .total_response_time / self .total_msgs
80- if not self .total_response_time :
81- items_per_second = 0.0
82- else :
83- items_per_second = self .total_items / self .total_response_time
83+
84+ try :
85+ rt99 = self .round_trip_99th .value
86+ except ValueError :
87+ rt99 = 0
88+
89+ try :
90+ rt_stddev = self .round_trip_stddev .value
91+ except ValueError :
92+ rt_stddev = 0
8493
8594 # msgs: total number of messages
8695 # items: total number of items
87- # rtt: round-trip-time (avg/ ema)
88- # ips: items-per-second (avg/ ema)
96+ # rtt: round-trip-time (ema/99th/stddev )
97+ # ips: items-per-second (ema)
8998 # timeouts: total number of timeouts
9099 # missing: total number of missing response items
91100 # quality: 0-100 for how complete responses are
92101 return (
93- 'msgs=%d items=%d rtt=%.2f/%.2f ips=%.5f/ %.5f '
102+ 'msgs=%d items=%d rtt=%.2f/%.2f/%.2f ips=%.5f '
94103 'timeouts=%d quality=%d'
95104 ) % (
96105 self .total_msgs ,
97106 self .total_items ,
98- avg_rtt ,
99107 self .round_trip_ema .value ,
100- items_per_second ,
108+ rt99 ,
109+ rt_stddev ,
101110 self .items_per_second_ema .value ,
102111 self .total_timeouts ,
103112 int (self .response_quality_ema .value ),
104113 )
105114
106- def record_timeout (self , timeout : float ) -> None :
115+ def record_timeout (self ) -> None :
107116 self .total_msgs += 1
108117 self .total_timeouts += 1
109118 self .response_quality_ema .update (0 )
110119 self .items_per_second_ema .update (0 )
111- self .round_trip_ema .update (timeout )
112120
113121 def record_response (self ,
114122 elapsed : float ,
@@ -148,7 +156,10 @@ def record_response(self,
148156
149157 self .total_items += num_items
150158 self .total_response_time += elapsed
159+
151160 self .round_trip_ema .update (elapsed )
161+ self .round_trip_99th .update (elapsed )
162+ self .round_trip_stddev .update (elapsed )
152163
153164 if elapsed > 0 :
154165 throughput = num_items / elapsed
0 commit comments