@@ -19,15 +19,28 @@ type Option func(*Worker)
19
19
20
20
// Worker for NSQ
21
21
type Worker struct {
22
- addr string
23
- subj string
24
- queue string
25
- client * nats.Conn
26
- stop chan struct {}
27
- stopOnce sync.Once
28
- runFunc func (context.Context , queue.QueuedMessage ) error
29
- logger queue.Logger
30
- stopFlag int32
22
+ addr string
23
+ subj string
24
+ queue string
25
+ client * nats.Conn
26
+ stop chan struct {}
27
+ stopOnce sync.Once
28
+ runFunc func (context.Context , queue.QueuedMessage ) error
29
+ logger queue.Logger
30
+ stopFlag int32
31
+ busyWorkers uint64
32
+ }
33
+
34
+ func (w * Worker ) incBusyWorker () {
35
+ atomic .AddUint64 (& w .busyWorkers , 1 )
36
+ }
37
+
38
+ func (w * Worker ) decBusyWorker () {
39
+ atomic .AddUint64 (& w .busyWorkers , ^ uint64 (0 ))
40
+ }
41
+
42
+ func (w * Worker ) BusyWorkers () uint64 {
43
+ return atomic .LoadUint64 (& w .busyWorkers )
31
44
}
32
45
33
46
// WithAddr setup the addr of NATS
@@ -93,22 +106,26 @@ func NewWorker(opts ...Option) *Worker {
93
106
}
94
107
95
108
// BeforeRun run script before start worker
96
- func (s * Worker ) BeforeRun () error {
109
+ func (w * Worker ) BeforeRun () error {
97
110
return nil
98
111
}
99
112
100
113
// AfterRun run script after start worker
101
- func (s * Worker ) AfterRun () error {
114
+ func (w * Worker ) AfterRun () error {
102
115
return nil
103
116
}
104
117
105
- func (s * Worker ) handle (job queue.Job ) error {
118
+ func (w * Worker ) handle (job queue.Job ) error {
106
119
// create channel with buffer size 1 to avoid goroutine leak
107
120
done := make (chan error , 1 )
108
121
panicChan := make (chan interface {}, 1 )
109
122
startTime := time .Now ()
110
123
ctx , cancel := context .WithTimeout (context .Background (), job .Timeout )
111
- defer cancel ()
124
+ w .incBusyWorker ()
125
+ defer func () {
126
+ cancel ()
127
+ w .decBusyWorker ()
128
+ }()
112
129
113
130
// run the job
114
131
go func () {
@@ -120,15 +137,15 @@ func (s *Worker) handle(job queue.Job) error {
120
137
}()
121
138
122
139
// run custom process function
123
- done <- s .runFunc (ctx , job )
140
+ done <- w .runFunc (ctx , job )
124
141
}()
125
142
126
143
select {
127
144
case p := <- panicChan :
128
145
panic (p )
129
146
case <- ctx .Done (): // timeout reached
130
147
return ctx .Err ()
131
- case <- s .stop : // shutdown service
148
+ case <- w .stop : // shutdown service
132
149
// cancel job
133
150
cancel ()
134
151
@@ -148,10 +165,10 @@ func (s *Worker) handle(job queue.Job) error {
148
165
}
149
166
150
167
// Run start the worker
151
- func (s * Worker ) Run () error {
168
+ func (w * Worker ) Run () error {
152
169
wg := & sync.WaitGroup {}
153
170
panicChan := make (chan interface {}, 1 )
154
- _ , err := s .client .QueueSubscribe (s .subj , s .queue , func (m * nats.Msg ) {
171
+ _ , err := w .client .QueueSubscribe (w .subj , w .queue , func (m * nats.Msg ) {
155
172
wg .Add (1 )
156
173
defer func () {
157
174
wg .Done ()
@@ -163,8 +180,8 @@ func (s *Worker) Run() error {
163
180
var data queue.Job
164
181
_ = json .Unmarshal (m .Data , & data )
165
182
166
- if err := s .handle (data ); err != nil {
167
- s .logger .Error (err )
183
+ if err := w .handle (data ); err != nil {
184
+ w .logger .Error (err )
168
185
}
169
186
})
170
187
if err != nil {
@@ -173,9 +190,9 @@ func (s *Worker) Run() error {
173
190
174
191
// wait close signal
175
192
select {
176
- case <- s .stop :
193
+ case <- w .stop :
177
194
case err := <- panicChan :
178
- s .logger .Error (err )
195
+ w .logger .Error (err )
179
196
}
180
197
181
198
// wait job completed
@@ -185,35 +202,35 @@ func (s *Worker) Run() error {
185
202
}
186
203
187
204
// Shutdown worker
188
- func (s * Worker ) Shutdown () error {
189
- if ! atomic .CompareAndSwapInt32 (& s .stopFlag , 0 , 1 ) {
205
+ func (w * Worker ) Shutdown () error {
206
+ if ! atomic .CompareAndSwapInt32 (& w .stopFlag , 0 , 1 ) {
190
207
return queue .ErrQueueShutdown
191
208
}
192
209
193
- s .stopOnce .Do (func () {
194
- s .client .Close ()
195
- close (s .stop )
210
+ w .stopOnce .Do (func () {
211
+ w .client .Close ()
212
+ close (w .stop )
196
213
})
197
214
return nil
198
215
}
199
216
200
217
// Capacity for channel
201
- func (s * Worker ) Capacity () int {
218
+ func (w * Worker ) Capacity () int {
202
219
return 0
203
220
}
204
221
205
222
// Usage for count of channel usage
206
- func (s * Worker ) Usage () int {
223
+ func (w * Worker ) Usage () int {
207
224
return 0
208
225
}
209
226
210
227
// Queue send notification to queue
211
- func (s * Worker ) Queue (job queue.QueuedMessage ) error {
212
- if atomic .LoadInt32 (& s .stopFlag ) == 1 {
228
+ func (w * Worker ) Queue (job queue.QueuedMessage ) error {
229
+ if atomic .LoadInt32 (& w .stopFlag ) == 1 {
213
230
return queue .ErrQueueShutdown
214
231
}
215
232
216
- err := s .client .Publish (s .subj , job .Bytes ())
233
+ err := w .client .Publish (w .subj , job .Bytes ())
217
234
if err != nil {
218
235
return err
219
236
}
0 commit comments