2
0
mirror of https://github.com/hibiken/asynq.git synced 2024-09-20 11:05:58 +08:00
golang基于redis的异步队列
Go to file
Ken Hibino b7c0c5d3aa Handle mutated task in RDB's Done, Retry, Kill methods
It is possible that user mutates the task's payload in Handler
(Although doc says the task in handler is read-only). Prevent
ending up in an inconsistent state by handling the case where
user mutates the task.
2019-12-31 08:24:03 -08:00
.github/ISSUE_TEMPLATE Update issue templates 2019-12-27 10:45:45 -08:00
internal Handle mutated task in RDB's Done, Retry, Kill methods 2019-12-31 08:24:03 -08:00
tools/asynqmon Add kill and killall command to asynqmon 2019-12-27 15:17:45 -08:00
.gitignore Change cmd dir to tools 2019-12-06 22:06:59 -08:00
.travis.yml Add .travis.yml 2019-11-30 09:08:14 -08:00
asynq_test.go Use asynqtest helpers in asynq package tests 2019-12-29 10:05:02 -08:00
asynq.go Change NewBackground API to take *redis.Client 2019-12-29 14:55:16 -08:00
background_test.go Add Config type to configure background processing behavior 2019-12-30 07:14:49 -08:00
background.go Minor cleanup 2019-12-30 07:14:49 -08:00
client_test.go Change NewClient API to take *redis.Client 2019-12-29 14:55:16 -08:00
client.go Add Config type to configure background processing behavior 2019-12-30 07:14:49 -08:00
doc.go Add Config type to configure background processing behavior 2019-12-30 07:14:49 -08:00
go.mod Add Get* methods to Payload type 2019-12-20 16:01:32 -08:00
go.sum Add Get* methods to Payload type 2019-12-20 16:01:32 -08:00
LICENSE Add MIT License 2019-11-30 10:21:25 -08:00
payload_test.go Critical fix 2019-12-27 15:17:45 -08:00
payload.go Add Hash method to Payload 2019-12-20 20:14:40 -08:00
processor_test.go Allow user to specify retry delay duration 2019-12-30 07:14:49 -08:00
processor.go Minor cleanup 2019-12-30 07:14:49 -08:00
README.md Add Config type to configure background processing behavior 2019-12-30 07:14:49 -08:00
scheduler_test.go Use asynqtest helpers in asynq package tests 2019-12-29 10:05:02 -08:00
scheduler.go Rename poller to scheduler 2019-12-29 10:05:02 -08:00

Asynq Build Status

Simple, efficent asynchronous task processing library in Go.

Table of Contents

Overview

Asynq provides a simple interface to asynchronous task processing.

Asynq also ships with a CLI to monitor the queues and take manual actions if needed.

Asynq provides:

  • Clear separation of task producer and consumer
  • Ability to schedule task processing in the future
  • Automatic retry of failed tasks with exponential backoff
  • Ability to configure max retry count per task
  • Ability to configure max number of worker goroutines to process tasks
  • Unix signal handling to safely shutdown background processing
  • Enhanced reliability TODO(hibiken): link to wiki page describing this.
  • CLI to query and mutate queues state for mointoring and administrative purposes

Requirements

Dependency Version
Redis v2.6+
Go v1.12+
github.com/go-redis/redis v.7.0+

Installation

go get github.com/hibiken/asynq

Getting Started

  1. Import asynq in your file.
import "github.com/hibiken/asynq"
  1. Create a Client instance to create tasks.
func main() {
    r := redis.NewClient(&redis.Options{
        Addr: "localhost:6379",
    }
    client := asynq.NewClient(r)

    t1 := asynq.Task{
        Type: "send_welcome_email",
        Payload: map[string]interface{}{
          "recipient_id": 1234,
        },
    }

    t2 := asynq.Task{
        Type: "send_reminder_email",
        Payload: map[string]interface{}{
          "recipient_id": 1234,
        },
    }

    // process the task immediately.
    err := client.Process(&t1, time.Now())

    // process the task 24 hours later.
    err = client.Process(&t2, time.Now().Add(24 * time.Hour))

    // specify the max number of retry (default: 25)
    err = client.Process(&t1, time.Now(), asynq.MaxRetry(1))
}
  1. Create a Background instance to process tasks.
func main() {
    r := redis.NewClient(&redis.Options{
        Addr: "localhost:6379",
    }
    bg := asynq.NewBackground(r, &asynq.Config{
        Concurrency: 20,
    })

    // Blocks until signal TERM or INT is received.
    // For graceful shutdown, send signal TSTP to stop processing more tasks
    // before sending TERM or INT signal.
    bg.Run(handler)
}

The argument to (*asynq.Background).Run is an interface asynq.Handler which has one method ProcessTask.

// ProcessTask should return nil if the processing of a task
// is successful.
//
// If ProcessTask return a non-nil error or panics, the task
// will be retried.
type Handler interface {
    ProcessTask(*Task) error
}

The simplest way to implement a handler is to define a function with the same signature and use asynq.HandlerFunc adapter type when passing it to Run.

func handler(t *asynq.Task) error {
    switch t.Type {
    case "send_welcome_email":
        id, err := t.Payload.GetInt("recipient_id")
        if err != nil {
            return err
        }
        fmt.Printf("Send Welcome Email to %d\n", id)

    // ... handle other types ...

    default:
        return fmt.Errorf("unexpected task type: %s", t.Type)
    }
    return nil
}

func main() {
    r := redis.NewClient(&redis.Options{
        Addr: "localhost:6379",
    }
    bg := asynq.NewBackground(r, &asynq.Config{
        Concurrency: 20,
    })

    // Use asynq.HandlerFunc adapter for a handler function
    bg.Run(asynq.HandlerFunc(handler))
}

License

Asynq is released under the MIT license. See LICENSE.