1
- use csv;
2
1
use istziio_client:: client_api:: { StorageClient , StorageRequest } ;
3
- use std:: collections:: VecDeque ;
4
2
use std:: error:: Error ;
5
3
use std:: path:: PathBuf ;
6
4
use std:: thread:: sleep;
@@ -22,51 +20,59 @@ pub enum ClientType {
22
20
Client2 ( ) ,
23
21
}
24
22
25
- pub fn parse_trace ( trace_path : PathBuf ) -> Result < VecDeque < TraceEntry > , Box < dyn Error > > {
26
- let mut trace: VecDeque < TraceEntry > = VecDeque :: new ( ) ;
23
+ pub fn parse_trace ( trace_path : PathBuf ) -> Result < Vec < TraceEntry > , Box < dyn Error > > {
27
24
let mut rdr = csv:: Reader :: from_path ( trace_path) ?;
25
+ let mut traces = Vec :: new ( ) ;
28
26
for result in rdr. records ( ) {
29
- // The iterator yields Result<StringRecord, Error>, so we check the
30
- // error here.
31
27
let record = result?;
32
- trace . push_back ( TraceEntry {
28
+ traces . push ( TraceEntry {
33
29
timestamp : record. get ( 0 ) . unwrap ( ) . parse ( ) . unwrap ( ) ,
34
30
request : StorageRequest :: Table ( record. get ( 1 ) . unwrap ( ) . parse ( ) . unwrap ( ) ) ,
35
31
} ) ;
36
32
}
37
- Ok ( trace )
33
+ Ok ( traces )
38
34
}
35
+
39
36
pub async fn run_trace (
40
- mut trace : VecDeque < TraceEntry > ,
37
+ traces : Vec < TraceEntry > ,
41
38
client_builder : & dyn Fn ( ) -> Box < dyn StorageClient > ,
42
39
) {
43
40
let start_time = SystemTime :: now ( ) ;
44
- let request_num = trace . len ( ) ;
41
+ let request_num = traces . len ( ) ;
45
42
let ( tx, mut rx) = mpsc:: channel ( 32 ) ;
46
- while !trace. is_empty ( ) {
47
- let next_entry = trace. pop_front ( ) . unwrap ( ) ;
43
+ for ( i, trace) in traces. into_iter ( ) . enumerate ( ) {
48
44
if let Some ( diff) =
49
- Duration :: from_millis ( next_entry . timestamp ) . checked_sub ( start_time. elapsed ( ) . unwrap ( ) )
45
+ Duration :: from_millis ( trace . timestamp ) . checked_sub ( start_time. elapsed ( ) . unwrap ( ) )
50
46
{
51
47
sleep ( diff) ;
52
48
}
53
- println ! ( "next trace: {}" , next_entry. timestamp) ;
54
49
let tx = tx. clone ( ) ;
55
50
let client = client_builder ( ) ;
56
51
tokio:: spawn ( async move {
57
- let table_id = match next_entry . request {
52
+ let table_id = match trace . request {
58
53
StorageRequest :: Table ( id) => id,
59
54
_ => panic ! ( "Invalid request type" ) ,
60
55
} ;
61
- println ! ( "start thread reading {}" , table_id) ;
56
+ println ! (
57
+ "Trace {} sends request for table {} at timestamp {}" ,
58
+ i, table_id, trace. timestamp
59
+ ) ;
62
60
let client_start = Instant :: now ( ) ;
63
- let req = next_entry. request ;
64
61
65
- let res = client. request_data ( req. clone ( ) ) . await ;
66
- if let Err ( e) = res {
67
- println ! ( "Error: {}" , e) ;
62
+ let res = client. request_data ( trace. request ) . await ;
63
+ if res. is_err ( ) {
64
+ println ! ( "Error: {}" , res. as_ref( ) . err( ) . unwrap( ) ) ;
65
+ }
66
+ let mut rx = res. unwrap ( ) ;
67
+ let mut total_num_rows = 0 ;
68
+ while let Some ( rb) = rx. recv ( ) . await {
69
+ total_num_rows += rb. num_rows ( ) ;
68
70
}
69
71
let client_duration = client_start. elapsed ( ) ;
72
+ println ! (
73
+ "Trace {} gets {} rows from the client, latency is {:?}" ,
74
+ i, total_num_rows, client_duration
75
+ ) ;
70
76
tx. send ( client_duration) . await . unwrap ( ) ;
71
77
} ) ;
72
78
}
@@ -75,7 +81,6 @@ pub async fn run_trace(
75
81
let mut duration_sum = Duration :: new ( 0 , 0 ) ;
76
82
for _ in 0 ..request_num {
77
83
let client_duration = rx. recv ( ) . await . unwrap ( ) ;
78
- println ! ( "Client latency: {:?}" , client_duration) ;
79
84
duration_sum += client_duration;
80
85
}
81
86
0 commit comments