-
Notifications
You must be signed in to change notification settings - Fork 615
[CHORE]: GatewayService creates uninitialized service instances (ToolService, PromptService, ResourceService) #2256
Copy link
Copy link
Labels
SHOULDP2: Important but not vital; high-value items that are not crucial for the immediate releaseP2: Important but not vital; high-value items that are not crucial for the immediate releasechoreLinting, formatting, dependency hygiene, or project maintenance choresLinting, formatting, dependency hygiene, or project maintenance chorespythonPython / backend development (FastAPI)Python / backend development (FastAPI)
Milestone
Description
Summary
GatewayService creates private instances of ToolService, PromptService, and ResourceService without calling their initialize() methods. This means events emitted by these services (e.g., _notify_tool_activated, _notify_prompt_deactivated) won't propagate to Redis or any subscribers.
Current Behavior
# mcpgateway/services/gateway_service.py:383-385
self.tool_service = ToolService()
self.prompt_service = PromptService()
self.resource_service = ResourceService()These services have an initialize() method that sets up the EventService Redis client:
# Example from prompt_service.py:204-207
async def initialize(self) -> None:
"""Initialize the service."""
logger.info("Initializing prompt service")
await self._event_service.initialize()Without initialize(), the _redis_client remains None and events are only pushed to local _event_subscribers queues. If no local subscribers exist, events are silently dropped.
Why This Currently Works
- Database state changes are committed - The actual
enabledfield updates happen regardless - Cache invalidation is explicit -
cache.invalidate_prompts()/cache.invalidate_resources()is called after batch operations - Global singletons exist -
main.pycreates and properly initializes global instances that handle event propagation for the app
Impact
- Events emitted during gateway state changes (activate/deactivate) don't reach Redis subscribers
- Cross-worker event propagation for these specific operations may not work
- UI updates relying on these events won't trigger (though cache invalidation handles most cases)
Proposed Solution
Option 1: Reuse Global Singletons (Preferred)
Refactor to use the initialized global instances from main.py:
# This requires careful handling of circular imports
from mcpgateway.services.tool_service import tool_service # singleton
from mcpgateway.services.prompt_service import prompt_service # singleton
from mcpgateway.services.resource_service import resource_service # singleton
class GatewayService:
def __init__(self):
self.tool_service = tool_service
self.prompt_service = prompt_service
self.resource_service = resource_serviceOption 2: Initialize in GatewayService.initialize()
async def initialize(self) -> None:
# ... existing initialization ...
await self.tool_service.initialize()
await self.prompt_service.initialize()
await self.resource_service.initialize()Option 3: Lazy Initialization
Initialize on first use if not already initialized.
Files Affected
mcpgateway/services/gateway_service.py- Creates uninitialized instancesmcpgateway/main.py- Has properly initialized global singletonsmcpgateway/services/tool_service.pymcpgateway/services/prompt_service.pymcpgateway/services/resource_service.py
Related
- Discovered during review of PR Synchronize Gateway Activation State Across Tools, Prompts, and Resources #2211
- This is pre-existing technical debt (ToolService had this pattern before PromptService/ResourceService were added)
Labels
tech-debtrefactor
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
SHOULDP2: Important but not vital; high-value items that are not crucial for the immediate releaseP2: Important but not vital; high-value items that are not crucial for the immediate releasechoreLinting, formatting, dependency hygiene, or project maintenance choresLinting, formatting, dependency hygiene, or project maintenance chorespythonPython / backend development (FastAPI)Python / backend development (FastAPI)