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

Change package APIs

This commit is contained in:
Ken Hibino 2019-11-16 14:45:51 -08:00
parent f4d59bece7
commit d2d0d1fde5

View File

@ -1,11 +1,19 @@
package asynq package asynq
/*
TODOs:
- [P0] Task error handling
- [P0] Retry
- [P0] Dead task (retry exausted)
- [P0] Shutdown all workers gracefully when killed
- [P1] Add Support for multiple queues
*/
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"log" "log"
"strconv" "strconv"
"strings"
"time" "time"
"github.com/go-redis/redis/v7" "github.com/go-redis/redis/v7"
@ -26,8 +34,12 @@ type Client struct {
// Task represents a task to be performed. // Task represents a task to be performed.
type Task struct { type Task struct {
Handler string // Type indicates the kind of the task to be performed.
Args []interface{} Type string
// Payload is an arbitrary data needed for task execution.
// The value has to be serializable.
Payload map[string]interface{}
} }
type delayedTask struct { type delayedTask struct {
@ -48,8 +60,13 @@ func NewClient(opt *RedisOpt) *Client {
return &Client{rdb: rdb} return &Client{rdb: rdb}
} }
// Enqueue pushes a given task to the specified queue. // Process enqueues the task to be performed at a given time.
func (c *Client) Enqueue(queue string, task *Task, executeAt time.Time) error { func (c *Client) Process(task *Task, executeAt time.Time) error {
return c.enqueue("default", task, executeAt)
}
// enqueue pushes a given task to the specified queue.
func (c *Client) enqueue(queue string, task *Task, executeAt time.Time) error {
if time.Now().After(executeAt) { if time.Now().After(executeAt) {
return push(c.rdb, queue, task) return push(c.rdb, queue, task)
} }
@ -74,9 +91,6 @@ type Workers struct {
// poolTokens is a counting semaphore to ensure the number of active workers // poolTokens is a counting semaphore to ensure the number of active workers
// does not exceed the limit. // does not exceed the limit.
poolTokens chan struct{} poolTokens chan struct{}
// handlers maps queue name to a handler for that queue's messages.
handlers map[string]func(msg string)
} }
// NewWorkers creates and returns a new Workers. // NewWorkers creates and returns a new Workers.
@ -85,17 +99,14 @@ func NewWorkers(poolSize int, opt *RedisOpt) *Workers {
return &Workers{ return &Workers{
rdb: rdb, rdb: rdb,
poolTokens: make(chan struct{}, poolSize), poolTokens: make(chan struct{}, poolSize),
handlers: make(map[string]func(string)),
} }
} }
// Handle registers a handler function for a given queue. // TaskHandler handles a given task and report any error.
func (w *Workers) Handle(q string, fn func(msg string)) { type TaskHandler func(*Task) error
w.handlers[q] = fn
}
// Run starts the workers and scheduler. // Run starts the workers and scheduler with a given handler.
func (w *Workers) Run() { func (w *Workers) Run(handler TaskHandler) {
go w.pollScheduledTasks() go w.pollScheduledTasks()
for { for {
@ -111,16 +122,17 @@ func (w *Workers) Run() {
q, msg := res[0], res[1] q, msg := res[0], res[1]
fmt.Printf("perform task %v from %s\n", msg, q) fmt.Printf("perform task %v from %s\n", msg, q)
handler, ok := w.handlers[strings.TrimPrefix(q, queuePrefix)] var task Task
if !ok { err = json.Unmarshal([]byte(msg), &task)
log.Printf("no handler found for queue %q\n", strings.TrimPrefix(q, queuePrefix)) if err != nil {
log.Printf("[Servere Error] could not parse json encoded message %s: %v", msg, err)
continue continue
} }
w.poolTokens <- struct{}{} // acquire a token w.poolTokens <- struct{}{} // acquire a token
go func(msg string) { go func(task *Task) {
handler(msg) handler(task)
<-w.poolTokens <-w.poolTokens
}(msg) }(&task)
} }
} }