-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[docs] op retries concepts section (#6818)
sorely overdue section on op retries resolves #6702 ## Test Plan make dev
- Loading branch information
1 parent
9168e73
commit 66ae1c0
Showing
9 changed files
with
156 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
--- | ||
title: Op Retries | Dagster | ||
description: Retry ops on exception using RetryPolicy and RetryRequested | ||
--- | ||
|
||
# Op Retries | ||
|
||
When an exception occurs during op execution, Dagster provides tools to retry that op within the same job run. | ||
|
||
## Relevant APIs | ||
|
||
| Name | Description | | ||
| ----------------------------------------------------- | ----------------------------------------------------------------------------- | | ||
| <PyObject module="dagster" object="RetryRequested" /> | An exception that can be thrown from the body of an op to request a retry | | ||
| <PyObject module="dagster" object="RetryPolicy" /> | A declarative policy to attach which will have retries requested on exception | | ||
| <PyObject module="dagster" object="Backoff" /> | Modification to delay between retries based on attempt number | | ||
| <PyObject module="dagster" object="Jitter" /> | Random modification to delay beween retries | | ||
|
||
## Overview | ||
|
||
In Dagster, code is executed within an [op](/concepts/ops-jobs-graphs/ops). Sometimes this code can fail for transient reasons, and the desired behavior is to retry and run the function again. | ||
|
||
Dagster provides both declarative <PyObject module="dagster" object="RetryPolicy" />s as well as manual <PyObject module="dagster" object="RetryRequested" /> exceptions to enable this behavior. | ||
|
||
## Using Op Retries | ||
|
||
Here we start off with an op that is causing us to have to retry the whole job anytime it fails. | ||
|
||
```python file=/concepts/solids_pipelines/retries.py startafter=problem_start endbefore=problem_end | ||
@op | ||
def problematic(): | ||
fails_sometimes() | ||
``` | ||
|
||
### RetryPolicy | ||
|
||
To get this solid to retry when an exception occurs, we can attach a <PyObject module="dagster" object="RetryRequested" />. | ||
|
||
```python file=/concepts/solids_pipelines/retries.py startafter=policy_start endbefore=policy_end | ||
@op(retry_policy=RetryPolicy()) | ||
def better(): | ||
fails_sometimes() | ||
``` | ||
|
||
This improves the situation, but we may need additional configuration to control how many times to retry and/or how long to wait between each retry. | ||
|
||
```python file=/concepts/solids_pipelines/retries.py startafter=policy2_start endbefore=policy2_end | ||
@op( | ||
retry_policy=RetryPolicy( | ||
max_retries=3, | ||
delay=0.2, # 200ms | ||
backoff=Backoff.EXPONENTIAL, | ||
jitter=Jitter.PLUS_MINUS, | ||
) | ||
) | ||
def even_better(): | ||
fails_sometimes() | ||
``` | ||
|
||
In addition to being able to set the policy directly on the op definition, it can also be set on specific invocations of an op, or a <PyObject module="dagster" object="job" decorator /> to apply to all ops contained within. | ||
|
||
### RetryRequested | ||
|
||
In certain more nuanced situations, we may need to evaluate code to determine if we want to retry or not. For this we can use a manual <PyObject module="dagster" object="RetryRequested" /> exception. | ||
|
||
```python file=/concepts/solids_pipelines/retries.py startafter=manual_start endbefore=manual_end | ||
@op | ||
def manual(): | ||
try: | ||
fails_sometimes() | ||
except Exception as e: | ||
if should_retry(e): | ||
raise RetryRequested(max_retries=1, seconds_to_wait=1) from e | ||
else: | ||
raise | ||
``` | ||
|
||
Using `raise from` will ensure the original exceptions information is captured by Dagster. |
Binary file not shown.
64 changes: 64 additions & 0 deletions
64
examples/docs_snippets/docs_snippets/concepts/solids_pipelines/retries.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
from dagster import Backoff, Jitter, RetryPolicy, RetryRequested, job, op | ||
|
||
|
||
def fails_sometimes(): | ||
raise Exception("jk, its always") | ||
|
||
|
||
def should_retry(_): | ||
return True | ||
|
||
|
||
# problem_start | ||
@op | ||
def problematic(): | ||
fails_sometimes() | ||
|
||
|
||
# problem_end | ||
|
||
# policy_start | ||
@op(retry_policy=RetryPolicy()) | ||
def better(): | ||
fails_sometimes() | ||
|
||
|
||
# policy_end | ||
|
||
# policy2_start | ||
@op( | ||
retry_policy=RetryPolicy( | ||
max_retries=3, | ||
delay=0.2, # 200ms | ||
backoff=Backoff.EXPONENTIAL, | ||
jitter=Jitter.PLUS_MINUS, | ||
) | ||
) | ||
def even_better(): | ||
fails_sometimes() | ||
|
||
|
||
# policy2_end | ||
|
||
|
||
# manual_start | ||
@op | ||
def manual(): | ||
try: | ||
fails_sometimes() | ||
except Exception as e: | ||
if should_retry(e): | ||
raise RetryRequested(max_retries=1, seconds_to_wait=1) from e | ||
else: | ||
raise | ||
|
||
|
||
# manual_end | ||
|
||
|
||
@job | ||
def retry_job(): | ||
problematic() | ||
better() | ||
even_better() | ||
manual() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
66ae1c0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
dagster – ./docs/next
dagster-elementl.vercel.app
dagster.vercel.app
docs.dagster.io
dagster-git-master-elementl.vercel.app
new-docs.dagster.io