Skip to content

Commit 1cc895e

Browse files
authored
QSTH-665: add retry_delay parameter (#44)
* feat: add retry_delay parameter * fix: fmt * fix: tests
1 parent e007ab4 commit 1cc895e

File tree

11 files changed

+486
-2
lines changed

11 files changed

+486
-2
lines changed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "qstash"
3-
version = "3.0.0"
3+
version = "3.1.0"
44
description = "Python SDK for Upstash QStash"
55
license = "MIT"
66
authors = ["Upstash <[email protected]>"]

qstash/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
from qstash.client import QStash
33
from qstash.receiver import Receiver
44

5-
__version__ = "3.0.0"
5+
__version__ = "3.1.0"
66
__all__ = ["QStash", "AsyncQStash", "Receiver"]

qstash/asyncio/message.py

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ async def publish(
4343
callback_headers: Optional[Dict[str, str]] = None,
4444
failure_callback_headers: Optional[Dict[str, str]] = None,
4545
retries: Optional[int] = None,
46+
retry_delay: Optional[str] = None,
4647
callback: Optional[str] = None,
4748
failure_callback: Optional[str] = None,
4849
delay: Optional[Union[str, int]] = None,
@@ -74,6 +75,34 @@ async def publish(
7475
callback message.
7576
:param retries: How often should this message be retried in case the destination
7677
API is not available.
78+
:param retry_delay: Delay between retries.
79+
80+
By default, the `retryDelay` is exponential backoff.
81+
More details can be found in: https://upstash.com/docs/qstash/features/retry.
82+
83+
The `retryDelay` option allows you to customize the delay (in milliseconds) between retry attempts when message delivery fails.
84+
85+
You can use mathematical expressions and the following built-in functions to calculate the delay dynamically.
86+
The special variable `retried` represents the current retry attempt count (starting from 0).
87+
88+
Supported functions:
89+
- `pow`
90+
- `sqrt`
91+
- `abs`
92+
- `exp`
93+
- `floor`
94+
- `ceil`
95+
- `round`
96+
- `min`
97+
- `max`
98+
99+
Examples of valid `retryDelay` values:
100+
```py
101+
1000 # 1 second
102+
1000 * (1 + retried) # 1 second multiplied by the current retry attempt
103+
pow(2, retried) # 2 to the power of the current retry attempt
104+
max(10, pow(2, retried)) # The greater of 10 or 2^retried
105+
```
77106
:param callback: A callback url that will be called after each attempt.
78107
:param failure_callback: A failure callback url that will be called when a delivery
79108
is failed, that is when all the defined retries are exhausted.
@@ -109,6 +138,7 @@ async def publish(
109138
callback_headers=callback_headers,
110139
failure_callback_headers=failure_callback_headers,
111140
retries=retries,
141+
retry_delay=retry_delay,
112142
callback=callback,
113143
failure_callback=failure_callback,
114144
delay=delay,
@@ -140,6 +170,7 @@ async def publish_json(
140170
callback_headers: Optional[Dict[str, str]] = None,
141171
failure_callback_headers: Optional[Dict[str, str]] = None,
142172
retries: Optional[int] = None,
173+
retry_delay: Optional[str] = None,
143174
callback: Optional[str] = None,
144175
failure_callback: Optional[str] = None,
145176
delay: Optional[Union[str, int]] = None,
@@ -172,6 +203,34 @@ async def publish_json(
172203
callback message.
173204
:param retries: How often should this message be retried in case the destination
174205
API is not available.
206+
:param retry_delay: Delay between retries.
207+
208+
By default, the `retryDelay` is exponential backoff.
209+
More details can be found in: https://upstash.com/docs/qstash/features/retry.
210+
211+
The `retryDelay` option allows you to customize the delay (in milliseconds) between retry attempts when message delivery fails.
212+
213+
You can use mathematical expressions and the following built-in functions to calculate the delay dynamically.
214+
The special variable `retried` represents the current retry attempt count (starting from 0).
215+
216+
Supported functions:
217+
- `pow`
218+
- `sqrt`
219+
- `abs`
220+
- `exp`
221+
- `floor`
222+
- `ceil`
223+
- `round`
224+
- `min`
225+
- `max`
226+
227+
Examples of valid `retryDelay` values:
228+
```py
229+
1000 # 1 second
230+
1000 * (1 + retried) # 1 second multiplied by the current retry attempt
231+
pow(2, retried) # 2 to the power of the current retry attempt
232+
max(10, pow(2, retried)) # The greater of 10 or 2^retried
233+
```
175234
:param callback: A callback url that will be called after each attempt.
176235
:param failure_callback: A failure callback url that will be called when a delivery
177236
is failed, that is when all the defined retries are exhausted.
@@ -203,6 +262,7 @@ async def publish_json(
203262
callback_headers=callback_headers,
204263
failure_callback_headers=failure_callback_headers,
205264
retries=retries,
265+
retry_delay=retry_delay,
206266
callback=callback,
207267
failure_callback=failure_callback,
208268
delay=delay,
@@ -227,6 +287,7 @@ async def enqueue(
227287
callback_headers: Optional[Dict[str, str]] = None,
228288
failure_callback_headers: Optional[Dict[str, str]] = None,
229289
retries: Optional[int] = None,
290+
retry_delay: Optional[str] = None,
230291
callback: Optional[str] = None,
231292
failure_callback: Optional[str] = None,
232293
deduplication_id: Optional[str] = None,
@@ -257,6 +318,34 @@ async def enqueue(
257318
callback message.
258319
:param retries: How often should this message be retried in case the destination
259320
API is not available.
321+
:param retry_delay: Delay between retries.
322+
323+
By default, the `retryDelay` is exponential backoff.
324+
More details can be found in: https://upstash.com/docs/qstash/features/retry.
325+
326+
The `retryDelay` option allows you to customize the delay (in milliseconds) between retry attempts when message delivery fails.
327+
328+
You can use mathematical expressions and the following built-in functions to calculate the delay dynamically.
329+
The special variable `retried` represents the current retry attempt count (starting from 0).
330+
331+
Supported functions:
332+
- `pow`
333+
- `sqrt`
334+
- `abs`
335+
- `exp`
336+
- `floor`
337+
- `ceil`
338+
- `round`
339+
- `min`
340+
- `max`
341+
342+
Examples of valid `retryDelay` values:
343+
```py
344+
1000 # 1 second
345+
1000 * (1 + retried) # 1 second multiplied by the current retry attempt
346+
pow(2, retried) # 2 to the power of the current retry attempt
347+
max(10, pow(2, retried)) # The greater of 10 or 2^retried
348+
```
260349
:param callback: A callback url that will be called after each attempt.
261350
:param failure_callback: A failure callback url that will be called when a delivery
262351
is failed, that is when all the defined retries are exhausted.
@@ -283,6 +372,7 @@ async def enqueue(
283372
callback_headers=callback_headers,
284373
failure_callback_headers=failure_callback_headers,
285374
retries=retries,
375+
retry_delay=retry_delay,
286376
callback=callback,
287377
failure_callback=failure_callback,
288378
delay=None,
@@ -315,6 +405,7 @@ async def enqueue_json(
315405
callback_headers: Optional[Dict[str, str]] = None,
316406
failure_callback_headers: Optional[Dict[str, str]] = None,
317407
retries: Optional[int] = None,
408+
retry_delay: Optional[str] = None,
318409
callback: Optional[str] = None,
319410
failure_callback: Optional[str] = None,
320411
deduplication_id: Optional[str] = None,
@@ -346,6 +437,34 @@ async def enqueue_json(
346437
callback message.
347438
:param retries: How often should this message be retried in case the destination
348439
API is not available.
440+
:param retry_delay: Delay between retries.
441+
442+
By default, the `retryDelay` is exponential backoff.
443+
More details can be found in: https://upstash.com/docs/qstash/features/retry.
444+
445+
The `retryDelay` option allows you to customize the delay (in milliseconds) between retry attempts when message delivery fails.
446+
447+
You can use mathematical expressions and the following built-in functions to calculate the delay dynamically.
448+
The special variable `retried` represents the current retry attempt count (starting from 0).
449+
450+
Supported functions:
451+
- `pow`
452+
- `sqrt`
453+
- `abs`
454+
- `exp`
455+
- `floor`
456+
- `ceil`
457+
- `round`
458+
- `min`
459+
- `max`
460+
461+
Examples of valid `retryDelay` values:
462+
```py
463+
1000 # 1 second
464+
1000 * (1 + retried) # 1 second multiplied by the current retry attempt
465+
pow(2, retried) # 2 to the power of the current retry attempt
466+
max(10, pow(2, retried)) # The greater of 10 or 2^retried
467+
```
349468
:param callback: A callback url that will be called after each attempt.
350469
:param failure_callback: A failure callback url that will be called when a delivery
351470
is failed, that is when all the defined retries are exhausted.
@@ -369,6 +488,7 @@ async def enqueue_json(
369488
callback_headers=callback_headers,
370489
failure_callback_headers=failure_callback_headers,
371490
retries=retries,
491+
retry_delay=retry_delay,
372492
callback=callback,
373493
failure_callback=failure_callback,
374494
deduplication_id=deduplication_id,

qstash/asyncio/schedule.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ async def create(
2727
callback_headers: Optional[Dict[str, str]] = None,
2828
failure_callback_headers: Optional[Dict[str, str]] = None,
2929
retries: Optional[int] = None,
30+
retry_delay: Optional[str] = None,
3031
callback: Optional[str] = None,
3132
failure_callback: Optional[str] = None,
3233
delay: Optional[Union[str, int]] = None,
@@ -51,6 +52,34 @@ async def create(
5152
callback message.
5253
:param retries: How often should this message be retried in case the destination
5354
API is not available.
55+
:param retry_delay: Delay between retries.
56+
57+
By default, the `retryDelay` is exponential backoff.
58+
More details can be found in: https://upstash.com/docs/qstash/features/retry.
59+
60+
The `retryDelay` option allows you to customize the delay (in milliseconds) between retry attempts when message delivery fails.
61+
62+
You can use mathematical expressions and the following built-in functions to calculate the delay dynamically.
63+
The special variable `retried` represents the current retry attempt count (starting from 0).
64+
65+
Supported functions:
66+
- `pow`
67+
- `sqrt`
68+
- `abs`
69+
- `exp`
70+
- `floor`
71+
- `ceil`
72+
- `round`
73+
- `min`
74+
- `max`
75+
76+
Examples of valid `retryDelay` values:
77+
```py
78+
1000 # 1 second
79+
1000 * (1 + retried) # 1 second multiplied by the current retry attempt
80+
pow(2, retried) # 2 to the power of the current retry attempt
81+
max(10, pow(2, retried)) # The greater of 10 or 2^retried
82+
```
5483
:param callback: A callback url that will be called after each attempt.
5584
:param failure_callback: A failure callback url that will be called when a delivery
5685
is failed, that is when all the defined retries are exhausted.
@@ -77,6 +106,7 @@ async def create(
77106
callback_headers=callback_headers,
78107
failure_callback_headers=failure_callback_headers,
79108
retries=retries,
109+
retry_delay=retry_delay,
80110
callback=callback,
81111
failure_callback=failure_callback,
82112
delay=delay,
@@ -106,6 +136,7 @@ async def create_json(
106136
callback_headers: Optional[Dict[str, str]] = None,
107137
failure_callback_headers: Optional[Dict[str, str]] = None,
108138
retries: Optional[int] = None,
139+
retry_delay: Optional[str] = None,
109140
callback: Optional[str] = None,
110141
failure_callback: Optional[str] = None,
111142
delay: Optional[Union[str, int]] = None,
@@ -131,6 +162,34 @@ async def create_json(
131162
callback message.
132163
:param retries: How often should this message be retried in case the destination
133164
API is not available.
165+
:param retry_delay: Delay between retries.
166+
167+
By default, the `retryDelay` is exponential backoff.
168+
More details can be found in: https://upstash.com/docs/qstash/features/retry.
169+
170+
The `retryDelay` option allows you to customize the delay (in milliseconds) between retry attempts when message delivery fails.
171+
172+
You can use mathematical expressions and the following built-in functions to calculate the delay dynamically.
173+
The special variable `retried` represents the current retry attempt count (starting from 0).
174+
175+
Supported functions:
176+
- `pow`
177+
- `sqrt`
178+
- `abs`
179+
- `exp`
180+
- `floor`
181+
- `ceil`
182+
- `round`
183+
- `min`
184+
- `max`
185+
186+
Examples of valid `retryDelay` values:
187+
```py
188+
1000 # 1 second
189+
1000 * (1 + retried) # 1 second multiplied by the current retry attempt
190+
pow(2, retried) # 2 to the power of the current retry attempt
191+
max(10, pow(2, retried)) # The greater of 10 or 2^retried
192+
```
134193
:param callback: A callback url that will be called after each attempt.
135194
:param failure_callback: A failure callback url that will be called when a delivery
136195
is failed, that is when all the defined retries are exhausted.
@@ -159,6 +218,7 @@ async def create_json(
159218
callback_headers=callback_headers,
160219
failure_callback_headers=failure_callback_headers,
161220
retries=retries,
221+
retry_delay=retry_delay,
162222
callback=callback,
163223
failure_callback=failure_callback,
164224
delay=delay,

qstash/dlq.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@ class DlqMessage(Message):
2929
if the response body contains non-UTF-8 characters.
3030
"""
3131

32+
retry_delay_expression: Optional[str]
33+
"""
34+
The retry delay expression for this DLQ message,
35+
if retry_delay was set when publishing the message.
36+
"""
37+
3238

3339
class DlqFilter(TypedDict, total=False):
3440
message_id: str
@@ -101,6 +107,7 @@ def parse_dlq_message_response(
101107
response_body=response.get("responseBody"),
102108
response_body_base64=response.get("responseBodyBase64"),
103109
flow_control=flow_control,
110+
retry_delay_expression=response.get("retryDelayExpression"),
104111
)
105112

106113

qstash/log.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,12 @@ class Log:
111111
max_retries: Optional[int]
112112
"""Number of retries that should be attempted in case of delivery failure."""
113113

114+
retry_delay_expression: Optional[str]
115+
"""
116+
The retry delay expression for this DLQ message,
117+
if retry_delay was set when publishing the message.
118+
"""
119+
114120
flow_control: Optional[FlowControlProperties]
115121
"""Flow control properties"""
116122

@@ -231,6 +237,7 @@ def parse_logs_response(response: List[Dict[str, Any]]) -> List[Log]:
231237
flow_control=flow_control,
232238
method=event.get("method"),
233239
max_retries=event.get("maxRetries"),
240+
retry_delay_expression=event.get("retryDelayExpression"),
234241
)
235242
)
236243

0 commit comments

Comments
 (0)