rama icon indicating copy to clipboard operation
rama copied to clipboard

make default pool usage easier for external use

Open GlenDC opened this issue 8 months ago • 1 comments

There is currently no default and easy to use PoolConnector for the super common http connector service case... I think we can do better here.

It came up as I was recently helping debug an open source project that recently accepted rama to its benchmarks (sharkbench) and it was really a pain in the but how much work I needed to do with the pool to make it work. That benchmark code doesn't use the easy http web client but a custom client. Here is the pool code I had to write:

let conn_pool = Pool::<ConnStoreFiFoReuseLruDrop<HttpClientService<Body>, BasicConnID>>::new(
    NonZeroU16::new(128).context("create NonZeroU16(128)")?,
    NonZeroU16::new(1024).context("create NonZeroU16(1024)")?,
)
.context("create conn pool")?;

let connector = PooledConnector::new(
    HttpConnector::new(TcpConnector::new().with_dns(try_new_dns_resolver()?)),
    conn_pool,
    BasicHttpConnId,
);

#[derive(Debug)]
#[non_exhaustive]
struct BasicHttpConnId;
type BasicConnID = (Protocol, Authority);

impl<Body> ReqToConnID<(), Request<Body>> for BasicHttpConnId {
    type ConnID = BasicConnID;

    fn id(
        &self,
        ctx: &rama::Context<()>,
        req: &Request<Body>,
    ) -> Result<Self::ConnID, OpaqueError> {
        let req_ctx = match ctx.get::<RequestContext>() {
            Some(ctx) => ctx,
            None => &RequestContext::try_from((ctx, req))?,
        };

        Ok((req_ctx.protocol.clone(), req_ctx.authority.clone()))
    }
}

Ideally however I would just have to write something like this (feel free to do it different, it is more to get the idea of the kind of simplicity I think we can achieve for the common cases:

PooledConnector::http_buider()
    .max_active(128)
    .total_active(1024)
    .build()

Dunno if such a fluent api should be tied to the connector or the Pool. Problem with the Pool is that you do still need access to the ConnId.

Or perhaps an entire different direction, but it has to be easier for the default easy case.

GlenDC avatar Apr 25 '25 19:04 GlenDC

@GlenDC completely agree, the first implementation of the PooledConnector was focussed on giving (hopefully) all the building blocks that were needed to do connection pooling under any circumstance (http, tcp, grouping connections...).

But it's also true that in almost all circumstances we will be using this combination of settings: HttpConnector, BasicConnID and ConnStoreFiFoReuseLruDrop. Only thing that will need to be changed is size of pool probably. So will look into an implementation where we expose this in a more ergonomic way. Should be easy.

soundofspace avatar Apr 29 '25 08:04 soundofspace