Files
zhenyi 716f952bb6 feat(message): add comprehensive message system with database migrations and health checks
- Add database migrations for message base table with indexes for efficient querying
- Implement rich content support with attachment, embed, and poll tables
- Create social features including reactions, bookmarks, mentions, and read states
- Add thread management with participant tracking and resolution capabilities
- Include article posts with title, cover image, tags, and engagement metrics
- Support scheduled messages, stickers, forwards, and interactive components
- Fix UUID defaults and ensure proper uniqueness constraints for drafts
- Add gRPC health server for imks and health check client for appks connectivity
- Replace non-connectable 0.0.0.0 addresses with localhost in service discovery
- Normalize addresses during RPC configuration to handle bind address issues
2026-06-11 23:07:38 +08:00

64 lines
2.1 KiB
Rust

//! gRPC health module for imks.
//!
//! Provides:
//! - imks's own gRPC health server (for external health checks)
//! - Health check client for probing appks health (5s interval)
use std::net::SocketAddr;
use std::time::Duration;
use tonic_health::pb::HealthCheckRequest;
use tonic_health::pb::health_check_response::ServingStatus;
use tonic_health::pb::health_client::HealthClient;
use crate::{ImksError, ImksResult};
/// Start imks's own gRPC health server on the given address.
///
/// Reports `SERVING` for the overall server status (empty service name).
pub async fn start_health_server(addr: SocketAddr) -> ImksResult<()> {
let (reporter, health_service) = tonic_health::server::health_reporter();
// Empty service name = overall server health.
// reporter is an owned handle — the server will remain SERVING
// indefinitely unless a caller updates the status.
reporter
.set_service_status("", tonic_health::ServingStatus::Serving)
.await;
tracing::info!(%addr, "imks gRPC health server started");
tonic::transport::Server::builder()
.add_service(health_service)
.serve(addr)
.await
.map_err(|e| ImksError::Internal(format!("Health gRPC server: {e:?}")))?;
Ok(())
}
/// Check appks health by opening a short-lived gRPC connection and calling `Check`.
///
/// Uses a 3-second connect timeout to fail fast when appks is unreachable.
pub async fn check_appks_health(addr: &str) -> ImksResult<bool> {
let endpoint = tonic::transport::Endpoint::from_shared(addr.to_string())
.map_err(|e| ImksError::Internal(format!("health endpoint: {e}")))?;
// Short-lived connection for health probe only
let channel = endpoint
.connect_timeout(Duration::from_secs(3))
.connect()
.await
.map_err(ImksError::GrpcTransport)?;
let mut client = HealthClient::new(channel);
let resp = client
.check(HealthCheckRequest {
service: "".to_string(),
})
.await
.map_err(ImksError::GrpcStatus)?;
Ok(resp.into_inner().status == ServingStatus::Serving as i32)
}