use std::future::Future;
use std::pin::Pin;
use crate::{Object, ObjectPool, ObjectPoolHandle};
use async_channel::{Sender, Receiver};
pub struct ObjPoolContainer<Obj>{
sender: Sender<Obj>,
receiver: Receiver<Obj>
}
impl<Obj:Object + Send> ObjPoolContainer<Obj> {
pub fn new()->ObjPoolContainer<Obj>{
let (sender,receiver) = async_channel::unbounded();
Self{sender,receiver}
}
pub fn set_pool_max(mut self,max:usize)->Self{
let (s,r) = async_channel::bounded(max);
self.sender = s;
self.receiver = r;
self
}
pub fn build(self)->impl ObjectPool<Obj> {
self
}
#[allow(dead_code)]
pub async fn handle<Out,Handle:ObjectPoolHandle<Obj,Out>>(&self, handle:Handle) ->Out{
let obj = self.get().await;
let (oo,result) = handle.handle(obj).await;
if let Some(s) = oo {
self.release(s).await;
}
return result;
}
pub async fn function<Out:Send,F>(&self, function:F) ->Out
where F: FnOnce(Obj)->Pin<Box<dyn Future<Output=(Option<Obj>,Out)>+Send>>+Send
{
let obj = self.get().await;
let (oo,result) = function(obj).await;
if let Some(s) = oo {
self.release(s).await;
}
return result;
}
}
#[async_trait::async_trait]
impl<Obj:Object + Send> ObjectPool<Obj> for ObjPoolContainer<Obj> {
async fn get(&self) -> Obj {
let result = self.receiver.try_recv();
if let Ok(obj) = result{
return obj;
}
let mut obj = Obj::default();
obj.init().await;
return obj;
}
async fn release(&self, mut o: Obj) {
o.reset().await;
let _result = self.sender.try_send(o);
}
}