use std::sync::Arc;
use tonic::{Request, Response, Status};
use crate::cdc::CdcEngine;
use crate::metrics::{MetricsRecorder, NoopMetrics};
use crate::proto::udb::core::livequery::services::v1 as lq_pb;
use crate::proto::udb::core::livequery::services::v1::live_query_service_server::LiveQueryService;
use crate::runtime::DataBrokerRuntime;
use crate::runtime::channels::ChannelManager;
pub use crate::proto::udb::core::livequery::services::v1::live_query_service_server::LiveQueryServiceServer;
use super::DataBrokerService;
mod budget;
mod config;
mod errors;
mod handlers;
mod predicate;
mod stream;
#[cfg(test)]
mod tests;
use errors::livequery_capability_status;
use stream::LiveQueryStream;
pub struct LiveQueryServiceImpl {
runtime: Option<Arc<DataBrokerRuntime>>,
cdc_engine: Option<Arc<CdcEngine>>,
channels: Option<ChannelManager>,
metrics: Arc<dyn MetricsRecorder>,
}
impl LiveQueryServiceImpl {
pub fn new() -> Self {
Self {
runtime: None,
cdc_engine: None,
channels: None,
metrics: Arc::new(NoopMetrics),
}
}
pub(crate) fn with_runtime(mut self, runtime: Option<Arc<DataBrokerRuntime>>) -> Self {
self.runtime = runtime;
self
}
pub(crate) fn with_cdc_engine(mut self, cdc_engine: Option<Arc<CdcEngine>>) -> Self {
self.cdc_engine = cdc_engine;
self
}
pub(crate) fn with_channels(mut self, channels: Option<ChannelManager>) -> Self {
self.channels = channels;
self
}
pub(crate) fn with_metrics(mut self, metrics: Arc<dyn MetricsRecorder>) -> Self {
self.metrics = metrics;
self
}
fn require_runtime(&self) -> Result<Arc<DataBrokerRuntime>, Status> {
self.runtime.clone().ok_or_else(|| {
livequery_capability_status(
"native_entity_dispatch",
"runtime_native_entity_dispatch",
"live query service requires runtime native-entity dispatch (no runtime configured)",
)
})
}
}
impl Default for LiveQueryServiceImpl {
fn default() -> Self {
Self::new()
}
}
#[tonic::async_trait]
impl LiveQueryService for LiveQueryServiceImpl {
type SubscribeStream = LiveQueryStream;
async fn subscribe(
&self,
request: Request<lq_pb::SubscribeRequest>,
) -> Result<Response<Self::SubscribeStream>, Status> {
handlers::subscribe(self, request).await
}
}
impl DataBrokerService {
pub(crate) fn build_livequery_service(&self) -> LiveQueryServiceImpl {
let runtime = self.runtime.load_full();
let channels = Some(runtime.channels().clone());
LiveQueryServiceImpl::new()
.with_runtime(Some(runtime))
.with_cdc_engine(self.cdc_engine.clone())
.with_channels(channels)
.with_metrics(self.metrics.clone())
}
}