Simple Service Discovery with Python
Service discovery is a crucial component of microservice architectures, allowing services to dynamically locate and communicate with each other without hardcoded addresses. This challenge asks you to implement a basic service discovery system in Python, enabling services to register themselves and other services to query for available instances. This is a simplified version, focusing on core concepts rather than production-ready features.
Problem Description
You are tasked with building a simple service discovery system. The system should allow services to register themselves with a central registry, providing a service name and a unique identifier (instance ID). Other services can then query the registry to find available instances of a specific service. The registry should maintain a list of registered services and their instance IDs.
What needs to be achieved:
- Implement a
ServiceRegistryclass that manages registered services. - Implement methods for registering a service, deregistering a service, and discovering services by name.
- The registry should store service information in a dictionary-like structure.
Key Requirements:
- The
ServiceRegistryshould be able to handle multiple instances of the same service. - The
discover_servicemethod should return a list of instance IDs for a given service name. If no instances are found, it should return an empty list. - The
deregister_servicemethod should remove a specific instance (identified by its instance ID) from the registry.
Expected Behavior:
The system should accurately register, deregister, and discover services based on their names and instance IDs. The discover_service method should return the correct list of instance IDs for a given service.
Edge Cases to Consider:
- Attempting to deregister a service that doesn't exist.
- Attempting to discover a service that has never been registered.
- Handling duplicate instance IDs (consider how to prevent or handle this). For simplicity, assume instance IDs are unique during registration.
Examples
Example 1:
Input:
Registry: Empty
Service A registers with instance ID "A1"
Service B registers with instance ID "A2"
Service C registers with instance ID "B1"
Discover Service A
Output: ["A1", "A2"]
Explanation: Service A has two registered instances, "A1" and "A2".
Example 2:
Input:
Registry: Contains Service A with instance ID "A1"
Deregister Service A with instance ID "A1"
Discover Service A
Output: []
Explanation: Service A's only instance has been deregistered, so the registry is empty for Service A.
Example 3: (Edge Case)
Input:
Registry: Empty
Discover Service D
Output: []
Explanation: Service D has never been registered, so the registry returns an empty list.
Constraints
- Service names and instance IDs should be strings.
- The registry should be able to handle at least 100 registered services concurrently.
- The
discover_servicemethod should return the results in the order they were registered. - Assume instance IDs are unique during registration.
Notes
- You can use a Python dictionary to store the service registry data. The keys of the dictionary can be service names, and the values can be lists of instance IDs.
- Consider the thread-safety of your implementation if you anticipate multiple services registering and discovering services concurrently (though this is not a primary focus for this challenge).
- Focus on the core functionality of registration, deregistration, and discovery. Error handling (e.g., raising exceptions for invalid input) can be kept minimal for this exercise.
- Think about how you would extend this system to include additional information about each service instance (e.g., health status, port number).