@@ -16,12 +16,12 @@ The Dapr client package allows you to interact with other Dapr applications from
1616- [ Go installed] ( https://golang.org/doc/install )
1717
1818
19- ## Import the client package
19+ ## Import the client package
2020``` go
2121import " github.com/dapr/go-sdk/client"
2222```
2323## Error handling
24- Dapr errors are based on [ gRPC's richer error model] ( https://cloud.google.com/apis/design/errors#error_model ) .
24+ Dapr errors are based on [ gRPC's richer error model] ( https://cloud.google.com/apis/design/errors#error_model ) .
2525The following code shows an example of how you can parse and handle the error details:
2626
2727``` go
@@ -54,7 +54,7 @@ if err != nil {
5454 fmt.Printf (" - Url: %s \n " , link.Url )
5555 fmt.Printf (" - Description: %s \n " , link.Description )
5656 }
57-
57+
5858 default :
5959 // Add cases for other types of details you expect
6060 fmt.Printf (" Unhandled error detail type: %v \n " , t)
@@ -102,14 +102,14 @@ import (
102102func ExampleWorkflow (ctx *workflow .WorkflowContext ) (any , error ) {
103103 var output string
104104 input := " world"
105-
105+
106106 if err := ctx.CallActivity (ExampleActivity, workflow.ActivityInput (input)).Await (&output); err != nil {
107107 return nil , err
108108 }
109-
109+
110110 // Print output - "hello world"
111111 fmt.Println (output)
112-
112+
113113 return nil , nil
114114}
115115
@@ -118,7 +118,7 @@ func ExampleActivity(ctx workflow.ActivityContext) (any, error) {
118118 if err := ctx.GetInput (&input); err != nil {
119119 return " " , err
120120 }
121-
121+
122122 return fmt.Sprintf (" hello %s " , input), nil
123123}
124124
@@ -128,39 +128,39 @@ func main() {
128128 if err != nil {
129129 log.Fatalf (" error creating worker: %v " , err)
130130 }
131-
131+
132132 // Register the workflow
133133 w.RegisterWorkflow (ExampleWorkflow)
134-
134+
135135 // Register the activity
136136 w.RegisterActivity (ExampleActivity)
137-
137+
138138 // Start workflow runner
139139 if err := w.Start (); err != nil {
140140 log.Fatal (err)
141141 }
142-
142+
143143 // Create a workflow client
144144 wfClient , err := workflow.NewClient ()
145145 if err != nil {
146146 log.Fatal (err)
147147 }
148-
148+
149149 // Start a new workflow
150150 id , err := wfClient.ScheduleNewWorkflow (context.Background (), " ExampleWorkflow" )
151151 if err != nil {
152152 log.Fatal (err)
153153 }
154-
154+
155155 // Wait for the workflow to complete
156156 metadata , err := wfClient.WaitForWorkflowCompletion (ctx, id)
157157 if err != nil {
158158 log.Fatal (err)
159159 }
160-
160+
161161 // Print workflow status post-completion
162162 fmt.Println (metadata.RuntimeStatus )
163-
163+
164164 // Shutdown Worker
165165 w.Shutdown ()
166166}
@@ -180,7 +180,7 @@ For simple use-cases, Dapr client provides easy to use `Save`, `Get`, `Delete` m
180180``` go
181181ctx := context.Background ()
182182data := []byte (" hello" )
183- store := " my-store" // defined in the component YAML
183+ store := " my-store" // defined in the component YAML
184184
185185// save state with the key key1, default options: strong, last-write
186186if err := client.SaveState (ctx, store, " key1" , data, nil ); err != nil {
@@ -269,7 +269,7 @@ meta := map[string]string{}
269269err := testClient.ExecuteStateTransaction (ctx, store, meta, ops)
270270```
271271
272- Retrieve, filter, and sort key/value data stored in your statestore using ` QueryState ` .
272+ Retrieve, filter, and sort key/value data stored in your statestore using ` QueryState ` .
273273
274274``` go
275275// Define the query string
@@ -340,7 +340,7 @@ func TestActivity(ctx workflow.ActivityContext) (any, error) {
340340 if err := ctx.GetInput (&input); err != nil {
341341 return " " , err
342342 }
343-
343+
344344 // Do something here
345345 return " result" , nil
346346}
@@ -361,18 +361,127 @@ func TestWorkflow(ctx *workflow.WorkflowContext) (any, error) {
361361 if err := ctx.WaitForExternalEvent (" testEvent" , time.Second *60 ).Await (&output); err != nil {
362362 return nil , err
363363 }
364-
364+
365365 if err := ctx.CreateTimer (time.Second ).Await (nil ); err != nil {
366366 return nil , nil
367367 }
368368 return output, nil
369369}
370370```
371371
372- Then compose your application that will use the workflow you've created. [ Refer to the How-To: Author workflows guide] ({{< ref howto-author-workflow.md >}}) for a full walk-through.
372+ Then compose your application that will use the workflow you've created. [ Refer to the How-To: Author workflows guide] ({{< ref howto-author-workflow.md >}}) for a full walk-through.
373373
374374Try out the [ Go SDK workflow example.] ( https://github.com/dapr/go-sdk/blob/main/examples/workflow )
375375
376+ ### Jobs
377+
378+ The Dapr client Go SDK allows you to schedule, get, and delete jobs. Jobs enable you to schedule work to be executed at specific times or intervals.
379+
380+ #### Scheduling a Job
381+
382+ To schedule a new job, use the ` ScheduleJobAlpha1 ` method:
383+
384+ ``` go
385+ import (
386+ " google.golang.org/protobuf/types/known/anypb"
387+ )
388+
389+ // Create job data
390+ data , err := anypb.New (&YourDataStruct{Message: " Hello, Job!" })
391+ if err != nil {
392+ panic (err)
393+ }
394+
395+ // Create a simple job
396+ job := &client.Job {
397+ Name : " my-scheduled-job" ,
398+ Data : data,
399+ DueTime : " 10s" , // Execute in 10 seconds
400+ }
401+
402+ // Schedule the job
403+ err = client.ScheduleJobAlpha1 (ctx, job)
404+ if err != nil {
405+ panic (err)
406+ }
407+ ```
408+
409+ #### Job with Schedule and Repeats
410+
411+ You can create recurring jobs using the ` Schedule ` field with cron expressions:
412+
413+ ``` go
414+ job := &client.Job {
415+ Name : " recurring-job" ,
416+ Data : data,
417+ Schedule : " 0 9 * * *" , // Run at 9 AM every day
418+ Repeats : 10 , // Repeat 10 times
419+ TTL : " 1h" , // Job expires after 1 hour
420+ }
421+
422+ err = client.ScheduleJobAlpha1 (ctx, job)
423+ ```
424+
425+ #### Job with Failure Policy
426+
427+ Configure how jobs should handle failures using failure policies:
428+
429+ ``` go
430+ // Constant retry policy with max retries and interval
431+ maxRetries := uint32 (3 )
432+ retryInterval := 30 * time.Second
433+ failurePolicy := client.NewFailurePolicyConstant (&maxRetries, &retryInterval)
434+
435+ job := &client.Job {
436+ Name : " resilient-job" ,
437+ Data : data,
438+ DueTime : " 2024-01-01T10:00:00Z" ,
439+ FailurePolicy : failurePolicy,
440+ }
441+
442+ err = client.ScheduleJobAlpha1 (ctx, job)
443+ ```
444+
445+ For jobs that should not be retried on failure, use the drop policy:
446+
447+ ``` go
448+ job := &client.Job {
449+ Name : " one-shot-job" ,
450+ Data : data,
451+ DueTime : " 2024-01-01T10:00:00Z" ,
452+ FailurePolicy : client.NewFailurePolicyDrop (),
453+ }
454+
455+ err = client.ScheduleJobAlpha1 (ctx, job)
456+ ```
457+
458+ #### Getting a Job
459+
460+ To get information about a scheduled job:
461+
462+ ``` go
463+ job , err := client.GetJobAlpha1 (ctx, " my-scheduled-job" )
464+ if err != nil {
465+ panic (err)
466+ }
467+
468+ fmt.Printf (" Job: %s , Schedule: %s , Repeats: %d \n " ,
469+ job.Name , job.Schedule , job.Repeats )
470+ ```
471+
472+ #### Deleting a Job
473+
474+ To cancel a scheduled job:
475+
476+ ``` go
477+ err = client.DeleteJobAlpha1 (ctx, " my-scheduled-job" )
478+ if err != nil {
479+ panic (err)
480+ }
481+ ```
482+
483+ For a full guide on jobs, visit [ How-To: Schedule and manage jobs] ({{< ref howto-schedule-and-handle-triggered-jobs.md >}}).
484+
376485### Output Bindings
377486
378487
@@ -522,7 +631,7 @@ func main() {
522631 panic (err)
523632 }
524633 defer client.Close ()
525-
634+
526635 resp , err := client.TryLockAlpha1 (ctx, " lockstore" , &dapr.LockRequest {
527636 LockOwner: " random_id_abc123" ,
528637 ResourceID: " my_file_name" ,
0 commit comments