13
13
14
14
from trinity .utils .ema import EMA
15
15
from trinity .utils .logging import HasTraceLogger
16
+ from trinity .utils .percentile import Percentile
17
+ from trinity .utils .stddev import StandardDeviation
16
18
from .constants import ROUND_TRIP_TIMEOUT
17
19
from .types import (
18
20
TResult ,
@@ -35,8 +37,10 @@ def __init__(self) -> None:
35
37
# empty responses.
36
38
self .response_quality_ema = EMA (initial_value = 0 , smoothing_factor = 0.05 )
37
39
38
- # an EMA of the round trip request/response time
40
+ # Metrics for the round trip request/response time
39
41
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 )
40
44
41
45
# an EMA of the items per second
42
46
self .items_per_second_ema = EMA (initial_value = 0 , smoothing_factor = 0.05 )
@@ -76,39 +80,43 @@ def get_stats(self) -> str:
76
80
"""
77
81
if not self .total_msgs :
78
82
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
84
93
85
94
# msgs: total number of messages
86
95
# 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)
89
98
# timeouts: total number of timeouts
90
99
# missing: total number of missing response items
91
100
# quality: 0-100 for how complete responses are
92
101
return (
93
- 'msgs=%d items=%d rtt=%.2f/%.2f ips=%.5f/ %.5f '
102
+ 'msgs=%d items=%d rtt=%.2f/%.2f/%.2f ips=%.5f '
94
103
'timeouts=%d quality=%d'
95
104
) % (
96
105
self .total_msgs ,
97
106
self .total_items ,
98
- avg_rtt ,
99
107
self .round_trip_ema .value ,
100
- items_per_second ,
108
+ rt99 ,
109
+ rt_stddev ,
101
110
self .items_per_second_ema .value ,
102
111
self .total_timeouts ,
103
112
int (self .response_quality_ema .value ),
104
113
)
105
114
106
- def record_timeout (self , timeout : float ) -> None :
115
+ def record_timeout (self ) -> None :
107
116
self .total_msgs += 1
108
117
self .total_timeouts += 1
109
118
self .response_quality_ema .update (0 )
110
119
self .items_per_second_ema .update (0 )
111
- self .round_trip_ema .update (timeout )
112
120
113
121
def record_response (self ,
114
122
elapsed : float ,
@@ -148,7 +156,10 @@ def record_response(self,
148
156
149
157
self .total_items += num_items
150
158
self .total_response_time += elapsed
159
+
151
160
self .round_trip_ema .update (elapsed )
161
+ self .round_trip_99th .update (elapsed )
162
+ self .round_trip_stddev .update (elapsed )
152
163
153
164
if elapsed > 0 :
154
165
throughput = num_items / elapsed
0 commit comments