use crate::AsyncTypedCommands;
use crate::client::{GlideClient, GlideClusterClient};
use crate::config::{GlideClientConfiguration, GlideClusterClientConfiguration};
use crate::executor::CustomCommand;
use crate::pipeline_options::PipelineOptions;
use crate::routes::Route;
use crate::write::ToValkeyArgs;
use crate::{ValkeyResult, ValkeyValue};
use std::future::Future;
use std::sync::OnceLock;
use tokio::runtime::{Builder, Runtime};
mod pipeline;
pub use pipeline::PipelineExt;
fn runtime() -> &'static Runtime {
static RUNTIME: OnceLock<Runtime> = OnceLock::new();
RUNTIME.get_or_init(|| {
Builder::new_multi_thread()
.enable_all()
.thread_name("glide-sync")
.build()
.expect("failed to build the shared GLIDE sync runtime")
})
}
pub fn block_on<F: Future>(future: F) -> F::Output {
runtime().block_on(future)
}
#[derive(Clone)]
pub struct SyncGlideClient {
inner: GlideClient,
}
impl SyncGlideClient {
pub fn connect(config: GlideClientConfiguration) -> ValkeyResult<Self> {
let inner = runtime().block_on(GlideClient::connect(config))?;
Ok(SyncGlideClient { inner })
}
pub fn async_client(&self) -> &GlideClient {
&self.inner
}
pub fn run<F, Fut, T>(&self, f: F) -> T
where
F: FnOnce(GlideClient) -> Fut,
Fut: Future<Output = T>,
{
runtime().block_on(f(self.inner.clone()))
}
pub fn update_connection_password(
&self,
password: Option<String>,
immediate_auth: bool,
) -> ValkeyResult<()> {
runtime().block_on(
self.inner
.update_connection_password(password, immediate_auth),
)
}
pub fn custom_command<A: ToValkeyArgs + Sync>(&self, args: &[A]) -> ValkeyResult<ValkeyValue> {
runtime().block_on(self.inner.custom_command(args))
}
pub fn exec(
&self,
pipeline: &crate::pipeline::Pipeline,
raise_on_error: bool,
options: &PipelineOptions,
) -> ValkeyResult<Vec<ValkeyValue>> {
runtime().block_on(self.inner.exec(pipeline, raise_on_error, options))
}
pub fn ping(&self) -> ValkeyResult<String> {
runtime().block_on(AsyncTypedCommands::ping(&self.inner))
}
}
#[derive(Clone)]
pub struct SyncGlideClusterClient {
inner: GlideClusterClient,
}
impl SyncGlideClusterClient {
pub fn connect(config: GlideClusterClientConfiguration) -> ValkeyResult<Self> {
let inner = runtime().block_on(GlideClusterClient::connect(config))?;
Ok(SyncGlideClusterClient { inner })
}
pub fn async_client(&self) -> &GlideClusterClient {
&self.inner
}
pub fn run<F, Fut, T>(&self, f: F) -> T
where
F: FnOnce(GlideClusterClient) -> Fut,
Fut: Future<Output = T>,
{
runtime().block_on(f(self.inner.clone()))
}
pub fn custom_command<A: ToValkeyArgs + Sync>(&self, args: &[A]) -> ValkeyResult<ValkeyValue> {
runtime().block_on(self.inner.custom_command(args))
}
pub fn custom_command_with_route<A: ToValkeyArgs + Sync>(
&self,
args: &[A],
route: Route,
) -> ValkeyResult<ValkeyValue> {
runtime().block_on(self.inner.custom_command_with_route(args, route))
}
pub fn update_connection_password(
&self,
password: Option<String>,
immediate_auth: bool,
) -> ValkeyResult<()> {
runtime().block_on(
self.inner
.update_connection_password(password, immediate_auth),
)
}
pub fn exec(
&self,
pipeline: &crate::pipeline::Pipeline,
raise_on_error: bool,
route: Option<crate::Route>,
options: &PipelineOptions,
) -> ValkeyResult<Vec<ValkeyValue>> {
runtime().block_on(self.inner.exec(pipeline, raise_on_error, route, options))
}
pub fn ping(&self) -> ValkeyResult<String> {
runtime().block_on(AsyncTypedCommands::ping(&self.inner))
}
}
macro_rules! impl_sync_command_dispatch {
($ty:ty) => {
#[::sealed::sealed]
impl crate::commands::core::SyncCommandDispatch for $ty {
fn glide_dispatch_command(&self, cmd: crate::cmd::Cmd) -> ValkeyResult<ValkeyValue> {
runtime().block_on(
crate::commands::core::CommandDispatch::glide_dispatch_command(
&self.inner,
cmd,
),
)
}
}
};
}
impl_sync_command_dispatch!(SyncGlideClient);
impl_sync_command_dispatch!(SyncGlideClusterClient);
macro_rules! impl_sync_script_invoke {
($ty:ty) => {
#[::sealed::sealed]
impl crate::script::ScriptInvokeSync for $ty {
fn glide_invoke_script(
&self,
hash: &str,
keys: &[Vec<u8>],
args: &[Vec<u8>],
) -> ValkeyResult<ValkeyValue> {
runtime().block_on(crate::script::ScriptInvoke::glide_invoke_script(
&self.inner,
hash,
keys,
args,
))
}
}
};
}
impl_sync_script_invoke!(SyncGlideClient);
impl_sync_script_invoke!(SyncGlideClusterClient);
macro_rules! impl_sync_pipeline_dispatch {
($ty:ty) => {
#[::sealed::sealed]
impl pipeline::SyncPipelineDispatch for $ty {
fn glide_dispatch_pipeline<T: crate::value::FromValkeyValue + Send>(
&self,
pipeline: &crate::pipeline::Pipeline,
) -> ValkeyResult<T> {
let async_conn = self.inner.clone();
runtime().block_on(crate::client::PipelineExt::query_async(
pipeline,
&async_conn,
))
}
}
};
}
impl_sync_pipeline_dispatch!(SyncGlideClient);
impl_sync_pipeline_dispatch!(SyncGlideClusterClient);