1
1
package simple
2
2
3
3
import (
4
+ "context"
4
5
"errors"
5
6
"sync"
6
7
@@ -18,10 +19,11 @@ var errMaxCapacity = errors.New("max capacity reached")
18
19
19
20
// Worker for simple queue using channel
20
21
type Worker struct {
21
- queueNotification chan queue.QueuedMessage
22
- runFunc func (queue.QueuedMessage , <- chan struct {}) error
23
- stop chan struct {}
24
- stopOnce sync.Once
22
+ taskQueue chan queue.QueuedMessage
23
+ runFunc func (context.Context , queue.QueuedMessage ) error
24
+ stop chan struct {}
25
+ logger queue.Logger
26
+ stopOnce sync.Once
25
27
}
26
28
27
29
// BeforeRun run script before start worker
@@ -36,36 +38,74 @@ func (s *Worker) AfterRun() error {
36
38
37
39
// Run start the worker
38
40
func (s * Worker ) Run () error {
39
- for notification := range s .queueNotification {
40
- // run custom process function
41
- _ = s .runFunc (notification , s .stop )
41
+ // check queue status
42
+ select {
43
+ case <- s .stop :
44
+ return queue .ErrQueueShutdown
45
+ default :
46
+ }
47
+
48
+ for task := range s .taskQueue {
49
+ done := make (chan struct {})
50
+ v , _ := task .(queue.Job )
51
+ ctx , cancel := context .WithTimeout (context .Background (), v .Timeout )
52
+ // vet doesn't complain if I do this
53
+ _ = cancel
54
+
55
+ // run the job
56
+ go func () {
57
+ // run custom process function
58
+ _ = s .runFunc (ctx , task )
59
+ close (done )
60
+ }()
61
+
62
+ select {
63
+ case <- ctx .Done (): // timeout reached
64
+ if errors .Is (ctx .Err (), context .DeadlineExceeded ) {
65
+ s .logger .Infof ("job timeout: %s" , v .Timeout .String ())
66
+ }
67
+ // wait job
68
+ <- done
69
+ case <- s .stop : // shutdown service
70
+ cancel ()
71
+ // wait job
72
+ <- done
73
+ case <- done : // job finish and continue to work
74
+ }
75
+
42
76
}
43
77
return nil
44
78
}
45
79
46
80
// Shutdown worker
47
81
func (s * Worker ) Shutdown () error {
48
82
s .stopOnce .Do (func () {
49
- close (s .queueNotification )
50
83
close (s .stop )
84
+ close (s .taskQueue )
51
85
})
52
86
return nil
53
87
}
54
88
55
89
// Capacity for channel
56
90
func (s * Worker ) Capacity () int {
57
- return cap (s .queueNotification )
91
+ return cap (s .taskQueue )
58
92
}
59
93
60
94
// Usage for count of channel usage
61
95
func (s * Worker ) Usage () int {
62
- return len (s .queueNotification )
96
+ return len (s .taskQueue )
63
97
}
64
98
65
99
// Queue send notification to queue
66
100
func (s * Worker ) Queue (job queue.QueuedMessage ) error {
67
101
select {
68
- case s .queueNotification <- job :
102
+ case <- s .stop :
103
+ return queue .ErrQueueShutdown
104
+ default :
105
+ }
106
+
107
+ select {
108
+ case s .taskQueue <- job :
69
109
return nil
70
110
default :
71
111
return errMaxCapacity
@@ -75,23 +115,31 @@ func (s *Worker) Queue(job queue.QueuedMessage) error {
75
115
// WithQueueNum setup the capcity of queue
76
116
func WithQueueNum (num int ) Option {
77
117
return func (w * Worker ) {
78
- w .queueNotification = make (chan queue.QueuedMessage , num )
118
+ w .taskQueue = make (chan queue.QueuedMessage , num )
79
119
}
80
120
}
81
121
82
122
// WithRunFunc setup the run func of queue
83
- func WithRunFunc (fn func (queue. QueuedMessage , <- chan struct {} ) error ) Option {
123
+ func WithRunFunc (fn func (context. Context , queue. QueuedMessage ) error ) Option {
84
124
return func (w * Worker ) {
85
125
w .runFunc = fn
86
126
}
87
127
}
88
128
129
+ // WithLogger set custom logger
130
+ func WithLogger (l queue.Logger ) Option {
131
+ return func (w * Worker ) {
132
+ w .logger = l
133
+ }
134
+ }
135
+
89
136
// NewWorker for struc
90
137
func NewWorker (opts ... Option ) * Worker {
91
138
w := & Worker {
92
- queueNotification : make (chan queue.QueuedMessage , defaultQueueSize ),
93
- stop : make (chan struct {}),
94
- runFunc : func (queue.QueuedMessage , <- chan struct {}) error {
139
+ taskQueue : make (chan queue.QueuedMessage , defaultQueueSize ),
140
+ stop : make (chan struct {}),
141
+ logger : queue .NewLogger (),
142
+ runFunc : func (context.Context , queue.QueuedMessage ) error {
95
143
return nil
96
144
},
97
145
}
0 commit comments