1515This module contains the Job class and related utilities for the Dapr Jobs API.
1616"""
1717
18+ from abc import ABC , abstractmethod
1819from dataclasses import dataclass
1920from typing import Optional
2021
2122from google .protobuf .any_pb2 import Any as GrpcAny
23+ from google .protobuf .duration_pb2 import Duration as GrpcDuration
24+
25+
26+ class FailurePolicy (ABC ):
27+ """Abstract base class for job failure policies."""
28+
29+ @abstractmethod
30+ def _to_proto (self ):
31+ """Convert this failure policy to its protobuf representation."""
32+ pass
33+
34+
35+ class DropFailurePolicy (FailurePolicy ):
36+ """A failure policy that drops the job when it fails to trigger.
37+
38+ When a job fails to trigger, it will be dropped and not retried.
39+ """
40+
41+ def _to_proto (self ):
42+ """Convert to protobuf JobFailurePolicy with drop policy."""
43+ from dapr .proto .common .v1 import common_pb2
44+
45+ return common_pb2 .JobFailurePolicy (drop = common_pb2 .JobFailurePolicyDrop ())
46+
47+
48+ class ConstantFailurePolicy (FailurePolicy ):
49+ """A failure policy that retries the job at constant intervals.
50+
51+ When a job fails to trigger, it will be retried after a constant interval,
52+ up to a maximum number of retries (if specified).
53+
54+ Args:
55+ max_retries (Optional[int]): Maximum number of retries. If None, retries indefinitely.
56+ interval_seconds (Optional[int]): Interval between retries in seconds. Defaults to 30.
57+ """
58+
59+ def __init__ (self , max_retries : Optional [int ] = None , interval_seconds : Optional [int ] = 30 ):
60+ self .max_retries = max_retries
61+ self .interval_seconds = interval_seconds
62+
63+ def _to_proto (self ):
64+ """Convert to protobuf JobFailurePolicy with constant policy."""
65+ from dapr .proto .common .v1 import common_pb2
66+
67+ constant_policy = common_pb2 .JobFailurePolicyConstant ()
68+
69+ if self .interval_seconds is not None :
70+ constant_policy .interval .CopyFrom (GrpcDuration (seconds = self .interval_seconds ))
71+
72+ if self .max_retries is not None :
73+ constant_policy .max_retries = self .max_retries
74+
75+ return common_pb2 .JobFailurePolicy (constant = constant_policy )
2276
2377
2478@dataclass
@@ -43,6 +97,8 @@ class Job:
4397 (calculated from job creation time), or non-repeating ISO8601.
4498 data (Optional[GrpcAny]): The serialized job payload that will be sent to the recipient
4599 when the job is triggered. If not provided, an empty Any proto will be used.
100+ failure_policy (Optional[FailurePolicy]): The failure policy to apply when the job fails
101+ to trigger. If not provided, the default behavior is determined by the Dapr runtime.
46102 overwrite (bool): If true, allows this job to overwrite an existing job with the same name.
47103 """
48104
@@ -52,6 +108,7 @@ class Job:
52108 due_time : Optional [str ] = None
53109 ttl : Optional [str ] = None
54110 data : Optional [GrpcAny ] = None
111+ failure_policy : Optional [FailurePolicy ] = None
55112 overwrite : bool = False
56113
57114 def _get_proto (self ):
@@ -85,6 +142,10 @@ def _get_proto(self):
85142 # Set empty Any proto
86143 job_proto .data .CopyFrom (GrpcAny ())
87144
145+ # Set failure policy if provided
146+ if self .failure_policy :
147+ job_proto .failure_policy .CopyFrom (self .failure_policy ._to_proto ())
148+
88149 return job_proto
89150
90151 @classmethod
@@ -99,12 +160,29 @@ def _from_proto(cls, job_proto):
99160 Returns:
100161 Job: A new Job instance.
101162 """
163+ # Parse failure policy if present
164+ failure_policy : Optional [FailurePolicy ] = None
165+ if job_proto .HasField ('failure_policy' ):
166+ policy = job_proto .failure_policy
167+ if policy .HasField ('drop' ):
168+ failure_policy = DropFailurePolicy ()
169+ elif policy .HasField ('constant' ):
170+ constant = policy .constant
171+ max_retries = constant .max_retries if constant .HasField ('max_retries' ) else None
172+ interval_seconds = None
173+ if constant .HasField ('interval' ):
174+ interval_seconds = constant .interval .seconds
175+ failure_policy = ConstantFailurePolicy (
176+ max_retries = max_retries , interval_seconds = interval_seconds
177+ )
178+
102179 return cls (
103180 name = job_proto .name ,
104181 schedule = job_proto .schedule if job_proto .HasField ('schedule' ) else None ,
105182 repeats = job_proto .repeats if job_proto .HasField ('repeats' ) else None ,
106183 due_time = job_proto .due_time if job_proto .HasField ('due_time' ) else None ,
107184 ttl = job_proto .ttl if job_proto .HasField ('ttl' ) else None ,
108185 data = job_proto .data if job_proto .HasField ('data' ) and job_proto .data .value else None ,
186+ failure_policy = failure_policy ,
109187 overwrite = job_proto .overwrite ,
110188 )
0 commit comments