- Implement GetEpochHistory forwarding in MonitoringServiceProxy - Fix clippy integer suffix style (0usize → 0_usize) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
109 lines
3.7 KiB
Rust
109 lines
3.7 KiB
Rust
//! Monitoring Service Proxy - Zero-copy gRPC forwarding for training metrics
|
|
//!
|
|
//! Forwards `GetLiveTrainingMetrics` and `StreamTrainingMetrics` from FXT clients
|
|
//! to the monitoring-service backend. Follows the same pattern as `MlTrainingProxy`.
|
|
|
|
use futures::Stream;
|
|
use std::pin::Pin;
|
|
use tonic::{Request, Response, Status};
|
|
use tracing::{error, info, instrument};
|
|
|
|
use crate::monitoring::monitoring_service_client::MonitoringServiceClient;
|
|
use crate::monitoring::monitoring_service_server::{MonitoringService, MonitoringServiceServer};
|
|
use crate::monitoring::{
|
|
GetEpochHistoryRequest, GetEpochHistoryResponse, GetLiveTrainingMetricsRequest,
|
|
GetLiveTrainingMetricsResponse, StreamTrainingMetricsRequest,
|
|
};
|
|
|
|
/// Monitoring Service Proxy
|
|
///
|
|
/// Zero-copy forwarding of gRPC requests to the monitoring-service backend.
|
|
#[derive(Debug, Clone)]
|
|
pub struct MonitoringServiceProxy {
|
|
client: MonitoringServiceClient<tonic::transport::Channel>,
|
|
}
|
|
|
|
impl MonitoringServiceProxy {
|
|
pub fn new(client: MonitoringServiceClient<tonic::transport::Channel>) -> Self {
|
|
Self { client }
|
|
}
|
|
|
|
pub fn into_server(self) -> MonitoringServiceServer<MonitoringServiceProxy> {
|
|
MonitoringServiceServer::new(self)
|
|
}
|
|
}
|
|
|
|
#[tonic::async_trait]
|
|
impl MonitoringService for MonitoringServiceProxy {
|
|
type StreamTrainingMetricsStream =
|
|
Pin<Box<dyn Stream<Item = Result<GetLiveTrainingMetricsResponse, Status>> + Send>>;
|
|
|
|
#[instrument(skip(self, request), fields(request_id = %uuid::Uuid::new_v4()), err)]
|
|
async fn get_live_training_metrics(
|
|
&self,
|
|
request: Request<GetLiveTrainingMetricsRequest>,
|
|
) -> Result<Response<GetLiveTrainingMetricsResponse>, Status> {
|
|
info!("Proxying GetLiveTrainingMetrics request");
|
|
|
|
let mut client = self.client.clone();
|
|
let response = client
|
|
.get_live_training_metrics(request)
|
|
.await
|
|
.map_err(|e| {
|
|
error!("Backend GetLiveTrainingMetrics failed: {}", e);
|
|
e
|
|
})?;
|
|
|
|
info!("GetLiveTrainingMetrics forwarded successfully");
|
|
Ok(response)
|
|
}
|
|
|
|
#[instrument(skip(self, request), fields(request_id = %uuid::Uuid::new_v4()), err)]
|
|
async fn stream_training_metrics(
|
|
&self,
|
|
request: Request<StreamTrainingMetricsRequest>,
|
|
) -> Result<Response<Self::StreamTrainingMetricsStream>, Status> {
|
|
info!("Proxying StreamTrainingMetrics streaming request");
|
|
|
|
let mut client = self.client.clone();
|
|
let stream_response = client
|
|
.stream_training_metrics(request)
|
|
.await
|
|
.map_err(|e| {
|
|
error!("Backend StreamTrainingMetrics failed: {}", e);
|
|
e
|
|
})?;
|
|
|
|
let stream = stream_response.into_inner();
|
|
let boxed_stream = Box::pin(stream) as Self::StreamTrainingMetricsStream;
|
|
|
|
info!("StreamTrainingMetrics forwarded successfully");
|
|
Ok(Response::new(boxed_stream))
|
|
}
|
|
|
|
#[instrument(skip(self, request), fields(request_id = %uuid::Uuid::new_v4()), err)]
|
|
async fn get_epoch_history(
|
|
&self,
|
|
request: Request<GetEpochHistoryRequest>,
|
|
) -> Result<Response<GetEpochHistoryResponse>, Status> {
|
|
info!("Proxying GetEpochHistory request");
|
|
|
|
let mut client = self.client.clone();
|
|
let response = client.get_epoch_history(request).await.map_err(|e| {
|
|
error!("Backend GetEpochHistory failed: {}", e);
|
|
e
|
|
})?;
|
|
|
|
info!("GetEpochHistory forwarded successfully");
|
|
Ok(response)
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
#[test]
|
|
fn test_proxy_creation() {
|
|
// Full integration tests require running backend service
|
|
}
|
|
}
|