Skip to content

Commit 06fc207

Browse files
authored
Merge pull request #21 from ashjorda/dashboard-health-status-fix
refactor(health-service): simplify health status tracking with global…
2 parents 2c9395a + 2835967 commit 06fc207

4 files changed

Lines changed: 249 additions & 150 deletions

File tree

config/config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ jwt_validation:
8686
# Datasource URL - must match the URL configured in your Webex Contact Center datasource
8787
# This should be the publicly accessible URL of your gateway (including port if non-standard)
8888
# Example: "https://your-gateway-domain.com:443"
89-
datasource_url: "https://b9eb5df4443d.ngrok-free.app"
89+
datasource_url: ""
9090

9191
# Datasource schema UUID - typically this is the BYOVA schema UUID
9292
# This is the schema ID from https://github.com/webex/dataSourceSchemas

src/core/health_service.py

Lines changed: 57 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,15 @@
1818
class HealthCheckService(health_pb2_grpc.HealthServicer):
1919
"""
2020
Health check service that provides real-time health monitoring.
21-
21+
2222
This service monitors the actual operational status of gateway components
2323
including connector availability and service health.
2424
"""
2525

2626
def __init__(self, router: Optional[VirtualAgentRouter] = None):
2727
"""
2828
Initialize the health check service.
29-
29+
3030
Args:
3131
router: VirtualAgentRouter instance for checking connector health
3232
"""
@@ -35,19 +35,23 @@ def __init__(self, router: Optional[VirtualAgentRouter] = None):
3535
self.logger = logging.getLogger(__name__)
3636
self._lock = threading.Lock()
3737
self._service_status = {}
38-
38+
3939
# Initialize with unknown status - will be updated on first check
4040
self._initialize_services()
41-
41+
4242
self.logger.info("HealthCheckService initialized with real health monitoring")
4343

4444
def _initialize_services(self):
4545
"""Initialize service statuses with unknown state."""
4646
with self._lock:
4747
# Initialize with unknown status - will be updated by health checks
4848
self._service_status[""] = health_pb2.HealthCheckResponse.SERVICE_UNKNOWN
49-
self._service_status["byova.gateway"] = health_pb2.HealthCheckResponse.SERVICE_UNKNOWN
50-
self._service_status["byova.VoiceVirtualAgentService"] = health_pb2.HealthCheckResponse.SERVICE_UNKNOWN
49+
self._service_status["byova.gateway"] = (
50+
health_pb2.HealthCheckResponse.SERVICE_UNKNOWN
51+
)
52+
self._service_status["byova.VoiceVirtualAgentService"] = (
53+
health_pb2.HealthCheckResponse.SERVICE_UNKNOWN
54+
)
5155

5256
def _update_service_health(self):
5357
"""Update service health status based on actual system state."""
@@ -57,38 +61,57 @@ def _update_service_health(self):
5761
if self.router:
5862
available_agents = self.router.get_all_available_agents()
5963
has_agents = len(available_agents) > 0
60-
64+
6165
if has_agents:
6266
# Gateway is serving if it has available agents
63-
self._service_status["byova.gateway"] = health_pb2.HealthCheckResponse.SERVING
64-
self._service_status["byova.VoiceVirtualAgentService"] = health_pb2.HealthCheckResponse.SERVING
65-
self._service_status[""] = health_pb2.HealthCheckResponse.SERVING
66-
self.logger.debug(f"Health check: SERVING - {len(available_agents)} agents available")
67+
self._service_status["byova.gateway"] = (
68+
health_pb2.HealthCheckResponse.SERVING
69+
)
70+
self._service_status["byova.VoiceVirtualAgentService"] = (
71+
health_pb2.HealthCheckResponse.SERVING
72+
)
73+
self._service_status[""] = (
74+
health_pb2.HealthCheckResponse.SERVING
75+
)
6776
else:
6877
# No agents available
69-
self._service_status["byova.gateway"] = health_pb2.HealthCheckResponse.NOT_SERVING
70-
self._service_status["byova.VoiceVirtualAgentService"] = health_pb2.HealthCheckResponse.NOT_SERVING
71-
self._service_status[""] = health_pb2.HealthCheckResponse.NOT_SERVING
72-
self.logger.warning("Health check: NOT_SERVING - No agents available")
78+
self._service_status["byova.gateway"] = (
79+
health_pb2.HealthCheckResponse.NOT_SERVING
80+
)
81+
self._service_status["byova.VoiceVirtualAgentService"] = (
82+
health_pb2.HealthCheckResponse.NOT_SERVING
83+
)
84+
self._service_status[""] = (
85+
health_pb2.HealthCheckResponse.NOT_SERVING
86+
)
7387
else:
7488
# No router available
75-
self._service_status["byova.gateway"] = health_pb2.HealthCheckResponse.SERVICE_UNKNOWN
76-
self._service_status["byova.VoiceVirtualAgentService"] = health_pb2.HealthCheckResponse.SERVICE_UNKNOWN
77-
self._service_status[""] = health_pb2.HealthCheckResponse.SERVICE_UNKNOWN
78-
self.logger.warning("Health check: SERVICE_UNKNOWN - No router available")
79-
89+
self._service_status["byova.gateway"] = (
90+
health_pb2.HealthCheckResponse.SERVICE_UNKNOWN
91+
)
92+
self._service_status["byova.VoiceVirtualAgentService"] = (
93+
health_pb2.HealthCheckResponse.SERVICE_UNKNOWN
94+
)
95+
self._service_status[""] = (
96+
health_pb2.HealthCheckResponse.SERVICE_UNKNOWN
97+
)
8098
except Exception as e:
8199
self.logger.error(f"Error updating service health: {e}")
82-
# Set all services to unknown on error
83100
with self._lock:
84-
self._service_status[""] = health_pb2.HealthCheckResponse.SERVICE_UNKNOWN
85-
self._service_status["byova.gateway"] = health_pb2.HealthCheckResponse.SERVICE_UNKNOWN
86-
self._service_status["byova.VoiceVirtualAgentService"] = health_pb2.HealthCheckResponse.SERVICE_UNKNOWN
101+
self._service_status[""] = (
102+
health_pb2.HealthCheckResponse.SERVICE_UNKNOWN
103+
)
104+
self._service_status["byova.gateway"] = (
105+
health_pb2.HealthCheckResponse.SERVICE_UNKNOWN
106+
)
107+
self._service_status["byova.VoiceVirtualAgentService"] = (
108+
health_pb2.HealthCheckResponse.SERVICE_UNKNOWN
109+
)
87110

88111
def set_service_status(self, service_name: str, status: int):
89112
"""
90113
Set the health status for a specific service.
91-
114+
92115
Args:
93116
service_name: Name of the service
94117
status: Health status (from health_pb2.HealthCheckResponse)
@@ -100,34 +123,36 @@ def set_service_status(self, service_name: str, status: int):
100123
def Check(self, request, context):
101124
"""
102125
Check the health of a specific service.
103-
126+
104127
Args:
105128
request: HealthCheckRequest containing service name
106129
context: gRPC context
107-
130+
108131
Returns:
109132
HealthCheckResponse with current service status
110133
"""
111134
service_name = request.service
112-
135+
113136
# Update health status before responding
114137
self._update_service_health()
115-
138+
116139
with self._lock:
117140
if service_name in self._service_status:
118141
status = self._service_status[service_name]
119142
self.logger.debug(f"Health check for '{service_name}': {status}")
120143
return health_pb2.HealthCheckResponse(status=status)
121144
else:
122-
self.logger.warning(f"Health check for unknown service '{service_name}': SERVICE_UNKNOWN")
145+
self.logger.warning(
146+
f"Health check for unknown service '{service_name}': SERVICE_UNKNOWN"
147+
)
123148
return health_pb2.HealthCheckResponse(
124149
status=health_pb2.HealthCheckResponse.SERVICE_UNKNOWN
125150
)
126151

127152
def Watch(self, request, context):
128153
"""
129154
Watch for health status changes (streaming).
130-
155+
131156
This is a placeholder implementation - streaming health updates
132157
are not currently implemented.
133158
"""
@@ -139,7 +164,7 @@ def Watch(self, request, context):
139164
def get_all_service_statuses(self):
140165
"""
141166
Get all service statuses for monitoring dashboard.
142-
167+
143168
Returns:
144169
Dictionary of service names to status codes
145170
"""

0 commit comments

Comments
 (0)