2
0
Fork 0
mirror of https://git.asonix.dog/asonix/pict-rs synced 2024-11-10 06:25:00 +00:00

Spawn new task to avoid complexity/bugs

This commit is contained in:
Aode (lion) 2021-08-31 10:17:08 -05:00
parent c1d4e3b87e
commit a6f2082b37

View file

@ -1,8 +1,5 @@
use actix_web::web::Bytes; use actix_web::web::Bytes;
use futures::{ use futures::stream::{LocalBoxStream, Stream, StreamExt};
future::FutureExt,
stream::{LocalBoxStream, Stream, StreamExt},
};
use std::{ use std::{
pin::Pin, pin::Pin,
task::{Context, Poll}, task::{Context, Poll},
@ -49,68 +46,31 @@ impl Process {
self.child.stdout.take().map(ProcessStream::new) self.child.stdout.take().map(ProcessStream::new)
} }
pub(crate) fn sink_stream<S, E>(mut self, mut input_stream: S) -> Option<ProcessSinkStream<E>> pub(crate) fn sink_stream<S, E>(mut self, input_stream: S) -> Option<ProcessSinkStream<E>>
where where
S: Stream<Item = Result<Bytes, E>> + Unpin + 'static, S: Stream<Item = Result<Bytes, E>> + Unpin + 'static,
E: From<std::io::Error> + 'static, E: From<std::io::Error> + 'static,
{ {
let mut stdin = self.child.stdin.take(); let mut stdin = self.take_sink()?;
let mut stdout = self.take_stream()?; let mut stdout = self.take_stream()?;
let s = async_stream::stream! { let (tx, mut rx) = tokio::sync::mpsc::channel(1);
let mut wait = Box::pin(self.child.wait().fuse());
actix_rt::spawn(async move {
if let Err(e) = stdin.send(input_stream).await {
let _ = tx.send(e).await;
}
});
Some(ProcessSinkStream {
stream: Box::pin(async_stream::stream! {
loop { loop {
tokio::select! { tokio::select! {
res = input_stream.next() => { opt = rx.recv() => {
match res { if let Some(e) = opt {
Some(Ok(mut bytes)) => {
if let Some(stdin) = stdin.as_mut() {
let mut fut = Box::pin(stdin.write_all_buf(&mut bytes));
loop {
tokio::select! {
res = &mut fut => {
if let Err(e) = res {
yield Err(e.into());
}
break;
}
res = stdout.next() => {
match res {
Some(Ok(bytes)) => yield Ok(bytes),
Some(Err(e)) => {
yield Err(e.into());
break;
}
None => break,
}
}
res = &mut wait => {
match res {
Ok(status) if !status.success() => {
yield Err(std::io::Error::from(std::io::ErrorKind::Other).into());
break;
},
Err(e) => {
yield Err(e.into());
break;
}
_ => (),
}
}
}
}
}
},
Some(Err(e)) => {
yield Err(e); yield Err(e);
break; break;
} }
None => {
stdin.take();
},
}
} }
res = stdout.next() => { res = stdout.next() => {
match res { match res {
@ -122,25 +82,16 @@ impl Process {
None => break, None => break,
} }
} }
res = &mut wait => {
match res {
Ok(status) if !status.success() => {
yield Err(std::io::Error::from(std::io::ErrorKind::Other).into());
break;
},
Err(e) => {
yield Err(e.into());
break;
}
_ => (),
} }
} }
}
}
};
Some(ProcessSinkStream { drop(stdout);
stream: Box::pin(s), match self.child.wait().await {
Ok(status) if status.success() => return,
Ok(_) => yield Err(std::io::Error::from(std::io::ErrorKind::Other).into()),
Err(e) => yield Err(e.into()),
}
}),
}) })
} }
} }