Skip to content

Commit 4a1b335

Browse files
committed
Dispatch directly to stdout/stderr in LogStream::write
1 parent 0dd32e1 commit 4a1b335

1 file changed

Lines changed: 42 additions & 32 deletions

File tree

src/commands/serve.rs

Lines changed: 42 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::common::{Profile, RunCommon, RunTarget};
2-
use anyhow::{bail, Result};
2+
use anyhow::{anyhow, bail, Result};
33
use clap::Parser;
44
use std::{
55
path::PathBuf,
@@ -11,7 +11,9 @@ use std::{
1111
};
1212
use wasmtime::component::{InstancePre, Linker};
1313
use wasmtime::{Engine, Store, StoreLimits};
14-
use wasmtime_wasi::preview2::{self, StreamResult, Table, WasiCtx, WasiCtxBuilder, WasiView};
14+
use wasmtime_wasi::preview2::{
15+
self, StreamError, StreamResult, Table, WasiCtx, WasiCtxBuilder, WasiView,
16+
};
1517
use wasmtime_wasi_http::{body::HyperOutgoingBody, WasiHttpCtx, WasiHttpView};
1618

1719
#[cfg(feature = "wasi-nn")]
@@ -135,19 +137,19 @@ impl ServeCommand {
135137
Ok(())
136138
}
137139

138-
fn new_store(&self, engine: &Engine, req_id: u64, output: OutputMutex) -> Result<Store<Host>> {
140+
fn new_store(&self, engine: &Engine, req_id: u64) -> Result<Store<Host>> {
139141
let mut builder = WasiCtxBuilder::new();
140142

141143
builder.envs(&[("REQUEST_ID", req_id.to_string())]);
142144

143145
builder.stdout(LogStream {
144146
prefix: format!("stdout [{req_id}] :: "),
145-
output: output.clone(),
147+
output: Output::Stdout,
146148
});
147149

148150
builder.stderr(LogStream {
149151
prefix: format!("stderr [{req_id}] :: "),
150-
output,
152+
output: Output::Stderr,
151153
});
152154

153155
let mut host = Host {
@@ -319,25 +321,17 @@ impl ProxyHandlerInner {
319321
}
320322
}
321323

322-
type OutputMutex = Arc<tokio::sync::Mutex<std::io::Stdout>>;
323-
324324
#[derive(Clone)]
325-
struct ProxyHandler {
326-
inner: Arc<ProxyHandlerInner>,
327-
output: OutputMutex,
328-
}
325+
struct ProxyHandler(Arc<ProxyHandlerInner>);
329326

330327
impl ProxyHandler {
331328
fn new(cmd: ServeCommand, engine: Engine, instance_pre: InstancePre<Host>) -> Self {
332-
Self {
333-
inner: Arc::new(ProxyHandlerInner {
334-
cmd,
335-
engine,
336-
instance_pre,
337-
next_id: AtomicU64::from(0),
338-
}),
339-
output: Arc::new(tokio::sync::Mutex::new(std::io::stdout())),
340-
}
329+
Self(Arc::new(ProxyHandlerInner {
330+
cmd,
331+
engine,
332+
instance_pre,
333+
next_id: AtomicU64::from(0),
334+
}))
341335
}
342336
}
343337

@@ -351,7 +345,7 @@ impl hyper::service::Service<Request> for ProxyHandler {
351345
fn call(&mut self, req: Request) -> Self::Future {
352346
use http_body_util::BodyExt;
353347

354-
let ProxyHandler { inner, output } = self.clone();
348+
let ProxyHandler(inner) = self.clone();
355349

356350
let (sender, receiver) = tokio::sync::oneshot::channel();
357351

@@ -365,7 +359,7 @@ impl hyper::service::Service<Request> for ProxyHandler {
365359
req.uri()
366360
);
367361

368-
let mut store = inner.cmd.new_store(&inner.engine, req_id, output)?;
362+
let mut store = inner.cmd.new_store(&inner.engine, req_id)?;
369363

370364
let req = store.data_mut().new_incoming_request(
371365
req.map(|body| body.map_err(|e| anyhow::anyhow!(e)).boxed()),
@@ -392,10 +386,28 @@ impl hyper::service::Service<Request> for ProxyHandler {
392386
}
393387
}
394388

389+
#[derive(Clone)]
390+
enum Output {
391+
Stdout,
392+
Stderr,
393+
}
394+
395+
impl Output {
396+
fn write_all(&self, buf: &[u8]) -> anyhow::Result<()> {
397+
use std::io::Write;
398+
399+
match self {
400+
Output::Stdout => std::io::stdout().write_all(buf),
401+
Output::Stderr => std::io::stderr().write_all(buf),
402+
}
403+
.map_err(|e| anyhow!(e))
404+
}
405+
}
406+
395407
#[derive(Clone)]
396408
struct LogStream {
397409
prefix: String,
398-
output: OutputMutex,
410+
output: Output,
399411
}
400412

401413
impl preview2::StdoutStream for LogStream {
@@ -404,7 +416,12 @@ impl preview2::StdoutStream for LogStream {
404416
}
405417

406418
fn isatty(&self) -> bool {
407-
false
419+
use std::io::IsTerminal;
420+
421+
match &self.output {
422+
Output::Stdout => std::io::stdout().is_terminal(),
423+
Output::Stderr => std::io::stderr().is_terminal(),
424+
}
408425
}
409426
}
410427

@@ -420,14 +437,7 @@ impl preview2::HostOutputStream for LogStream {
420437
}
421438
}
422439

423-
let output = self.output.clone();
424-
tokio::task::spawn(async move {
425-
use std::io::Write;
426-
let mut output = output.lock().await;
427-
output.write_all(&msg).expect("writing to stdout");
428-
});
429-
430-
Ok(())
440+
self.output.write_all(&msg).map_err(StreamError::LastOperationFailed)
431441
}
432442

433443
fn flush(&mut self) -> StreamResult<()> {

0 commit comments

Comments
 (0)