mirror of
https://git.asonix.dog/asonix/pict-rs
synced 2024-12-23 03:41:23 +00:00
Spawn new task to avoid complexity/bugs
This commit is contained in:
parent
c1d4e3b87e
commit
a6f2082b37
1 changed files with 30 additions and 79 deletions
109
src/stream.rs
109
src/stream.rs
|
@ -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,98 +46,52 @@ 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());
|
|
||||||
|
|
||||||
loop {
|
actix_rt::spawn(async move {
|
||||||
tokio::select! {
|
if let Err(e) = stdin.send(input_stream).await {
|
||||||
res = input_stream.next() => {
|
let _ = tx.send(e).await;
|
||||||
match res {
|
}
|
||||||
Some(Ok(mut bytes)) => {
|
});
|
||||||
if let Some(stdin) = stdin.as_mut() {
|
|
||||||
let mut fut = Box::pin(stdin.write_all_buf(&mut bytes));
|
|
||||||
|
|
||||||
loop {
|
Some(ProcessSinkStream {
|
||||||
tokio::select! {
|
stream: Box::pin(async_stream::stream! {
|
||||||
res = &mut fut => {
|
loop {
|
||||||
if let Err(e) = res {
|
tokio::select! {
|
||||||
yield Err(e.into());
|
opt = rx.recv() => {
|
||||||
}
|
if let Some(e) = opt {
|
||||||
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 {
|
Some(Ok(bytes)) => yield Ok(bytes),
|
||||||
Some(Ok(bytes)) => yield Ok(bytes),
|
Some(Err(e)) => {
|
||||||
Some(Err(e)) => {
|
yield Err(e.into());
|
||||||
yield Err(e.into());
|
break;
|
||||||
break;
|
}
|
||||||
|
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()),
|
||||||
|
}
|
||||||
|
}),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue