mirror of
https://github.com/modrinth/code.git
synced 2026-08-25 09:04:55 +00:00
feat: use postcard for redis serde (#6956)
* redo error handling in xredis * give proper types to metadata fields * add round-trip tests * inline loader enum metadata fields * postcard roundtrips * prepare * bump redis key version * serde-binhum * clippy * fix * fix frontend checking existence of component fields rather than non-null-ness * prepare
This commit is contained in:
@@ -1,14 +1,14 @@
|
||||
use std::time::Duration;
|
||||
|
||||
use eyre::{Result, WrapErr, bail};
|
||||
use prometheus::Registry;
|
||||
|
||||
use super::RedisPool;
|
||||
use super::config::{RedisConfig, RedisTopology};
|
||||
use super::connection::RedisBackendBuildError;
|
||||
use super::metrics::{
|
||||
LogicalPoolStatus, LogicalPoolStatusProvider,
|
||||
register_blocking_pool_metrics,
|
||||
};
|
||||
use super::{Error, RedisPool};
|
||||
|
||||
const POOL_RETAIN_INTERVAL: Duration = Duration::from_secs(30);
|
||||
const MAX_IDLE_CONNECTION_AGE: Duration = Duration::from_secs(5 * 60);
|
||||
@@ -27,9 +27,7 @@ enum RedisBlockingPoolInner {
|
||||
}
|
||||
|
||||
impl RedisBlockingPool {
|
||||
pub(super) async fn new(
|
||||
config: &RedisConfig,
|
||||
) -> Result<Self, RedisBackendBuildError> {
|
||||
pub(super) async fn new(config: &RedisConfig) -> Result<Self> {
|
||||
let pool_size = config.blocking_pool_size();
|
||||
let inner = match config.topology() {
|
||||
RedisTopology::Standalone => {
|
||||
@@ -39,14 +37,16 @@ impl RedisBlockingPool {
|
||||
let manager = deadpool_redis::Manager::new_with_config(
|
||||
config.seed_urls()[0].clone(),
|
||||
connection_config,
|
||||
)?;
|
||||
)
|
||||
.wrap_err("configuring standalone blocking Redis client")?;
|
||||
let pool = deadpool_redis::Pool::builder(manager)
|
||||
.max_size(pool_size.max())
|
||||
.wait_timeout(Some(Duration::from_millis(
|
||||
config.wait_timeout_ms(),
|
||||
)))
|
||||
.runtime(deadpool_redis::Runtime::Tokio1)
|
||||
.build()?;
|
||||
.build()
|
||||
.wrap_err("building standalone blocking Redis pool")?;
|
||||
retain_standalone_pool(pool.clone());
|
||||
RedisBlockingPoolInner::Standalone(pool)
|
||||
}
|
||||
@@ -54,14 +54,16 @@ impl RedisBlockingPool {
|
||||
let manager = deadpool_redis::cluster::Manager::new(
|
||||
config.seed_urls().to_vec(),
|
||||
false,
|
||||
)?;
|
||||
)
|
||||
.wrap_err("configuring clustered blocking Redis client")?;
|
||||
let pool = deadpool_redis::cluster::Pool::builder(manager)
|
||||
.max_size(pool_size.max())
|
||||
.wait_timeout(Some(Duration::from_millis(
|
||||
config.wait_timeout_ms(),
|
||||
)))
|
||||
.runtime(deadpool_redis::Runtime::Tokio1)
|
||||
.build()?;
|
||||
.build()
|
||||
.wrap_err("building clustered blocking Redis pool")?;
|
||||
retain_cluster_pool(pool.clone());
|
||||
RedisBlockingPoolInner::Cluster(pool)
|
||||
}
|
||||
@@ -70,10 +72,7 @@ impl RedisBlockingPool {
|
||||
Ok(Self { inner })
|
||||
}
|
||||
|
||||
pub(super) fn register_metrics(
|
||||
&self,
|
||||
registry: &Registry,
|
||||
) -> Result<(), prometheus::Error> {
|
||||
pub(super) fn register_metrics(&self, registry: &Registry) -> Result<()> {
|
||||
register_blocking_pool_metrics(registry, self.clone())
|
||||
}
|
||||
|
||||
@@ -81,22 +80,33 @@ impl RedisBlockingPool {
|
||||
&self,
|
||||
key: &str,
|
||||
timeout: Duration,
|
||||
) -> Result<Option<[Vec<u8>; 2]>, Error> {
|
||||
) -> Result<Option<[Vec<u8>; 2]>> {
|
||||
if timeout.is_zero() {
|
||||
return Err(Error::InvalidBlockingTimeout);
|
||||
bail!("redis blocking timeout must be greater than zero");
|
||||
}
|
||||
|
||||
let mut command = redis::cmd("BRPOP");
|
||||
command.arg(key).arg(timeout.as_secs_f64());
|
||||
|
||||
let response: Option<(Vec<u8>, Vec<u8>)> = match &self.inner {
|
||||
RedisBlockingPoolInner::Standalone(pool) => {
|
||||
command.query_async(&mut pool.get().await?).await?
|
||||
}
|
||||
RedisBlockingPoolInner::Cluster(pool) => {
|
||||
command.query_async(&mut pool.get().await?).await?
|
||||
}
|
||||
};
|
||||
let response: Option<(Vec<u8>, Vec<u8>)> =
|
||||
match &self.inner {
|
||||
RedisBlockingPoolInner::Standalone(pool) => {
|
||||
let mut connection = pool.get().await.wrap_err(
|
||||
"fetching standalone blocking Redis connection",
|
||||
)?;
|
||||
command.query_async(&mut connection).await.wrap_err(
|
||||
"reading from standalone Redis blocking queue",
|
||||
)?
|
||||
}
|
||||
RedisBlockingPoolInner::Cluster(pool) => {
|
||||
let mut connection = pool.get().await.wrap_err(
|
||||
"fetching clustered blocking Redis connection",
|
||||
)?;
|
||||
command.query_async(&mut connection).await.wrap_err(
|
||||
"reading from clustered Redis blocking queue",
|
||||
)?
|
||||
}
|
||||
};
|
||||
|
||||
Ok(response.map(|(key, value)| [key, value]))
|
||||
}
|
||||
@@ -120,7 +130,7 @@ impl RedisPool {
|
||||
&self,
|
||||
key: &str,
|
||||
timeout: Duration,
|
||||
) -> Result<Option<[Vec<u8>; 2]>, Error> {
|
||||
) -> Result<Option<[Vec<u8>; 2]>> {
|
||||
self.blocking.brpop(key, timeout).await
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user