use crate::reflection::descriptor::ServiceDescriptorCache;
use prost_reflect::{DescriptorPool, ServiceDescriptor};
use std::sync::Arc;
use tokio::sync::RwLock;
use tonic::Status;
use tracing::{debug, trace};
#[derive(Debug, Clone)]
pub struct DescriptorCache {
cache: Arc<RwLock<ServiceDescriptorCache>>,
}
impl Default for DescriptorCache {
fn default() -> Self {
Self::new()
}
}
impl DescriptorCache {
pub fn new() -> Self {
Self {
cache: Arc::new(RwLock::new(ServiceDescriptorCache::new())),
}
}
pub async fn add_service(&self, service: ServiceDescriptor) {
let service_name = service.full_name().to_string();
trace!("Adding service to cache: {}", service_name);
let mut cache = self.cache.write().await;
cache.add_service(service);
debug!("Added service to cache: {}", service_name);
}
pub async fn get_method(
&self,
service_name: &str,
method_name: &str,
) -> Result<prost_reflect::MethodDescriptor, Status> {
trace!("Getting method from cache: {}::{}", service_name, method_name);
let cache = self.cache.read().await;
cache.get_method(service_name, method_name).cloned()
}
pub async fn get_service(&self, service_name: &str) -> Result<ServiceDescriptor, Status> {
trace!("Getting service from cache: {}", service_name);
let cache = self.cache.read().await;
cache.get_service_with_error(service_name).cloned()
}
pub async fn contains_service(&self, service_name: &str) -> bool {
let cache = self.cache.read().await;
cache.contains_service(service_name)
}
pub async fn contains_method(&self, service_name: &str, method_name: &str) -> bool {
let cache = self.cache.read().await;
cache.contains_method(service_name, method_name)
}
pub async fn populate_from_pool(&self, pool: Option<&DescriptorPool>) {
let pool = match pool {
Some(pool) => pool,
None => {
debug!("No descriptor pool provided, skipping cache population");
return;
}
};
trace!("Populating cache from descriptor pool");
let mut cache = self.cache.write().await;
for service in pool.services() {
cache.add_service(service);
}
debug!("Populated cache with {} services", pool.services().count());
}
pub async fn service_count(&self) -> usize {
let cache = self.cache.read().await;
cache.service_count()
}
pub async fn method_count(&self) -> usize {
let cache = self.cache.read().await;
cache.method_count()
}
}
#[cfg(test)]
mod tests {
#[test]
fn test_module_compiles() {
}
}