Implementing Canary Deployment in an Angular Application
Canary deployments are a powerful technique for releasing new versions of software gradually, minimizing risk and allowing for real-world testing before a full rollout. This challenge asks you to implement a basic canary deployment strategy within an Angular application, allowing a subset of users to experience the new version while the majority continue using the existing one. This is crucial for identifying and addressing issues early, ensuring a smoother user experience.
Problem Description
You need to build an Angular component that displays different content based on a user's assigned "canary" status. The application will have two versions: a "stable" version and a "canary" version. A percentage of users (defined by a configuration value) will be randomly assigned to the canary version. The component should dynamically switch between displaying the stable and canary content based on this user assignment.
What needs to be achieved:
- User Assignment: Implement a mechanism to randomly assign users to either the "stable" or "canary" version based on a configurable percentage (e.g., 5% of users are canaries). This assignment should be deterministic for a given user ID (e.g., using a hash function) to ensure consistent assignment across sessions.
- Content Switching: Create an Angular component that displays different content based on the user's assigned version. For simplicity, the "stable" content will be a simple paragraph, and the "canary" content will be a different paragraph.
- Configuration: The canary percentage should be configurable via a service, allowing for easy adjustment without modifying the component's code.
Key Requirements:
- The component must be reusable and easily integrated into other parts of the application.
- The user assignment logic should be encapsulated within a service.
- The component should reactively update its content when the canary percentage configuration changes.
- The assignment should be deterministic based on a user ID.
Expected Behavior:
- When the application loads, the component should determine the user's version (stable or canary) based on the configured percentage and a unique user ID.
- The component should display the appropriate content (stable or canary) based on the user's version.
- If the canary percentage is changed, the component should re-evaluate the user's version and update the displayed content accordingly.
- Different users should be assigned to either stable or canary versions based on the configured percentage. The same user should always be assigned to the same version.
Edge Cases to Consider:
- Zero Canary Percentage: Handle the case where the canary percentage is set to 0. All users should be assigned to the stable version.
- 100% Canary Percentage: Handle the case where the canary percentage is set to 100. All users should be assigned to the canary version.
- Invalid Canary Percentage: Handle the case where the canary percentage is outside the range of 0-100. You can either default to a safe value (e.g., 50%) or throw an error.
- No User ID: Consider what happens if no user ID is provided. You might default to assigning the user to the stable version or generate a random ID.
Examples
Example 1:
Input: canaryPercentage = 10, userId = "user123"
Output: Component displays "Canary Content" (assuming user123 is assigned to the canary version based on the percentage and hash function)
Explanation: The user is randomly assigned to the canary version based on the 10% probability and their user ID.
Example 2:
Input: canaryPercentage = 0, userId = "user456"
Output: Component displays "Stable Content"
Explanation: The canary percentage is 0, so all users are assigned to the stable version.
Example 3:
Input: canaryPercentage = 50, userId = "user789", canaryPercentage changes to 20
Output: Initially, Component displays "Canary Content" (assuming user789 was assigned to canary initially). After the percentage change, Component displays "Stable Content" (assuming user789 is now assigned to stable).
Explanation: The component reacts to the change in the canary percentage and updates the displayed content accordingly.
Constraints
- Canary Percentage: Must be a number between 0 and 100 (inclusive).
- User ID: Can be a string.
- Performance: The user assignment logic should be efficient enough to not significantly impact the application's performance. Avoid computationally expensive operations.
- Angular Version: Assume Angular 14 or later.
- Deterministic Assignment: The assignment of a user to a version must be deterministic based on their user ID.
Notes
- You can use a simple hash function (e.g.,
hashCode) to generate a deterministic assignment based on the user ID. Consider using a library for more robust hashing if needed. - Use Angular's reactive forms or signals to react to changes in the canary percentage.
- Focus on the core logic of user assignment and content switching. You don't need to implement a full-fledged deployment pipeline.
- Consider using a service to encapsulate the canary percentage configuration and user assignment logic. This promotes reusability and testability.
- Think about how you would test this component to ensure it behaves as expected under different scenarios.