@@ -3,32 +3,33 @@ use std::time::Instant;
33#[ derive( Debug , Clone ) ]
44pub struct ServerTiming {
55 enabled : bool ,
6- start : Instant ,
7- events : Vec < TimingEvent > ,
8- }
9-
10- #[ derive( Debug , Clone ) ]
11- struct TimingEvent {
12- name : & ' static str ,
13- duration_ms : f64 ,
6+ previous_event : Instant ,
7+ header : String ,
148}
159
1610impl ServerTiming {
1711 #[ must_use]
1812 pub fn new ( enabled : bool ) -> Self {
1913 Self {
2014 enabled,
21- start : Instant :: now ( ) ,
22- events : Vec :: new ( ) ,
15+ previous_event : Instant :: now ( ) ,
16+ header : String :: new ( ) ,
2317 }
2418 }
2519
2620 pub fn record ( & mut self , name : & ' static str ) {
2721 if !self . enabled {
2822 return ;
2923 }
30- let duration_ms = self . start . elapsed ( ) . as_secs_f64 ( ) * 1000.0 ;
31- self . events . push ( TimingEvent { name, duration_ms } ) ;
24+ let now = Instant :: now ( ) ;
25+ let duration_ms = ( now - self . previous_event ) . as_secs_f64 ( ) * 1000.0 ;
26+ self . previous_event = now;
27+
28+ if !self . header . is_empty ( ) {
29+ self . header . push_str ( ", " ) ;
30+ }
31+ use std:: fmt:: Write ;
32+ write ! ( & mut self . header, "{};dur={:.2}" , name, duration_ms) . unwrap ( ) ;
3233 }
3334
3435 #[ must_use]
@@ -37,15 +38,12 @@ impl ServerTiming {
3738 }
3839
3940 #[ must_use]
40- pub fn as_header_value ( & self ) -> String {
41- if !self . enabled {
42- return String :: new ( ) ;
41+ pub fn as_header_value ( & self ) -> & str {
42+ if self . enabled {
43+ & self . header
44+ } else {
45+ ""
4346 }
44- self . events
45- . iter ( )
46- . map ( |event| format ! ( "{};dur={:.2}" , event. name, event. duration_ms) )
47- . collect :: < Vec < _ > > ( )
48- . join ( ", " )
4947 }
5048}
5149
@@ -54,74 +52,3 @@ impl Default for ServerTiming {
5452 Self :: new ( false )
5553 }
5654}
57-
58- #[ cfg( test) ]
59- mod tests {
60- use super :: * ;
61- use std:: thread;
62- use std:: time:: Duration ;
63-
64- #[ test]
65- fn test_disabled_timing ( ) {
66- let mut timing = ServerTiming :: new ( false ) ;
67- assert ! ( !timing. is_enabled( ) ) ;
68- timing. record ( "event1" ) ;
69- timing. record ( "event2" ) ;
70- assert_eq ! ( timing. as_header_value( ) , "" ) ;
71- }
72-
73- #[ test]
74- fn test_enabled_timing ( ) {
75- let mut timing = ServerTiming :: new ( true ) ;
76- assert ! ( timing. is_enabled( ) ) ;
77- timing. record ( "event1" ) ;
78- thread:: sleep ( Duration :: from_millis ( 10 ) ) ;
79- timing. record ( "event2" ) ;
80- let header = timing. as_header_value ( ) ;
81- assert ! ( header. contains( "event1;dur=" ) ) ;
82- assert ! ( header. contains( "event2;dur=" ) ) ;
83- assert ! ( header. contains( ", " ) ) ;
84- }
85-
86- #[ test]
87- fn test_timing_values_increase ( ) {
88- let mut timing = ServerTiming :: new ( true ) ;
89- timing. record ( "first" ) ;
90- thread:: sleep ( Duration :: from_millis ( 5 ) ) ;
91- timing. record ( "second" ) ;
92- assert_eq ! ( timing. events. len( ) , 2 ) ;
93- assert ! ( timing. events[ 1 ] . duration_ms > timing. events[ 0 ] . duration_ms) ;
94- }
95-
96- #[ test]
97- fn test_default_is_disabled ( ) {
98- let timing = ServerTiming :: default ( ) ;
99- assert ! ( !timing. is_enabled( ) ) ;
100- }
101-
102- #[ test]
103- fn test_header_format ( ) {
104- let mut timing = ServerTiming :: new ( true ) ;
105- timing. events . push ( TimingEvent {
106- name : "test" ,
107- duration_ms : 123.456 ,
108- } ) ;
109- let header = timing. as_header_value ( ) ;
110- assert_eq ! ( header, "test;dur=123.46" ) ;
111- }
112-
113- #[ test]
114- fn test_multiple_events_format ( ) {
115- let mut timing = ServerTiming :: new ( true ) ;
116- timing. events . push ( TimingEvent {
117- name : "first" ,
118- duration_ms : 10.5 ,
119- } ) ;
120- timing. events . push ( TimingEvent {
121- name : "second" ,
122- duration_ms : 25.75 ,
123- } ) ;
124- let header = timing. as_header_value ( ) ;
125- assert_eq ! ( header, "first;dur=10.50, second;dur=25.75" ) ;
126- }
127- }
0 commit comments