#pool #tokio #resources #ecosystem #generic #future #manage

nightly tokio-resource-pool

为Tokio生态系统提供的通用资源池

11个版本 (4个破坏性版本)

0.5.0-alpha.12019年9月22日
0.5.0-alpha.02019年9月7日
0.4.1 2019年7月28日
0.3.2 2019年7月13日
0.1.2 2019年5月23日

#1475 in 异步

Download history 2/week @ 2024-03-10 23/week @ 2024-03-31

每月51次下载
tokio-redis-pool中使用

MIT许可证

30KB
513

为Tokio生态系统提供的通用资源池。

文档

请参阅docs.rs上托管的相关文档

替代方案

还有一个名为bb8的资源池。它有两个显著的区别。

  • API不同。这个库提供了一个指向你的资源的struct,而bb8将资源转换为返回资源的Future闭包。

  • 回收的方式不同。这个库在资源返回时立即回收资源,而bb8在给定的时间间隔内回收资源。


lib.rs:

为Tokio生态系统提供的通用资源池。

示例

要使用它,您需要为您的资源实现Manage,然后使用Builder创建一个Pool。完成此操作后,您可以通过调用Pool::check_out来请求资源。

// TODO: Update this example when `redis` supports `tokio` 0.2.

use futures::{try_ready, Async, Poll};
use futures::future::{lazy, Future, FutureResult, IntoFuture};
use redis::{RedisError, RedisFuture, RedisResult};
use redis::aio::{Connection, ConnectionLike};
use tokio;

use tokio_resource_pool::{Builder, CheckOut, Manage, Pool, Status, RealDependencies};

struct RedisManager {
    client: redis::Client,
}

impl RedisManager {
    fn new(url: impl redis::IntoConnectionInfo) -> RedisResult<Self> {
        let client = redis::Client::open(url)?;
        Ok(Self { client })
    }
}

impl Manage for RedisManager {
    type Resource = Connection;

    type Dependencies = RealDependencies;

    type CheckOut = RedisCheckOut;

    type Error = RedisError;

    type CreateFuture = Box<dyn Future<Item = Self::Resource, Error = Self::Error> + Send>;

    fn create(&self) -> Self::CreateFuture {
        Box::new(self.client.get_async_connection())
    }

    fn status(&self, _: &Self::Resource) -> Status {
        Status::Valid
    }

    type RecycleFuture = RecycleFuture;

    fn recycle(&self, connection: Self::Resource) -> Self::RecycleFuture {
        let inner = redis::cmd("PING").query_async::<_, ()>(connection);
        RecycleFuture { inner }
    }
}

pub struct RecycleFuture {
    inner: RedisFuture<(Connection, ())>,
}

impl Future for RecycleFuture {
    type Item = Option<Connection>;

    type Error = RedisError;

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        let (connection, ()) = try_ready!(self.inner.poll());
        Ok(Async::Ready(Some(connection)))
    }
}

pub struct RedisCheckOut {
    inner: CheckOut<RedisManager>,
}

impl ConnectionLike for RedisCheckOut {
    fn req_packed_command(
        self,
        cmd: Vec<u8>,
    ) -> Box<dyn Future<Item = (Self, redis::Value), Error = RedisError> + Send> {
        let borrower = move |connection: Connection| connection.req_packed_command(cmd);
        Box::new(self.inner.lend(borrower))
    }

    fn req_packed_commands(
        self,
        cmd: Vec<u8>,
        offset: usize,
        count: usize,
    ) -> Box<dyn Future<Item = (Self, Vec<redis::Value>), Error = RedisError> + Send> {
        let borrower =
            move |connection: Connection| connection.req_packed_commands(cmd, offset, count);
        Box::new(self.inner.lend(borrower))
    }

    fn get_db(&self) -> i64 {
        self.inner.get_db()
    }
}

impl From<CheckOut<RedisManager>> for RedisCheckOut {
    fn from(inner: CheckOut<RedisManager>) -> Self {
        Self { inner }
    }
}

# fn main() -> RedisResult<()> {
let manager = RedisManager::new("redis://127.0.0.1/")?;
tokio::run(lazy(move || {
    let pool = Builder::new().build(4, manager);
    tokio::spawn(
        pool.check_out()
            .and_then(|connection| {
                redis::cmd("INFO").query_async::<_, redis::InfoDict>(connection)
            })
            .map(|(_, info)| println!("{:#?}", info))
            .map_err(|error| eprintln!("error: {}", error)),
    )
}));
# Ok(())
# }

替代方案

还有一个名为bb8的资源池。它有两个显著的区别。

  • API不同。这个库提供了一个指向你的资源的struct,而bb8将资源转换为返回资源的Future闭包。

  • 回收的方式不同。这个库在资源返回时立即回收资源,而bb8在给定的时间间隔内回收资源。

依赖项

~1.5MB
~24K SLoC