Skip to content

Commit 608d7bb

Browse files
add handler mux and enqueue client
1 parent 950ba21 commit 608d7bb

2 files changed

Lines changed: 131 additions & 0 deletions

File tree

client.go

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package relay
2+
3+
import (
4+
"context"
5+
"errors"
6+
"time"
7+
8+
"github.com/MohamedAklamaash/relay/internal/base"
9+
"github.com/MohamedAklamaash/relay/internal/rdb"
10+
"github.com/google/uuid"
11+
)
12+
13+
var (
14+
ErrDuplicateTask = rdb.ErrDuplicateTask
15+
ErrTaskIDConflict = rdb.ErrTaskIDConflict
16+
)
17+
18+
type Client struct {
19+
rdb *rdb.RDB
20+
}
21+
22+
func NewClient(r RedisConnOpt) *Client {
23+
return &Client{rdb: rdb.New(r.MakeClient())}
24+
}
25+
26+
func (c *Client) Close() error {
27+
return c.rdb.Close()
28+
}
29+
30+
func (c *Client) Enqueue(task *Task, opts ...Option) (*TaskInfo, error) {
31+
return c.EnqueueContext(context.Background(), task, opts...)
32+
}
33+
34+
func (c *Client) EnqueueContext(ctx context.Context, task *Task, opts ...Option) (*TaskInfo, error) {
35+
if task == nil {
36+
return nil, errors.New("relay: cannot enqueue nil task")
37+
}
38+
o := composeOptions(defaultOptions(), append(task.opts, opts...)...)
39+
40+
id := o.taskID
41+
if id == "" {
42+
id = uuid.NewString()
43+
}
44+
45+
msg := &base.TaskMessage{
46+
ID: id,
47+
Type: task.typename,
48+
Payload: task.payload,
49+
Queue: o.queue,
50+
MaxRetry: o.maxRetry,
51+
Timeout: int64(o.timeout.Seconds()),
52+
Retention: int64(o.retention.Seconds()),
53+
EnqueuedAt: time.Now().Unix(),
54+
}
55+
if !o.deadline.IsZero() {
56+
msg.Deadline = o.deadline.Unix()
57+
}
58+
if o.uniqueTTL > 0 {
59+
msg.UniqueHash = base.HashUnique(o.queue, task.typename, task.payload)
60+
}
61+
62+
if err := c.rdb.Enqueue(ctx, msg, o.processAt, o.uniqueTTL); err != nil {
63+
return nil, err
64+
}
65+
66+
state := "pending"
67+
if o.processAt.After(time.Now()) {
68+
state = "scheduled"
69+
}
70+
return &TaskInfo{
71+
ID: msg.ID,
72+
Queue: msg.Queue,
73+
Type: msg.Type,
74+
Payload: msg.Payload,
75+
State: state,
76+
MaxRetry: msg.MaxRetry,
77+
NextProcessAt: o.processAt,
78+
}, nil
79+
}

handler.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package relay
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"sync"
7+
)
8+
9+
type Handler interface {
10+
ProcessTask(context.Context, *Task) error
11+
}
12+
13+
type HandlerFunc func(context.Context, *Task) error
14+
15+
func (f HandlerFunc) ProcessTask(ctx context.Context, t *Task) error {
16+
return f(ctx, t)
17+
}
18+
19+
type ServeMux struct {
20+
mu sync.RWMutex
21+
m map[string]Handler
22+
}
23+
24+
func NewServeMux() *ServeMux {
25+
return &ServeMux{m: make(map[string]Handler)}
26+
}
27+
28+
func (mux *ServeMux) Handle(pattern string, h Handler) {
29+
mux.mu.Lock()
30+
defer mux.mu.Unlock()
31+
if pattern == "" {
32+
panic("relay: invalid pattern")
33+
}
34+
if h == nil {
35+
panic("relay: nil handler")
36+
}
37+
mux.m[pattern] = h
38+
}
39+
40+
func (mux *ServeMux) HandleFunc(pattern string, fn func(context.Context, *Task) error) {
41+
mux.Handle(pattern, HandlerFunc(fn))
42+
}
43+
44+
func (mux *ServeMux) ProcessTask(ctx context.Context, t *Task) error {
45+
mux.mu.RLock()
46+
h, ok := mux.m[t.Type()]
47+
mux.mu.RUnlock()
48+
if !ok {
49+
return fmt.Errorf("relay: no handler registered for %q", t.Type())
50+
}
51+
return h.ProcessTask(ctx, t)
52+
}

0 commit comments

Comments
 (0)