You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

67 lines
1.7 KiB

//! The actual running task
use super::*;
use futures::{
prelude::*,
future::OptionFuture,
};
use std::time::Duration;
pub type SupervisorError = (); //TODO
pub type Error = (); // TODO
pub(super) fn spawn_supervisor(service: Service) -> JoinHandle<Result<(), SupervisorError>>
{
tokio::spawn(async move {
//TODO: Spawn slave and handle its exiting, restarting, etc according to config
Ok(())
})
}
/// Delay for a number of **nanoseconds** between the specified bounds
fn jitter_for(bounds: (u64, u64)) -> OptionFuture<impl Future<Output = ()> + 'static>
{
match bounds.jitter() {
0 => None.into(),
x => Some(tokio::time::delay_for(Duration::from_nanos(x))).into()
}
}
fn spawn_slave(service: Service) -> JoinHandle<Result<(), Error>>
{
let Service { inner: service, rx } = service;
tokio::spawn(async move {
let cfg = service.opt.as_ref();
let mut rx = rx
.chunk(cfg.req_dispatch_chunk.into())
.lag(cfg.req_dispatch_delay.unwrap_or(Duration::ZERO));
let mut timeout = cfg.req_dispatch_force_timeout.map(tokio::time::interval);
loop {
tokio::select! {
block = rx.next() => {
match block {
Some(block) => {
if let Some(bounds) = cfg.req_dispatch_jitter.and_then(|x| (x.0 + x.1 > 0).then(|| x)) {
// Jitter delay.
jitter_for(bounds).await;
}
// TODO: Filter and then/or process this block
},
None => {
// Reached the end of stream, exit gracefully.
break;
}
}
}
_ = OptionFuture::from(timeout.as_mut().map(|x| x.tick())), if timeout.is_some() => {
// Cause the `rx` to release a non-full chunk.
rx.get_mut().push_now();
}
}
}
Ok(())
})
}