How to define the future and handle

todo!

How to gracefully shutdown the nested runtime

Using the manutallyDrop to customize drop order of vars.

pub struct BackgroundShutdownRuntime(ManuallyDrop<Runtime>);
 
impl Debug for BackgroundShutdownRuntime {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.debug_tuple("BackgroundShutdownRuntime").finish()
    }
}
 
impl Drop for BackgroundShutdownRuntime {
    fn drop(&mut self) {
        // Safety: The runtime is only dropped once here.
        let runtime = unsafe { ManuallyDrop::take(&mut self.0) };
 
        runtime.shutdown_background();
    }
}

How to implement the object pool

The object pool could be shared with the different threads, that means it should be thread safe

/// A concurrent object pool.
pub struct ObjectPool<T> {
    inner: Arc<ObjectPoolInner<T>>,
}
 
impl<T> Clone for ObjectPool<T> {
    fn clone(&self) -> Self {
        Self {
            inner: self.inner.clone(),
        }
    }
}
 
struct ObjectPoolInner<T> {
    queue: Option<ArrayQueue<T>>,
    create: Box<dyn Fn() -> T + Send + Sync + 'static>,
}
 
impl<T> ObjectPool<T>
where
    T: Default + 'static,
{
    /// Create a new concurrent object pool.
    pub fn new(capacity: usize) -> Self {
        Self::new_with_create(capacity, T::default)
    }
}
 
impl<T> ObjectPool<T> {
    /// Create a new concurrent object pool with object creation method.
    pub fn new_with_create(capacity: usize, create: impl Fn() -> T + Send + Sync + 'static) -> Self {
        let inner = ObjectPoolInner {
            queue: if capacity == 0 {
                None
            } else {
                Some(ArrayQueue::new(capacity))
            },
            create: Box::new(create),
        };
        Self { inner: Arc::new(inner) }
    }
 
    /// Get or create an object from the objcet pool.
    pub fn acquire(&self) -> T {
        self.inner.queue.as_ref().unwrap().pop()
        match self.inner.queue.as_ref() {
            Some(queue) => queue.pop().unwrap_or((self.inner.create)()),
            None => (self.inner.create)(),
        }
    }
 
    /// Give back or release an object from the objcet pool.
    pub fn release(&self, item: T) {
        if let Some(queue) = self.inner.queue.as_ref() {
            let _ = queue.push(item);
        }
    }
}