1
- use std:: sync:: atomic:: { AtomicIsize , Ordering } ;
1
+ use std:: fmt;
2
+ use std:: fmt:: Debug ;
2
3
3
4
use dashmap:: DashMap ;
4
5
use once_cell:: sync:: OnceCell ;
@@ -55,12 +56,23 @@ impl Stats {
55
56
56
57
pub fn to_string ( & self ) -> String {
57
58
let stats = Stats :: instance ( ) ;
59
+
58
60
let conns = stats. conns . value ( ) ;
59
61
let conns_rate = stats. conns . rate ( ) ;
62
+ let conns_avg_rate = stats. conns . avg_rate ( ) ;
63
+ let conns_medi_rate = stats. conns . medi_rate ( ) ;
64
+
60
65
let subs = stats. subs . value ( ) ;
66
+ let subs_rate = stats. subs . rate ( ) ;
67
+ let subs_avg_rate = stats. subs . avg_rate ( ) ;
68
+ let subs_medi_rate = stats. subs . medi_rate ( ) ;
69
+
61
70
let conn_fails = stats. conn_fails . value ( ) ;
62
71
let recvs = stats. recvs . value ( ) ;
63
72
let recvs_rate = stats. recvs . rate ( ) ;
73
+ let recvs_avg_rate = stats. recvs . avg_rate ( ) ;
74
+ let recvs_medi_rate = stats. recvs . medi_rate ( ) ;
75
+
64
76
let sends = stats. sends . value ( ) ;
65
77
let sends_rate = stats. sends . rate ( ) ;
66
78
let closeds = stats. closeds . value ( ) ;
@@ -69,65 +81,132 @@ impl Stats {
69
81
. iter ( )
70
82
. map ( |entry| ( entry. key ( ) . clone ( ) , entry. value ( ) . value ( ) ) )
71
83
. collect :: < Vec < ( String , isize ) > > ( ) ;
72
- format ! ( "* Connecteds:{} {:0.2?}/s, conn_fails:{}, subs:{}, sends:{} {:0.2?}/s, recvs:{} {:0.2?}/s, closeds:{}, ifaddrs: {:?}, last err: {:?}" ,
73
- conns, conns_rate, conn_fails, subs, sends, sends_rate, recvs, recvs_rate, closeds, ifaddrs, stats. last_err. write( ) . take( ) )
84
+ format ! ( "* Connecteds:{} ( {:0.2?}/s, {:0.2?}/s, {:0.2?}/s), conn_fails:{}, subs:{} ({:0.2?}/s, {:0.2?}/s, {:0.2?}/s), sends:{} {:0.2?}/s, recvs:{} ( {:0.2?}/s, {:0.2?}/s, {:0.2?}/s) , closeds:{}, ifaddrs: {:?}, last err: {:?}" ,
85
+ conns, conns_rate, conns_avg_rate , conns_medi_rate , conn_fails, subs, subs_rate , subs_avg_rate , subs_medi_rate , sends, sends_rate, recvs, recvs_rate, recvs_avg_rate , recvs_medi_rate , closeds, ifaddrs, stats. last_err. write( ) . take( ) )
74
86
}
75
87
}
76
88
77
- #[ derive( Debug ) ]
78
- pub struct Counter ( AtomicIsize , RwLock < DiscreteRateCounter > ) ;
89
+ pub type StartMillis = i64 ;
90
+ pub type EndMillis = i64 ;
91
+
92
+ pub struct Counter {
93
+ inner : RwLock < CounterInner >
94
+ }
95
+
96
+ pub struct CounterInner {
97
+ nums : isize ,
98
+ rate : DiscreteRateCounter ,
99
+ cost_times : Vec < ( StartMillis , EndMillis ) > ,
100
+ }
101
+
102
+ impl Debug for Counter {
103
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
104
+ let inner = self . inner . read ( ) ;
105
+ write ! ( f, "(nums: {}, rate: {:?}, cost_times_len: {})" , inner. nums, inner. rate. rate( ) , inner. cost_times. len( ) )
106
+ }
107
+ }
79
108
80
109
impl Counter {
81
110
#[ inline]
82
111
fn new ( ) -> Self {
83
- Counter (
84
- AtomicIsize :: new ( 0 ) ,
85
- RwLock :: new ( DiscreteRateCounter :: new ( 10 ) ) ,
86
- )
112
+ Counter {
113
+ inner : RwLock :: new (
114
+ CounterInner {
115
+ nums : 0 ,
116
+ rate : DiscreteRateCounter :: new ( 100 ) ,
117
+ cost_times : Vec :: new ( )
118
+ } )
119
+ }
87
120
}
88
121
89
122
#[ inline]
90
123
pub fn inc ( & self ) {
91
- self . 0 . fetch_add ( 1 , Ordering :: SeqCst ) ;
92
- self . 1 . write ( ) . update ( ) ;
124
+ let mut inner = self . inner . write ( ) ;
125
+ inner. nums += 1 ;
126
+ inner. rate . update ( ) ;
93
127
}
94
128
95
129
#[ inline]
130
+ pub fn inc2 ( & self , start : StartMillis , end : EndMillis ) {
131
+ let mut inner = self . inner . write ( ) ;
132
+ inner. nums += 1 ;
133
+ inner. rate . update ( ) ;
134
+ inner. cost_times . push ( ( start, end) ) ;
135
+ }
136
+
96
137
pub fn inc_limit ( & self , limit : isize ) -> bool {
97
- let res = self
98
- . 0
99
- . fetch_update ( Ordering :: SeqCst , Ordering :: SeqCst , |x| {
100
- if x < limit {
101
- Some ( x + 1 )
102
- } else {
103
- None
104
- }
105
- } ) ;
106
- if res. is_ok ( ) {
107
- self . 1 . write ( ) . update ( ) ;
138
+ let mut inner = self . inner . write ( ) ;
139
+ if inner. nums < limit {
140
+ inner. nums += 1 ;
141
+ inner. rate . update ( ) ;
108
142
true
109
- } else {
143
+ } else {
110
144
false
111
145
}
112
146
}
113
147
148
+ #[ inline]
149
+ pub fn inc_limit_cost_times ( & self , limit_cost_times : usize , start : StartMillis , end : EndMillis ) {
150
+ let mut inner = self . inner . write ( ) ;
151
+ inner. nums += 1 ;
152
+ inner. rate . update ( ) ;
153
+ if inner. cost_times . len ( ) > limit_cost_times {
154
+ inner. cost_times . remove ( 0 ) ;
155
+
156
+ }
157
+ inner. cost_times . push ( ( start, end) ) ;
158
+ }
159
+
114
160
#[ inline]
115
161
pub fn dec ( & self ) {
116
- self . 0 . fetch_sub ( 1 , Ordering :: SeqCst ) ;
162
+ self . inner . write ( ) . nums += 1 ;
117
163
}
118
164
119
165
#[ inline]
120
166
pub fn decs ( & self , v : isize ) {
121
- self . 0 . fetch_sub ( v , Ordering :: SeqCst ) ;
167
+ self . inner . write ( ) . nums += v ;
122
168
}
123
169
124
170
#[ inline]
125
171
pub fn value ( & self ) -> isize {
126
- self . 0 . load ( Ordering :: SeqCst )
172
+ self . inner . read ( ) . nums
127
173
}
128
174
129
175
#[ inline]
130
176
pub fn rate ( & self ) -> f64 {
131
- self . 1 . read ( ) . rate ( )
177
+ self . inner . read ( ) . rate . rate ( )
178
+ }
179
+
180
+ #[ inline]
181
+ pub fn avg_rate ( & self ) -> f64 {
182
+ let inner = self . inner . read ( ) ;
183
+ if inner. cost_times . len ( ) > 1 {
184
+ //average rate
185
+ let ( first, _) = inner. cost_times . first ( ) . unwrap ( ) ;
186
+ let ( _, last) = inner. cost_times . last ( ) . unwrap ( ) ;
187
+ //println!("avg_rate inner.cost_times.len(): {}, {:?}, first: {}, last: {}", inner.cost_times.len(), ((last - first) as f64 / 1000.0), first, last);
188
+ inner. cost_times . len ( ) as f64 / ( ( last - first) as f64 / 1000.0 )
189
+ } else {
190
+ 1.0
191
+ }
192
+
193
+ }
194
+
195
+ #[ inline]
196
+ pub fn medi_rate ( & self ) -> f64 {
197
+ let inner = self . inner . read ( ) ;
198
+ if inner. cost_times . len ( ) > 1 {
199
+ //intermediate rate
200
+ let len = inner. cost_times . len ( ) ;
201
+ let start_idx = ( len as f64 * 0.15 ) as usize ;
202
+ let end_idx = len - start_idx - 1 ;
203
+ let ( first, _) = inner. cost_times [ start_idx] ;
204
+ let ( _, last) = inner. cost_times [ end_idx] ;
205
+ //println!("medi_rate inner.cost_times.len(): {}, {:?}", end_idx - start_idx, ((last - first) as f64 / 1000.0));
206
+ ( end_idx - start_idx) as f64 / ( ( last - first) as f64 / 1000.0 )
207
+ } else {
208
+ 1.0
209
+ }
210
+
132
211
}
133
212
}
0 commit comments