1use std::thread;
2
3use mio_extras::channel::{SyncSender, TrySendError};
4
5use crate::structure::duration::Duration;
6
7const TIMEOUT_EPSILON_NS: i64 = 1000; pub const TIMEOUT_FALLBACK: Duration = Duration::from_nanos(20_000_000); pub fn try_send_timeout<T>(
13 sender: &SyncSender<T>,
14 t: T,
15 timeout_opt: Option<Duration>,
16) -> Result<(), TrySendError<T>> {
17 match sender.try_send(t) {
18 Ok(()) => Ok(()), Err(TrySendError::Full(tt)) => {
21 let mut mt = tt;
22 let timeout = timeout_opt.unwrap_or(TIMEOUT_FALLBACK).to_nanoseconds();
23 let mut time_left = timeout;
24 let mut delay = TIMEOUT_EPSILON_NS;
25 while time_left > TIMEOUT_EPSILON_NS {
26 match sender.try_send(mt) {
27 Ok(()) => return Ok(()),
28 Err(TrySendError::Full(tt)) => {
29 thread::sleep(std::time::Duration::from_nanos(delay as u64)); mt = tt;
31 time_left -= delay;
32 delay *= 2;
33 }
34 Err(other) => return Err(other),
35 }
36 }
37 Err(TrySendError::Full(mt))
38 }
39 Err(other) => Err(other),
40 }
41}