hotfix: enable reading lines split over multiple stdout buffers

This commit is contained in:
Ilion Beyst 2022-12-03 15:57:59 +01:00
parent c7d9734067
commit 453ff83e6c
4 changed files with 32 additions and 5 deletions

5
Cargo.lock generated
View file

@ -1256,9 +1256,9 @@ checksum = "73cbba799671b762df5a175adf59ce145165747bb891505c43d09aefbbf38beb"
[[package]] [[package]]
name = "memchr" name = "memchr"
version = "2.4.1" version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]] [[package]]
name = "mime" name = "mime"
@ -1586,6 +1586,7 @@ dependencies = [
"chrono", "chrono",
"futures", "futures",
"futures-core", "futures-core",
"memchr",
"planetwars-rules", "planetwars-rules",
"rand 0.6.5", "rand 0.6.5",
"serde", "serde",

View file

@ -18,6 +18,7 @@ chrono = { version = "0.4", features = ["serde"] }
bollard = { git = "https://github.com/fussybeaver/bollard", rev = "c5d87a4934c70a04f9c649fedb241dbd4943c927" } bollard = { git = "https://github.com/fussybeaver/bollard", rev = "c5d87a4934c70a04f9c649fedb241dbd4943c927" }
bytes = "1.1" bytes = "1.1"
async-trait = "0.1" async-trait = "0.1"
memchr = "2.5.0"
[dev-dependencies] [dev-dependencies]
tempfile = "3" tempfile = "3"

View file

@ -5,7 +5,7 @@ use std::sync::{Arc, Mutex};
use async_trait::async_trait; use async_trait::async_trait;
use bollard::container::{self, AttachContainerOptions, AttachContainerResults, LogOutput}; use bollard::container::{self, AttachContainerOptions, AttachContainerResults, LogOutput};
use bollard::Docker; use bollard::Docker;
use bytes::Bytes; use bytes::{Bytes, BytesMut};
use futures::{Stream, StreamExt}; use futures::{Stream, StreamExt};
use tokio::io::{AsyncWrite, AsyncWriteExt}; use tokio::io::{AsyncWrite, AsyncWriteExt};
use tokio::sync::mpsc; use tokio::sync::mpsc;
@ -168,6 +168,8 @@ fn run_docker_bot(
event_bus, event_bus,
match_logger, match_logger,
rx, rx,
stdout_buf: BytesMut::new(),
}; };
let join_handle = tokio::spawn(bot_runner.run()); let join_handle = tokio::spawn(bot_runner.run());
@ -198,6 +200,9 @@ pub struct DockerBotRunner {
rx: mpsc::UnboundedReceiver<RequestMessage>, rx: mpsc::UnboundedReceiver<RequestMessage>,
match_logger: MatchLogger, match_logger: MatchLogger,
player_id: u32, player_id: u32,
stdout_buf: BytesMut,
// stderr_buf: BytesMut,
} }
impl DockerBotRunner { impl DockerBotRunner {
@ -243,8 +248,11 @@ impl DockerBotRunner {
let log_output = item.expect("failed to get log output"); let log_output = item.expect("failed to get log output");
match log_output { match log_output {
LogOutput::StdOut { message } => { LogOutput::StdOut { message } => {
// TODO: this is not correct (buffering and such) self.stdout_buf.extend_from_slice(&message);
return Ok(message); if let Some(split_idx) = memchr::memchr(b'\n', &self.stdout_buf) {
let line = self.stdout_buf.split_to(split_idx+1);
return Ok(line.freeze())
}
} }
LogOutput::StdErr { mut message } => { LogOutput::StdErr { mut message } => {
// TODO // TODO

View file

@ -148,3 +148,20 @@ async fn docker_runner_crash() {
}) })
.await; .await;
} }
#[tokio::test]
async fn test_long_line() {
let bot_spec = simple_python_docker_bot_spec("./bots", "echo_bot.py");
let len = 10 * 2_usize.pow(20); // 10 megabytes - hopefully large enough to cause buffering
let buf = std::iter::repeat(b'a').take(len).collect::<Vec<u8>>();
with_bot_match_ctx(bot_spec, |ctx| {
async move {
let resp = ctx.request(1, buf, Duration::from_millis(200)).await;
let resp_bytes = resp.expect("unexpected error");
assert_eq!(resp_bytes.len(), len + 1);
}
.boxed()
})
.await;
}