aquatic ws load test: send offers, count offer responses

This commit is contained in:
Joakim Frostegård 2020-08-01 04:27:55 +02:00
parent 6a9e1f5e72
commit 55045279ac
6 changed files with 47 additions and 19 deletions

1
Cargo.lock generated
View file

@ -230,6 +230,7 @@ dependencies = [
"rand", "rand",
"rand_distr", "rand_distr",
"serde", "serde",
"serde_json",
"slab", "slab",
"tungstenite", "tungstenite",
] ]

View file

@ -18,6 +18,7 @@ mio = { version = "0.7", features = ["udp", "os-poll", "os-util"] }
rand = { version = "0.7", features = ["small_rng"] } rand = { version = "0.7", features = ["small_rng"] }
rand_distr = "0.2" rand_distr = "0.2"
serde = { version = "1", features = ["derive"] } serde = { version = "1", features = ["derive"] }
serde_json = "1"
slab = "0.4" slab = "0.4"
tungstenite = "0.11" tungstenite = "0.11"

View file

@ -19,6 +19,7 @@ pub struct Statistics {
pub requests: AtomicUsize, pub requests: AtomicUsize,
pub response_peers: AtomicUsize, pub response_peers: AtomicUsize,
pub responses_announce: AtomicUsize, pub responses_announce: AtomicUsize,
pub responses_offer: AtomicUsize,
pub responses_scrape: AtomicUsize, pub responses_scrape: AtomicUsize,
pub responses_failure: AtomicUsize, pub responses_failure: AtomicUsize,
pub bytes_sent: AtomicUsize, pub bytes_sent: AtomicUsize,

View file

@ -102,6 +102,8 @@ fn monitor_statistics(
let requests_per_second = statistics.requests let requests_per_second = statistics.requests
.fetch_and(0, Ordering::SeqCst) as f64 / interval_f64; .fetch_and(0, Ordering::SeqCst) as f64 / interval_f64;
let responses_offer_per_second = statistics.responses_offer
.fetch_and(0, Ordering::SeqCst) as f64 / interval_f64;
let responses_scrape_per_second = statistics.responses_scrape let responses_scrape_per_second = statistics.responses_scrape
.fetch_and(0, Ordering::SeqCst) as f64 / interval_f64; .fetch_and(0, Ordering::SeqCst) as f64 / interval_f64;
let responses_failure_per_second = statistics.responses_failure let responses_failure_per_second = statistics.responses_failure
@ -116,6 +118,7 @@ fn monitor_statistics(
let responses_per_second = let responses_per_second =
responses_announce_per_second + responses_announce_per_second +
responses_offer_per_second +
responses_scrape_per_second + responses_scrape_per_second +
responses_failure_per_second; responses_failure_per_second;
@ -125,6 +128,7 @@ fn monitor_statistics(
println!("Requests out: {:.2}/second", requests_per_second); println!("Requests out: {:.2}/second", requests_per_second);
println!("Responses in: {:.2}/second", responses_per_second); println!("Responses in: {:.2}/second", responses_per_second);
println!(" - Announce responses: {:.2}", responses_announce_per_second); println!(" - Announce responses: {:.2}", responses_announce_per_second);
println!(" - Offer responses: {:.2}", responses_offer_per_second);
println!(" - Scrape responses: {:.2}", responses_scrape_per_second); println!(" - Scrape responses: {:.2}", responses_scrape_per_second);
println!(" - Failure responses: {:.2}", responses_failure_per_second); println!(" - Failure responses: {:.2}", responses_failure_per_second);
//println!("Peers per announce response: {:.2}", response_peers / responses_announce); //println!("Peers per announce response: {:.2}", response_peers / responses_announce);

View file

@ -1,6 +1,6 @@
use std::sync::atomic::Ordering; use std::sync::atomic::Ordering;
use std::time::Duration; use std::time::Duration;
use std::io::{Read, Write, ErrorKind, Cursor}; use std::io::ErrorKind;
use hashbrown::HashMap; use hashbrown::HashMap;
use mio::{net::TcpStream, Events, Poll, Interest, Token}; use mio::{net::TcpStream, Events, Poll, Interest, Token};
@ -12,9 +12,6 @@ use crate::config::*;
use crate::utils::create_random_request; use crate::utils::create_random_request;
type HandshakeResult<T> = std::result::Result<(tungstenite::protocol::WebSocket<TcpStream>, T), tungstenite::handshake::HandshakeError<tungstenite::handshake::client::ClientHandshake<TcpStream>>>;
pub enum ConnectionState { pub enum ConnectionState {
TcpStream(TcpStream), TcpStream(TcpStream),
WebSocket(WebSocket<TcpStream>), WebSocket(WebSocket<TcpStream>),
@ -120,28 +117,27 @@ impl Connection {
rng: &mut impl Rng, rng: &mut impl Rng,
){ ){
if let ConnectionState::WebSocket(ref mut ws) = self.stream { if let ConnectionState::WebSocket(ref mut ws) = self.stream {
let mut send_request = false;
loop { loop {
match ws.read_message(){ match ws.read_message(){
Ok(message) => { Ok(message) => {
Self::register_response_type(state, message); send_request |= Self::register_response_type(state, message);
break;
}, },
Err(tungstenite::Error::Io(err)) if err.kind() == ErrorKind::WouldBlock => { Err(tungstenite::Error::Io(err)) if err.kind() == ErrorKind::WouldBlock => {
self.can_send_initial = false; self.can_send_initial = false;
eprintln!("handle_read_event error would block: {}", err); break;
return;
}, },
Err(err) => { Err(err) => {
eprintln!("handle_read_event error: {}", err); eprintln!("handle_read_event error: {}", err);
return; break;
} }
} }
}; };
if send_request {
self.send_request( self.send_request(
config, config,
state, state,
@ -149,12 +145,28 @@ impl Connection {
); );
} }
} }
}
fn register_response_type( fn register_response_type(
state: &LoadTestState, state: &LoadTestState,
message: ::tungstenite::Message, message: ::tungstenite::Message,
){ ) -> bool {
state.statistics.responses_announce.fetch_add(1, Ordering::SeqCst); // FIXME if let ::tungstenite::Message::Text(text) = message {
if text.contains("offer"){
state.statistics.responses_offer
.fetch_add(1, Ordering::SeqCst);
return false;
} else if text.contains("announce"){
state.statistics.responses_announce
.fetch_add(1, Ordering::SeqCst);
} else if text.contains("scrape"){
state.statistics.responses_scrape
.fetch_add(1, Ordering::SeqCst);
}
}
true
} }
pub fn send_request( pub fn send_request(

View file

@ -57,13 +57,22 @@ fn create_announce_request(
let info_hash_index = select_info_hash_index(config, &state, rng); let info_hash_index = select_info_hash_index(config, &state, rng);
let mut offers = Vec::with_capacity(10);
for _ in 0..10 {
offers.push(AnnounceRequestOffer {
offer_id: OfferId(rng.gen()),
offer: JsonValue(::serde_json::Value::from("{}")),
})
}
InMessage::AnnounceRequest(AnnounceRequest { InMessage::AnnounceRequest(AnnounceRequest {
info_hash: state.info_hashes[info_hash_index], info_hash: state.info_hashes[info_hash_index],
peer_id: PeerId(rng.gen()), peer_id: PeerId(rng.gen()),
bytes_left: Some(bytes_left), bytes_left: Some(bytes_left),
event, event,
numwant: None, numwant: None,
offers: None, // FIXME offers: Some(offers),
answer: None, answer: None,
to_peer_id: None, to_peer_id: None,
offer_id: None, offer_id: None,