Skip to content

Commit a69288d

Browse files
Implement retry policy and enhance errored state handling (#326)
* Implement retry policy and enhance errored state handling - Added a retry policy model to manage state retries with configurable methods (fixed, linear, exponential). - Updated the errored state function to create a retry state if the maximum retries have not been reached, improving error recovery. - Enhanced the ErroredResponseModel to include a flag indicating whether a retry state was created. - Modified the GraphTemplate and State models to incorporate retry policy attributes, ensuring better state management. - Improved validation and error handling in the upsert_graph_template function to accommodate the new retry policy structure. * Refactor retry policy and errored state handling - Introduced a new RetryStrategy enum with additional strategies for retrying operations, enhancing flexibility in retry mechanisms. - Updated the RetryPolicyModel to include a compute_delay method for calculating delays based on the selected strategy. - Refactored the errored_state function to utilize the new retry policy structure, improving error handling and state management. - Removed the previous _calculate_enqueue_after function, streamlining the code and enhancing clarity. * Add retry policy documentation and integrate into graph configuration - Introduced a new documentation file for the Retry Policy feature, detailing its configuration and usage within Exosphere. - Updated the `create-graph.md` file to include a section on retry policies, explaining their structure and providing examples. - Modified `mkdocs.yml` to include the new Retry Policy documentation in the navigation, enhancing accessibility for users. * Enhance retry policy error handling and validation - Added validation to ensure the retry count is greater than 0 in the compute_delay method of RetryPolicyModel, raising a ValueError for invalid inputs. - Updated the compute_delay method to correctly calculate delays based on the retry count, adjusting the exponentiation logic. - Refined error handling in the GraphTemplate model by replacing ValueError with HTTPException for better integration with FastAPI, ensuring a 404 response when a graph template is not found. * Update retry policy documentation and examples - Clarified the backoff_factor parameter in the retry policy documentation to specify its unit as milliseconds. - Added retry policy examples in the create-graph.md file to demonstrate its usage in graph template creation and updates. - Ensured consistency in the retry policy structure across documentation, enhancing user understanding and implementation. * Enhance retry policy implementation and documentation - Added the `max_delay` parameter to the retry policy model, allowing users to cap the maximum delay for retry attempts. - Updated the documentation to include detailed explanations of the `max_delay` parameter and its usage in retry strategies. - Improved error handling in the `errored_state` function to log errors when fetching graph templates and raise appropriate HTTP exceptions. - Refactored the `GraphTemplate` model to raise a ValueError instead of an HTTPException when a graph template is not found, enhancing error handling consistency. - Updated the `compute_delay` method in the `RetryPolicyModel` to apply the new delay capping logic across all retry strategies. * Enhance errored state handling with retry state management - Added error handling for duplicate retry states in the `errored_state` function, logging when a retry state already exists. - Introduced a new `fanout_id` field in the `State` model to support unique identification of retry states. - Updated the database index to enforce uniqueness on the combination of relevant state fields, improving data integrity and query performance. * Update state-manager/app/models/db/state.py Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> * Update docs/docs/exosphere/retry-policy.md Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> * Update docs/docs/exosphere/retry-policy.md Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> * Update state-manager/app/controller/errored_state.py Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> * Update state-manager/app/controller/errored_state.py Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> * Update state-manager/app/models/retry_policy_model.py Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> * Update max_delay description in RetryPolicyModel to clarify behavior when set to None * Refine documentation for retry policy and errored state handling - Added missing newlines in the retry policy documentation for better readability. - Removed redundant assignment in the errored state handling to streamline the code logic. * Enhance tests for errored state and upsert graph template - Added retry policy integration in the test cases for errored state handling and upsert graph template. - Updated test fixtures to include additional state attributes for better simulation of state behavior. - Improved error handling assertions in the errored state tests to ensure proper HTTP exceptions are raised. - Mocked retry policy in graph template tests to validate retry behavior during upsert operations. * Refactor test for RetryPolicyModel by removing unnecessary import - Removed the unused 'random' import from the test file for cleaner code. - Updated the instantiation of RetryPolicyModel to improve readability. * Add comprehensive tests for errored state handling in graph templates - Introduced multiple test cases to cover scenarios where graph templates are not found, encounter other errors, or trigger DuplicateKeyError during state creation. - Enhanced error handling assertions to ensure proper HTTP exceptions are raised for missing graph templates and other exceptions. - Validated behavior when maximum retries are reached, ensuring no new state is created in such cases. - Improved overall test coverage for errored state functionality. * Refactor assertions in errored state tests for clarity - Updated assertions in the TestErroredState class to use 'not' instead of '== False' for improved readability. - Ensured consistency in the test code style across multiple test cases. * Remove Kubernetes deployment steps from the publish workflow - Eliminated the deploy-to-k8s job from the publish-state-manager workflow to streamline the CI/CD process. - This change focuses on publishing the image without the deployment step, simplifying the workflow configuration. --------- Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
1 parent 722b208 commit a69288d

14 files changed

Lines changed: 1234 additions & 63 deletions

.github/workflows/publish-state-mangaer.yml

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -111,30 +111,3 @@ jobs:
111111
push: true
112112
tags: ${{ steps.meta.outputs.tags }}
113113
labels: ${{ steps.meta.outputs.labels }}
114-
115-
deploy-to-k8s:
116-
needs: publish-image
117-
runs-on: ubuntu-latest
118-
119-
steps:
120-
- name: Deploy to K8s
121-
run: |
122-
echo "${{ secrets.KUBE_CONFIG }}" | base64 -d > kubeconfig.yaml
123-
export KUBECONFIG=$PWD/kubeconfig.yaml
124-
kubectl get nodes
125-
126-
echo "selected image: ${{ fromJson(needs.publish-image.outputs.json).tags[1] }}"
127-
128-
kubectl set image deployment/exosphere-state-manager exosphere-state-manager=${{fromJson(needs.publish-image.outputs.json).tags[1]}}
129-
130-
kubectl rollout status deployment/exosphere-state-manager
131-
132-
status=$(kubectl rollout status deployment/exosphere-state-manager)
133-
134-
echo "$status"
135-
136-
if [[ "$status" != *"successfully rolled out"* ]]; then
137-
kubectl rollout undo deployment/exosphere-state-manager
138-
echo "❌ Deployment failed. Rolled back." >&2
139-
exit 1
140-
fi

docs/docs/exosphere/create-graph.md

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,13 @@ One can define a graph on Exosphere through a simple json config, which specifie
5151
},
5252
"next_nodes": []
5353
}
54-
]
54+
],
55+
"retry_policy": {
56+
"max_retries": 3,
57+
"strategy": "EXPONENTIAL",
58+
"backoff_factor": 2000,
59+
"exponent": 2
60+
}
5561
}
5662
```
5763

@@ -126,6 +132,24 @@ Use the `${{ ... }}` syntax to map outputs from previous nodes:
126132
- **`${{ node_identifier.outputs.field_name }}`**: Maps output from a specific node
127133
- **`initial`**: Static value provided when the graph is triggered
128134
- **Direct values**: String values. In v1, numbers/booleans must be string-encoded (e.g., "42", "true").
135+
136+
### Retry Policy
137+
138+
Graphs can include a retry policy to handle transient failures automatically. The retry policy is configured at the graph level and applies to all nodes within the graph.
139+
140+
```json
141+
{
142+
"retry_policy": {
143+
"max_retries": 3,
144+
"strategy": "EXPONENTIAL",
145+
"backoff_factor": 2000, // milliseconds
146+
"exponent": 2
147+
}
148+
}
149+
```
150+
151+
For detailed information about retry policies, including all available strategies and configuration options, see the [Retry Policy](retry-policy.md) documentation.
152+
129153
## Creating Graph Templates
130154

131155
The recommended way to create graph templates is using the Exosphere Python SDK, which provides a clean interface to the State Manager API.
@@ -156,7 +180,13 @@ async def create_graph_template():
156180
result = await state_manager.upsert_graph(
157181
graph_name="my-workflow",
158182
graph_nodes=graph_nodes,
159-
secrets=secrets
183+
secrets=secrets,
184+
retry_policy={
185+
"max_retries": 3,
186+
"strategy": "EXPONENTIAL",
187+
"backoff_factor": 2000,
188+
"exponent": 2
189+
}
160190
)
161191
print("Graph template created successfully!")
162192
print(f"Validation status: {result['validation_status']}")
@@ -268,7 +298,13 @@ The state manager validates your graph template:
268298
result = await state_manager.upsert_graph(
269299
graph_name="my-workflow",
270300
graph_nodes=updated_nodes,
271-
secrets=updated_secrets
301+
secrets=updated_secrets,
302+
retry_policy={
303+
"max_retries": 3,
304+
"strategy": "EXPONENTIAL",
305+
"backoff_factor": 2000,
306+
"exponent": 2
307+
}
272308
)
273309
print("Graph template updated successfully!")
274310
print(f"Validation status: {result['validation_status']}")

0 commit comments

Comments
 (0)