2
0
mirror of https://github.com/hibiken/asynq.git synced 2024-11-10 11:31:58 +08:00

Update readme example code

This commit is contained in:
Ken Hibino 2020-03-14 15:51:23 -07:00
parent 77f5a38453
commit 37554fd23c

125
README.md
View File

@ -22,21 +22,90 @@ First, make sure you are running a Redis server locally.
$ redis-server $ redis-server
``` ```
To create and schedule tasks, use `Client` and provide a task and when to enqueue the task. Next, write a package that encapslates task creation and task handling.
```go
package tasks
import (
"fmt"
"github.com/hibiken/asynq"
)
// A list of background task types.
const (
EmailDelivery = "email:deliver"
ImageProcessing = "image:process"
)
// Write function NewXXXTask to create a task.
func NewEmailDeliveryTask(userID int, tmplID string) *asynq.Task {
payload := map[string]interface{}{"user_id": userID, "template_id": tmplID}
return asynq.NewTask(EmailDelivery, payload)
}
func NewImageProcessingTask(src, dst string) *asynq.Task {
payload := map[string]interface{}{"src": src, "dst": dst}
return asynq.NewTask(ImageProcessing, payload)
}
// Write function HandleXXXTask to handle the given task.
// NOTE: It satisfies the asynq.HandlerFunc interface.
func HandleEmailDeliveryTask(ctx context.Context, t *asynq.Task) error {
userID, err := t.Payload.GetInt("user_id")
if err != nil {
return err
}
tmplID, err := t.Payload.GetString("template_id")
if err != nil {
return err
}
fmt.Printf("Send Email to User: user_id = %d, template_id = %s\n", userID, tmplID)
// Email delivery logic ...
return nil
}
func HandleImageProcessingTask(ctx context.Context, t *asynq.Task) error {
src, err := t.Payload.GetString("src")
if err != nil {
return err
}
dst, err := t.Payload.GetString("dst")
if err != nil {
return err
}
fmt.Printf("Process image: src = %s, dst = %s\n", src, dst)
// Image processing logic ...
return nil
}
```
In your web application code, import the above package and use [`Client`](https://pkg.go.dev/github.com/hibiken/asynq?tab=doc#Client) to enqueue tasks to the task queue.
A task will be processed by a background worker as soon as the task gets enqueued. A task will be processed by a background worker as soon as the task gets enqueued.
Scheduled tasks will be stored in Redis and will be enqueued at the specified time. Scheduled tasks will be stored in Redis and will be enqueued at the specified time.
```go ```go
func main() { package main
r := &asynq.RedisClientOpt{
Addr: "127.0.0.1:6379",
}
import (
"time"
"github.com/hibiken/asynq"
"your/app/package/tasks"
)
const redisAddr = "127.0.0.1:6379"
func main() {
r := &asynq.RedisClientOpt{Addr: redisAddr}
c := asynq.NewClient(r) c := asynq.NewClient(r)
// Example 1: Enqueue task to be processed immediately. // Example 1: Enqueue task to be processed immediately.
t := asynq.NewTask("email:signup", map[string]interface{}{"user_id": 42}) t := tasks.NewEmailDeliveryTask(42, "some:template:id")
err := c.Enqueue(t) err := c.Enqueue(t)
if err != nil { if err != nil {
log.Fatal("could not enqueue task: %v", err) log.Fatal("could not enqueue task: %v", err)
@ -45,7 +114,7 @@ func main() {
// Example 2: Schedule task to be processed in the future. // Example 2: Schedule task to be processed in the future.
t = asynq.NewTask("email:reminder", map[string]interface{}{"user_id": 42}) t = tasks.NewEmailDeliveryTask(42, "other:template:id")
err = c.EnqueueIn(24*time.Hour, t) err = c.EnqueueIn(24*time.Hour, t)
if err != nil { if err != nil {
log.Fatal("could not schedule task: %v", err) log.Fatal("could not schedule task: %v", err)
@ -55,7 +124,7 @@ func main() {
// Example 3: Pass options to tune task processing behavior. // Example 3: Pass options to tune task processing behavior.
// Options include MaxRetry, Queue, Timeout, Deadline, etc. // Options include MaxRetry, Queue, Timeout, Deadline, etc.
t = asynq.NewTask("email:reminder", map[string]interface{}{"user_id": 42}) t = tasks.NewImageProcessingTask("some/blobstore/url", "other/blobstore/url")
err = c.Enqueue(t, asynq.MaxRetry(10), asynq.Queue("critical"), asynq.Timeout(time.Minute)) err = c.Enqueue(t, asynq.MaxRetry(10), asynq.Queue("critical"), asynq.Timeout(time.Minute))
if err != nil { if err != nil {
log.Fatal("could not enqueue task: %v", err) log.Fatal("could not enqueue task: %v", err)
@ -63,26 +132,23 @@ func main() {
} }
``` ```
To start the background workers, use `Background` and provide your `Handler` to process the tasks. Next, create a binary to process these tasks in the background.
To start the background workers, use [`Background`](https://pkg.go.dev/github.com/hibiken/asynq?tab=doc#Background) and provide your [`Handler`](https://pkg.go.dev/github.com/hibiken/asynq?tab=doc#Handler) to process the tasks.
`Handler` is an interface with one method `ProcessTask` with the following signature. You can optionally use [`ServeMux`](https://pkg.go.dev/github.com/hibiken/asynq?tab=doc#ServeMux) to create a handler, just as you would with [`"net/http"`](https://golang.org/pkg/net/http/) Handler.
```go ```go
// ProcessTask should return nil if the processing of a task is successful. package main
//
// If ProcessTask return a non-nil error or panics, the task will be retried after delay.
type Handler interface {
ProcessTask(context.Context, *asynq.Task) error
}
```
You can optionally use `ServeMux` to create a handler, just as you would with `"net/http"` Handler. import (
"github.com/hibiken/asynq"
"your/app/package/tasks"
)
const redisAddr = "127.0.0.1:6379"
```go
func main() { func main() {
r := &asynq.RedisClientOpt{ r := &asynq.RedisClientOpt{Addr: redisAddr}
Addr: "127.0.0.1:6379",
}
bg := asynq.NewBackground(r, &asynq.Config{ bg := asynq.NewBackground(r, &asynq.Config{
// Specify how many concurrent workers to use // Specify how many concurrent workers to use
@ -98,23 +164,12 @@ func main() {
// mux maps a type to a handler // mux maps a type to a handler
mux := asynq.NewServeMux() mux := asynq.NewServeMux()
mux.HandleFunc("email:signup", signupEmailHandler) mux.HandleFunc(tasks.EmailDelivery, tasks.HandleEmailDeliveryTask)
mux.HandleFunc("email:reminder", reminderEmailHandler) mux.HandleFunc(tasks.ImageProcessing, tasks.HandleImageProcessingTask)
// ...register other handlers... // ...register other handlers...
bg.Run(mux) bg.Run(mux)
} }
// function with the same signature as the sole method for the Handler interface.
func signupEmailHandler(ctx context.Context, t *asynq.Task) error {
id, err := t.Payload.GetInt("user_id")
if err != nil {
return err
}
fmt.Printf("Send welcome email to user %d\n", id)
// ...your email sending logic...
return nil
}
``` ```
For a more detailed walk-through of the library, see our [Getting Started Guide](https://github.com/hibiken/asynq/wiki/Getting-Started). For a more detailed walk-through of the library, see our [Getting Started Guide](https://github.com/hibiken/asynq/wiki/Getting-Started).