diff --git a/daprdocs/content/en/developing-applications/building-blocks/jobs/howto-handle-triggered-jobs.md b/daprdocs/content/en/developing-applications/building-blocks/jobs/howto-handle-triggered-jobs.md index fb978ac20..5bb4393f0 100644 --- a/daprdocs/content/en/developing-applications/building-blocks/jobs/howto-handle-triggered-jobs.md +++ b/daprdocs/content/en/developing-applications/building-blocks/jobs/howto-handle-triggered-jobs.md @@ -1,83 +1,3 @@ ---- -type: docs -title: "How-To: Handle triggered jobs" -linkTitle: "How-To: Handle triggered jobs" -weight: 2000 -description: "Learn how to use the jobs API to schedule jobs and handle triggered jobs" ---- - -Now that you've learned what the [jobs building block]({{< ref jobs-overview.md >}}) provides, let's look at an example of how to use the API. This guide follows an example that uses two applications to set up the jobs API: -- `job-scheduler` application: schedules jobs for droid maintenance. -- `job-service` application: handles the triggered jobs that are sent back to the app at their `dueTime`. - - - -## Start the Scheduler service - -When you [run `dapr init` in either self-hosted mode or on Kubernetes]({{< ref install-dapr-selfhost.md >}}), the Dapr Scheduler service is started. - -## Set up the Jobs API - -### Schedule jobs - -In your code, start by setting up and scheduling jobs your project. In the first application, create a new job, including its `name`, `data`, and `dueTime` values. - -{{< tabs "Go" >}} - -{{% codetab %}} - - - -For example, the following `job-scheduler` application code uses Go HTTP client to schedule a job named `R2-D2` with a `"value"` of `"R2-D2:Oil Change"` and a `dueTime` of `"2s"`. - -```go -package main - -import ( - "fmt" - "io" - "log" - "net/http" - "os" - "strings" - "time" -) - -var r2d2JobBody = `{ - "data": { - "@type": "type.googleapis.com/google.protobuf.StringValue", - "value": "R2-D2:Oil Change" - }, - "dueTime": "2s" - }` - -func main() { - //Sleep for 5 seconds to wait for job-service to start - time.Sleep(5 * time.Second) - - daprHost := os.Getenv("DAPR_HOST") - if daprHost == "" { - daprHost = "http://localhost" - } - - schedulerDaprHttpPort := "6280" - - client := http.Client{ - Timeout: 30 * time.Second, - } - - // Schedule a job using the Dapr Jobs API with short dueTime - jobName := "R2-D2" - reqURL := daprHost + ":" + schedulerDaprHttpPort + "/v1.0-alpha1/jobs/" + jobName - - req, err := http.NewRequest("POST", reqURL, strings.NewReader(r2d2JobBody)) - if err != nil { - log.Fatal(err.Error()) - } - - req.Header.Set("Content-Type", "application/json") // Schedule a job using the Dapr Jobs API res, err := client.Do(req) @@ -97,11 +17,7 @@ func main() { } ``` -### Create a job handler - -Next, in a second application, you need to create a job handler that handles the triggered jobs that are sent back to the application. - -For example, the following `job-service` application code has a job handler called `handleJob` to deal with the triggered R2D2 job from earlier, at its `"dueTime": "2s"`. +The following is application code to handle the triggered jobs that are sent back to the application at their dueTime. ```go package main @@ -193,30 +109,18 @@ func setDroidJob(decodedValue string) DroidJob { ## Run the Dapr sidecar -Once you've set up the Jobs API in your application, run the Dapr sidecar. In a terminal window, run the following Dapr command for the `job-service` application. +Once you've set up the Jobs API in your application, run the Dapr sidecar. ```bash // service to handle the triggered jobs // run locally to the directory where the job handler service lives dapr run --app-id job-service --app-port 6200 --dapr-http-port 6280 -- go run . -``` -In a second terminal window, run the following Dapr command to start the `job-scheduler` application. - -```bash // service to schedule a job to be sent back at some point in the future // run locally to the directory where the job scheduler service lives dapr run --app-id job-scheduler --app-port 6300 --dapr-http-port 6380 -- go run . ``` -**Expected output** - -```text - -``` - - - ## Next steps - [Learn more about the Scheduler control plane service]({{< ref "concepts/dapr-services/scheduler.md" >}}) diff --git a/daprdocs/content/en/developing-applications/building-blocks/jobs/howto-schedule-jobs.md b/daprdocs/content/en/developing-applications/building-blocks/jobs/howto-schedule-and-handle-triggered-jobs.md similarity index 58% rename from daprdocs/content/en/developing-applications/building-blocks/jobs/howto-schedule-jobs.md rename to daprdocs/content/en/developing-applications/building-blocks/jobs/howto-schedule-and-handle-triggered-jobs.md index be297dcd9..9d5740d27 100644 --- a/daprdocs/content/en/developing-applications/building-blocks/jobs/howto-schedule-jobs.md +++ b/daprdocs/content/en/developing-applications/building-blocks/jobs/howto-schedule-and-handle-triggered-jobs.md @@ -1,12 +1,12 @@ --- type: docs -title: "How-To: Schedule jobs" -linkTitle: "How-To: Schedule jobs" +title: "How-To: Schedule and handle triggered jobs" +linkTitle: "How-To: Schedule and handle triggered jobs" weight: 2000 -description: "Learn how to use the jobs API to schedule jobs" +description: "Learn how to use the jobs API to schedule and handle triggered jobs" --- -Now that you've learned what the [jobs building block]({{< ref jobs-overview.md >}}) provides, let's look at an example of how to use the API. The code example below describes an application that schedules jobs for a database backup application. +Now that you've learned what the [jobs building block]({{< ref jobs-overview.md >}}) provides, let's look at an example of how to use the API. The code example below describes an application that schedules jobs for a database backup application and handles them at trigger time, also known as the time the job was sent back to the application because it reached it's dueTime. -The Go SDK schedules the job named `prod-db-backup`. Job data is housed in a backup database (`"my-prod-db"`) and are called with `ScheduleJobAlpha1`. For example: +The following Go SDK code sample schedules the job named `prod-db-backup`. Job data is housed in a backup database (`"my-prod-db"`) and is scheduled with `ScheduleJobAlpha1`, +providing the job `data` which is the backup `task` name and `metadata` including the location and database name. The job is scheduled with a `schedule` set and the amount of `repeats` +desired, meaning there is a max amount of times the job should be triggered and sent back to the app. At trigger time, so `@every 1s` according to the `schedule`, this job will be +triggered and sent back to the application up to the max repeats set which is `10`. At the trigger time, the `prodDBBackupHandler` function is called executing the +desired business logic for this job at trigger time. For example: ```go package main @@ -41,13 +45,9 @@ import ( ) func main() { - // Initialize the server server, err := daprs.NewService(":50070") - - if err != nil { - log.Fatalf("failed to start the server: %v", err) - } + // ... if err = server.AddJobEventHandler("prod-db-backup", prodDBBackupHandler); err != nil { log.Fatalf("failed to register job event handler: %v", err) @@ -59,11 +59,7 @@ func main() { log.Fatalf("failed to start server: %v", err) } }() - - // Brief intermission to allow for the server to initialize. - time.Sleep(10 * time.Second) - - ctx := context.Background() + // ... // Set up backup location jobData, err := json.Marshal(&api.DBBackup{ @@ -74,10 +70,7 @@ func main() { }, }, ) - - if err != nil { - panic(err) - } + // ... // Set up the job job := daprc.Job{ @@ -91,36 +84,25 @@ func main() { // Create the client client, err := daprc.NewClient() - if err != nil { - panic(err) - } + // ... + defer client.Close() // Schedule job err = client.ScheduleJobAlpha1(ctx, &job) - if err != nil { - panic(err) - } - - - fmt.Println("schedulejob - success") - - time.Sleep(3 * time.Second) + // ... + fmt.Println("schedule job - success") // Get job resp, err := client.GetJobAlpha1(ctx, "prod-db-backup") - if err != nil { - panic(err) - } - fmt.Printf("getjob - resp: %v\n", resp) // parse - + // ... + fmt.Printf("get job - resp: %v\n", resp) // parse + + // Let test run and then cleanup the job + time.Sleep(20 * time.Second) // Delete job err = client.DeleteJobAlpha1(ctx, "prod-db-backup") - if err != nil { - fmt.Printf("job deletion error: %v\n", err) - } else { - fmt.Println("deletejob - success") - } + // ... if err = server.Stop(); err != nil { log.Fatalf("failed to stop server: %v\n", err) @@ -129,19 +111,18 @@ func main() { var jobCount = 0 - +// at job trigger time this function is called func prodDBBackupHandler(ctx context.Context, job *common.JobEvent) error { var jobData common.Job if err := json.Unmarshal(job.Data, &jobData); err != nil { - return fmt.Errorf("failed to unmarshal job: %v", err) + // ... } decodedPayload, err := base64.StdEncoding.DecodeString(jobData.Value) - if err != nil { - return fmt.Errorf("failed to decode job payload: %v", err) - } + // ... + var jobPayload api.DBBackup if err := json.Unmarshal(decodedPayload, &jobPayload); err != nil { - return fmt.Errorf("failed to unmarshal payload: %v", err) + // ... } fmt.Printf("job %d received:\n type: %v \n typeurl: %v\n value: %v\n extracted payload: %v\n", jobCount, job.JobType, jobData.TypeURL, jobData.Value, jobPayload) jobCount++ @@ -157,10 +138,16 @@ func prodDBBackupHandler(ctx context.Context, job *common.JobEvent) error { ## Run the Dapr sidecar -Once you've set up the Jobs API in your application, run the Dapr sidecar. +Once you've set up the Jobs API in your application, in a terminal window run the Dapr sidecar with the following command. ```bash -dapr run --app-id=distributed-scheduler --metrics-port=9091 --dapr-grpc-port 50001 --app-port 50070 --app-protocol grpc --log-level debug go run ./main.go +dapr run --app-id=distributed-scheduler \ + --metrics-port=9091 \ + --dapr-grpc-port 50001 \ + --app-port 50070 \ + --app-protocol grpc \ + --log-level debug \ + go run ./main.go ``` ## Next steps