4 releases (2 breaking)
0.3.0 | Apr 28, 2024 |
---|---|
0.2.0 | Feb 15, 2022 |
0.1.1 | Aug 20, 2020 |
0.1.0 | Aug 17, 2020 |
#331 in Caching
93 downloads per month
Used in warpgrapher
47KB
583 lines
ultra-batch
ultra-batch
is a Rust library to batch and cache database queries or other potentially expensive data lookups. The main motivation for this library is to solve the "N + 1" query problem seen in GraphQL and elsewhere. This library takes heavy influence from the GraphQL Foundation's DataLoader. It's designed primarily for dealing with database queries, but it can be used to batch any potentially expensive data loading operations.
Example Use
First, add tokio
, async-trait
, and anyhow
(optional) as dependencies.
use async_trait::async_trait;
use ultra_batch::{Fetcher, Batcher, Cache};
#[derive(Debug, Clone)]
struct User {
id: u64,
// User model from your DB, etc.
}
struct UserFetcher {
// Database connection, etc.
}
#[async_trait]
impl Fetcher for UserFetcher {
// The thing we can use to look up a single `User` (like an ID)
type Key = u64;
// The thing we are trying to look up
type Value = User;
// Used to indicate the batch request failed (DB connection failed, etc)
type Error = anyhow::Error;
// Fetch a batch of users
async fn fetch(
&self,
keys: &[Self::Key],
values: &mut Cache<'_, Self::Key, Self::Value>,
) -> Result<(), Self::Error> {
let users: Vec<User> = todo!(); // Fetch users based on the given keys
for user in users {
values.insert(user.id, user); // Insert all users we found
}
Ok(())
}
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let fetcher = UserFetcher { /* ... */ };
let batcher = Batcher::build(fetcher).finish();
// Retrieve a user by ID. If `load` gets called in other tasks/threads
// at the same time, then all the requested IDs will get batched together
let user = batcher.load(123).await?;
println!("User: {:?}", user);
Ok(())
}
Minimum Supported Rust Version (MSRV)
ultra-batch
currently supports Rust v1.56. Changes to the MSRV are tracked in the Changelog.
Alternative projects
License
Licensed under either the MIT license or Apache 2.0 license (licensee's choice).
Dependencies
~3.5–10MB
~87K SLoC