fix(stress): serve a browse that lands while an offer awaits its answer
The mock seeder drained every message but the TransferResponse while it waited for the client to allow an upload, so a browse arriving in that window was silently dropped and counted against the client.
This commit is contained in:
@@ -496,18 +496,7 @@ impl SeederState {
|
|||||||
Err(_) => return,
|
Err(_) => return,
|
||||||
};
|
};
|
||||||
match msg.get_message_code() {
|
match msg.get_message_code() {
|
||||||
// GetShareFileList: reply with everything we hold.
|
4 if !self.send_listing(&mut p, shared) => return,
|
||||||
4 => {
|
|
||||||
let dir = SharedDirectory {
|
|
||||||
name: format!("stress\\{}", self.name),
|
|
||||||
files: self.files.clone(),
|
|
||||||
};
|
|
||||||
let list =
|
|
||||||
build_shared_file_list(std::slice::from_ref(&dir));
|
|
||||||
if !self.reply(&mut p, shared, &list.get_buffer()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// QueueUpload: offer the transfer, then stream it once allowed.
|
// QueueUpload: offer the transfer, then stream it once allowed.
|
||||||
43 => {
|
43 => {
|
||||||
msg.set_pointer(8);
|
msg.set_pointer(8);
|
||||||
@@ -527,7 +516,7 @@ impl SeederState {
|
|||||||
if !self.reply(&mut p, shared, &tr.get_buffer()) {
|
if !self.reply(&mut p, shared, &tr.get_buffer()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if !self.wait_for_allow(&mut p, token) {
|
if !self.wait_for_allow(&mut p, shared, token) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let content = self.content.clone();
|
let content = self.content.clone();
|
||||||
@@ -543,8 +532,25 @@ impl SeederState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Wait for the client's `TransferResponse` allowing `token`.
|
/// Everything we hold, the answer to a GetShareFileList.
|
||||||
fn wait_for_allow(&self, p: &mut TcpStream, token: u32) -> bool {
|
fn send_listing(&self, p: &mut TcpStream, shared: bool) -> bool {
|
||||||
|
let dir = SharedDirectory {
|
||||||
|
name: format!("stress\\{}", self.name),
|
||||||
|
files: self.files.clone(),
|
||||||
|
};
|
||||||
|
let list = build_shared_file_list(std::slice::from_ref(&dir));
|
||||||
|
self.reply(p, shared, &list.get_buffer())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Wait for the client's `TransferResponse` allowing `token`. A browse
|
||||||
|
/// that arrives meanwhile is answered: a busy client accepts an offer
|
||||||
|
/// late, and a browse it sent in between is not lost work on its side.
|
||||||
|
fn wait_for_allow(
|
||||||
|
&self,
|
||||||
|
p: &mut TcpStream,
|
||||||
|
shared: bool,
|
||||||
|
token: u32,
|
||||||
|
) -> bool {
|
||||||
let deadline = Instant::now() + Duration::from_secs(30);
|
let deadline = Instant::now() + Duration::from_secs(30);
|
||||||
while Instant::now() < deadline && !self.stop.load(Ordering::Relaxed) {
|
while Instant::now() < deadline && !self.stop.load(Ordering::Relaxed) {
|
||||||
match read_framed(p) {
|
match read_framed(p) {
|
||||||
@@ -554,6 +560,12 @@ impl SeederState {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Ok(msg)
|
||||||
|
if msg.get_message_code() == 4
|
||||||
|
&& !self.send_listing(p, shared) =>
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
Err(ref e) if is_timeout(e) => {}
|
Err(ref e) if is_timeout(e) => {}
|
||||||
Err(_) => return false,
|
Err(_) => return false,
|
||||||
|
|||||||
Reference in New Issue
Block a user