@@ -5,11 +5,14 @@ use std::fs::File;
5
5
use std:: io:: prelude:: * ;
6
6
use std:: { collections:: HashMap , sync:: Arc } ;
7
7
8
- use agp_datapath:: messages:: Agent ;
8
+ use agp_datapath:: messages:: { Agent , AgentType } ;
9
+ use agp_service:: AgpHeaderFlags ;
9
10
use parking_lot:: RwLock ;
10
11
use testing:: parse_line;
11
12
use tokio_util:: sync:: CancellationToken ;
12
13
14
+ use agp_service:: streaming:: StreamingConfiguration ;
15
+
13
16
use agp_gw:: config;
14
17
use clap:: Parser ;
15
18
use indicatif:: ProgressBar ;
@@ -18,9 +21,19 @@ use tracing::{debug, error, info};
18
21
#[ derive( Parser , Debug ) ]
19
22
#[ command( version, about, long_about = None ) ]
20
23
pub struct Args {
21
- /// Workload input file
22
- #[ arg( short, long, value_name = "WORKLOAD" , required = true ) ]
23
- workload : String ,
24
+ /// Workload input file, required if used in workload mode. If this is set the streaming mode is set to false.
25
+ #[ arg( short, long, value_name = "WORKLOAD" , required = false ) ]
26
+ workload : Option < String > ,
27
+
28
+ /// Runs in streaming mode.
29
+ #[ arg(
30
+ short,
31
+ long,
32
+ value_name = "STREAMING" ,
33
+ required = false ,
34
+ default_value_t = false
35
+ ) ]
36
+ streaming : bool ,
24
37
25
38
/// Agp config file
26
39
#[ arg( short, long, value_name = "CONFIGURATION" , required = true ) ]
@@ -54,22 +67,30 @@ pub struct Args {
54
67
#[ arg(
55
68
short,
56
69
long,
57
- value_name = "SLEEP " ,
70
+ value_name = "FREQUENCY " ,
58
71
required = false ,
59
72
default_value_t = 0
60
73
) ]
61
- sleep : u32 ,
74
+ frequency : u32 ,
75
+
76
+ /// used only in streaming mode, defines the maximum number of packets to send
77
+ #[ arg( short, long, value_name = "PACKETS" , required = false ) ]
78
+ max_packets : Option < u64 > ,
62
79
}
63
80
64
81
impl Args {
65
82
pub fn msg_size ( & self ) -> & u32 {
66
83
& self . msg_size
67
84
}
68
85
69
- pub fn workload ( & self ) -> & String {
86
+ pub fn workload ( & self ) -> & Option < String > {
70
87
& self . workload
71
88
}
72
89
90
+ pub fn streaming ( & self ) -> & bool {
91
+ & self . streaming
92
+ }
93
+
73
94
pub fn id ( & self ) -> & u64 {
74
95
& self . id
75
96
}
@@ -82,8 +103,12 @@ impl Args {
82
103
& self . quite
83
104
}
84
105
85
- pub fn sleep ( & self ) -> & u32 {
86
- & self . sleep
106
+ pub fn frequency ( & self ) -> & u32 {
107
+ & self . frequency
108
+ }
109
+
110
+ pub fn max_packets ( & self ) -> & Option < u64 > {
111
+ & self . max_packets
87
112
}
88
113
}
89
114
@@ -95,22 +120,137 @@ async fn main() {
95
120
let config_file = args. config ( ) ;
96
121
let msg_size = * args. msg_size ( ) ;
97
122
let id = * args. id ( ) ;
98
- let sleep = * args. sleep ( ) ;
123
+ let frequency = * args. frequency ( ) ;
124
+ let mut streaming = * args. streaming ( ) ;
125
+ let max_packets = args. max_packets ;
126
+ if input. is_some ( ) {
127
+ streaming = false ;
128
+ }
99
129
100
- // setup agent config
130
+ info ! (
131
+ "configuration -- workload file: {}, agent config {}, publisher id: {}, streaming mode: {}, msg size: {}" ,
132
+ input. as_ref( ) . unwrap_or( & "None" . to_string( ) ) ,
133
+ config_file,
134
+ id,
135
+ streaming,
136
+ msg_size,
137
+ ) ;
138
+
139
+ // start local agent
140
+ // get service
101
141
let mut config = config:: load_config ( config_file) . expect ( "failed to load configuration" ) ;
102
142
let _guard = config. tracing . setup_tracing_subscriber ( ) ;
143
+ let svc_id = agp_config:: component:: id:: ID :: new_with_str ( "gateway/0" ) . unwrap ( ) ;
144
+ let svc = config. services . get_mut ( & svc_id) . unwrap ( ) ;
103
145
104
- info ! (
105
- "configuration -- input file: {}, agent config: {}, msg size: {}" ,
106
- input, config_file, msg_size
107
- ) ;
146
+ // create local agent
147
+ let agent_name = Agent :: from_strings ( "cisco" , "default" , "publisher" , id) ;
148
+ // required in streaming mode
149
+ let dest_name = AgentType :: from_strings ( "cisco" , "default" , "subscriber" ) ;
150
+ let mut rx = svc
151
+ . create_agent ( & agent_name)
152
+ . expect ( "failed to create agent" ) ;
153
+
154
+ // connect to the remote gateway
155
+ let conn_id = svc. connect ( None ) . await . unwrap ( ) ;
156
+ info ! ( "remote connection id = {}" , conn_id) ;
157
+
158
+ // subscribe for local name
159
+ match svc
160
+ . subscribe (
161
+ & agent_name,
162
+ agent_name. agent_type ( ) ,
163
+ agent_name. agent_id_option ( ) ,
164
+ Some ( conn_id) ,
165
+ )
166
+ . await
167
+ {
168
+ Ok ( _) => { }
169
+ Err ( e) => {
170
+ panic ! ( "an error accoured while adding a subscription {}" , e) ;
171
+ }
172
+ }
173
+
174
+ svc. set_route ( & agent_name, & dest_name, None , conn_id)
175
+ . await
176
+ . unwrap ( ) ;
177
+
178
+ // wait for the connection to be established
179
+ tokio:: time:: sleep ( tokio:: time:: Duration :: from_millis ( 100 ) ) . await ;
108
180
181
+ // STREAMING MODE
182
+ if streaming {
183
+ // create streaming session
184
+ let res = svc
185
+ . create_session (
186
+ & agent_name,
187
+ agp_service:: session:: SessionConfig :: Streaming ( StreamingConfiguration {
188
+ source : agent_name. clone ( ) ,
189
+ max_retries : None ,
190
+ timeout : None ,
191
+ } ) ,
192
+ )
193
+ . await ;
194
+ if res. is_err ( ) {
195
+ panic ! ( "error creating fire and forget session" ) ;
196
+ }
197
+
198
+ // loop to listen to errors coming from the local gateway
199
+ tokio:: spawn ( async move {
200
+ loop {
201
+ match rx. recv ( ) . await {
202
+ None => {
203
+ info ! ( %conn_id, "end of stream" ) ;
204
+ break ;
205
+ }
206
+ Some ( msg_info) => {
207
+ if msg_info. is_err ( ) {
208
+ error ! ( "received an error message {:?}" , msg_info) ;
209
+ continue ;
210
+ } else {
211
+ panic ! ( "received a message from the gateway, this should never happen" ) ;
212
+ }
213
+ }
214
+ }
215
+ }
216
+ } ) ;
217
+
218
+ // get the session
219
+ let session_info = res. unwrap ( ) ;
220
+
221
+ for i in 0 ..max_packets. unwrap_or ( u64:: MAX ) {
222
+ let payload: Vec < u8 > = vec ! [ 120 ; msg_size as usize ] ; // ASCII for 'x' = 120
223
+ info ! ( "publishing message {}" , i) ;
224
+ // set fanout > 1 to send the message in broadcast
225
+ let flags = AgpHeaderFlags :: new ( 10 , None , None , None , None ) ;
226
+ if svc
227
+ . publish_with_flags (
228
+ & agent_name,
229
+ session_info. clone ( ) ,
230
+ & dest_name,
231
+ None ,
232
+ flags,
233
+ payload,
234
+ )
235
+ . await
236
+ . is_err ( )
237
+ {
238
+ error ! ( "an error occurred sending publication, the test will fail" , ) ;
239
+ }
240
+ if frequency != 0 {
241
+ tokio:: time:: sleep ( tokio:: time:: Duration :: from_millis ( frequency as u64 ) ) . await ;
242
+ }
243
+ }
244
+ return ;
245
+ }
246
+
247
+ // WORKLOAD MODE
248
+ // setup agent config
109
249
let mut publication_list = HashMap :: new ( ) ;
110
250
let mut oracle = HashMap :: new ( ) ;
111
251
let mut routes = Vec :: new ( ) ;
112
252
113
- let res = File :: open ( input) ;
253
+ let res = File :: open ( input. as_ref ( ) . unwrap ( ) ) ;
114
254
if res. is_err ( ) {
115
255
panic ! ( "error opening the input file" ) ;
116
256
}
@@ -142,37 +282,6 @@ async fn main() {
142
282
}
143
283
}
144
284
145
- // start local agent
146
- // get service
147
- let svc_id = agp_config:: component:: id:: ID :: new_with_str ( "gateway/0" ) . unwrap ( ) ;
148
- let svc = config. services . get_mut ( & svc_id) . unwrap ( ) ;
149
-
150
- // create local agent
151
- let agent_name = Agent :: from_strings ( "cisco" , "default" , "publisher" , id) ;
152
- let mut rx = svc
153
- . create_agent ( & agent_name)
154
- . expect ( "failed to create agent" ) ;
155
-
156
- // connect to the remote gateway
157
- let conn_id = svc. connect ( None ) . await . unwrap ( ) ;
158
- info ! ( "remote connection id = {}" , conn_id) ;
159
-
160
- // subscribe for local name
161
- match svc
162
- . subscribe (
163
- & agent_name,
164
- agent_name. agent_type ( ) ,
165
- agent_name. agent_id_option ( ) ,
166
- Some ( conn_id) ,
167
- )
168
- . await
169
- {
170
- Ok ( _) => { }
171
- Err ( e) => {
172
- panic ! ( "an error accoured while adding a subscription {}" , e) ;
173
- }
174
- }
175
-
176
285
// set routes for all subscriptions
177
286
for r in routes {
178
287
match svc
@@ -317,8 +426,8 @@ async fn main() {
317
426
bar. inc ( 1 ) ;
318
427
}
319
428
320
- if sleep != 0 {
321
- tokio:: time:: sleep ( tokio:: time:: Duration :: from_millis ( sleep as u64 ) ) . await ;
429
+ if frequency != 0 {
430
+ tokio:: time:: sleep ( tokio:: time:: Duration :: from_millis ( frequency as u64 ) ) . await ;
322
431
}
323
432
}
324
433
let duration = start. elapsed ( ) ;
0 commit comments