Skip to content

Commit bd8ff5e

Browse files
committed
implement task queue
1 parent 61d8db3 commit bd8ff5e

4 files changed

Lines changed: 115 additions & 3 deletions

File tree

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ require (
1515
github.com/jessevdk/go-flags v1.4.0
1616
github.com/kelseyhightower/envconfig v1.4.0
1717
github.com/lestrrat-go/jwx v1.0.2
18+
github.com/panjf2000/ants/v2 v2.4.3
1819
github.com/patrickmn/go-cache v2.1.0+incompatible
1920
github.com/pion/dtls/v2 v2.0.1-0.20200503085337-8e86b3a7d585
2021
github.com/plgd-dev/go-coap/v2 v2.1.4-0.20201201213140-b8c428d8fccf

go.sum

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ github.com/go-acme/lego v2.7.2+incompatible/go.mod h1:yzMNe9CasVUhkquNvti5nAtPmG
3131
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
3232
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
3333
github.com/go-ocf/go-coap/v2 v2.0.4-0.20200728125043-f38b86f047a7/go.mod h1:X9wVKcaOSx7wBxKcvrWgMQq1R2DNeA7NBLW2osIb8TM=
34-
github.com/go-ocf/kit v0.0.0-20200728130040-4aebdb6982bc h1:VfEKBNg9m0rHO88jv/fOCXW1MN+Z4imfGZhYF0G8484=
3534
github.com/go-ocf/kit v0.0.0-20200728130040-4aebdb6982bc/go.mod h1:TIsoMT/iB7t9P6ahkcOnsmvS83SIJsv9qXRfz/yLf6M=
3635
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
3736
github.com/gofrs/uuid v3.3.0+incompatible h1:8K4tyRfvU1CYPgJsveYFQMhpFd/wXNM7iK6rR7UHz84=
@@ -85,6 +84,8 @@ github.com/lestrrat-go/pdebug v0.0.0-20200204225717-4d6bd78da58d/go.mod h1:B06CS
8584
github.com/miekg/dns v1.1.29 h1:xHBEhR+t5RzcFJjBLJlax2daXOrTYtr9z4WdKEfWFzg=
8685
github.com/miekg/dns v1.1.29/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
8786
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
87+
github.com/panjf2000/ants/v2 v2.4.3 h1:wHghL17YKFanB62QjPQ9o+DuM4q7WrQ7zAhoX8+eBXU=
88+
github.com/panjf2000/ants/v2 v2.4.3/go.mod h1:f6F0NZVFsGCp5A7QW/Zj/m92atWwOkY0OIhFxRNFr4A=
8889
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
8990
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
9091
github.com/pion/dtls/v2 v2.0.1-0.20200503085337-8e86b3a7d585 h1:0v1k/bHrth28TctdEWnrCgLehYn3nOvFAwOwtwmyC34=
@@ -96,7 +97,6 @@ github.com/pion/transport v0.10.0/go.mod h1:BnHnUipd0rZQyTVB2SBGojFHT9CBt5C5TcsJ
9697
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
9798
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
9899
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
99-
github.com/plgd-dev/go-coap/v2 v2.0.4-0.20200819112225-8eb712b901bc h1:kEOQOFCaNd7SDhf17MSQkSB519JeDbwhhrUWBffbsZI=
100100
github.com/plgd-dev/go-coap/v2 v2.0.4-0.20200819112225-8eb712b901bc/go.mod h1:+tCi9Q78H/orWRtpVWyBgrr4vKFo2zYtbbxUllerBp4=
101101
github.com/plgd-dev/go-coap/v2 v2.1.4-0.20201201213140-b8c428d8fccf h1:am6M4meMUVVNItVjtrCZSOVUwHNz95MkkmUn8TjS4Js=
102102
github.com/plgd-dev/go-coap/v2 v2.1.4-0.20201201213140-b8c428d8fccf/go.mod h1:DccQmYY6swDlNlOCQOAX+SXTI9laSfGytskmeeNWmms=
@@ -227,8 +227,8 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8
227227
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
228228
gopkg.in/square/go-jose.v2 v2.5.1 h1:7odma5RETjNHWJnR32wx8t+Io4djHE1PqxCFx3iiZ2w=
229229
gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
230-
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
231230
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
231+
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
232232
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
233233
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
234234
honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=

task/queue/queue.go

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package queue
2+
3+
import (
4+
"container/list"
5+
"fmt"
6+
"sync"
7+
8+
"github.com/panjf2000/ants/v2"
9+
)
10+
11+
// TaskQueue representation of task queue.
12+
type TaskQueue struct {
13+
goPool *ants.Pool
14+
limit int
15+
numParallelRequest int
16+
17+
mutex sync.Mutex
18+
queue *list.List
19+
}
20+
21+
// New creates task queue which is processed by number of workers. Number of task is limited by limit.
22+
func New(numWorkers, limit int) (*TaskQueue, error) {
23+
p, err := ants.NewPool(numWorkers, ants.WithPreAlloc(true), ants.WithNonblocking(true))
24+
if err != nil {
25+
return nil, err
26+
}
27+
return &TaskQueue{
28+
queue: list.New(),
29+
goPool: p,
30+
limit: limit,
31+
numParallelRequest: numWorkers,
32+
}, nil
33+
}
34+
35+
func (q *TaskQueue) appendQueue(tasks []func()) error {
36+
q.mutex.Lock()
37+
defer q.mutex.Unlock()
38+
if q.queue.Len()+len(tasks) > q.limit {
39+
return fmt.Errorf("reached limit of max processed jobs")
40+
}
41+
for _, t := range tasks {
42+
q.queue.PushBack(t)
43+
}
44+
return nil
45+
}
46+
47+
func (q *TaskQueue) popQueue() func() {
48+
q.mutex.Lock()
49+
defer q.mutex.Unlock()
50+
if q.queue.Len() == 0 {
51+
return nil
52+
}
53+
return q.queue.Remove(q.queue.Front()).(func())
54+
}
55+
56+
// Submit appends and execute task by taskQueue.
57+
func (q *TaskQueue) Submit(tasks ...func()) error {
58+
err := q.appendQueue(tasks)
59+
if err != nil {
60+
return err
61+
}
62+
q.goPool.Submit(func() {
63+
for {
64+
task := q.popQueue()
65+
if task == nil {
66+
return
67+
}
68+
task()
69+
}
70+
})
71+
return nil
72+
}
73+
74+
// Release closes queue and release it.
75+
func (q *TaskQueue) Release() {
76+
q.goPool.Release()
77+
q.mutex.Lock()
78+
defer q.mutex.Unlock()
79+
q.queue.Init()
80+
}

task/queue/queue_test.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package queue_test
2+
3+
import (
4+
"testing"
5+
6+
"github.com/plgd-dev/kit/task/queue"
7+
"github.com/stretchr/testify/require"
8+
)
9+
10+
func TestTaskQueue_Submit(t *testing.T) {
11+
_, err := queue.New(-1, 10)
12+
require.Error(t, err)
13+
q, err := queue.New(1, 2)
14+
require.NoError(t, err)
15+
err = q.Submit(func() {}, func() {}, func() {})
16+
require.Error(t, err)
17+
v := make(chan int)
18+
err = q.Submit(func() { v <- 1 }, func() { v <- 2 })
19+
require.NoError(t, err)
20+
d := <-v
21+
require.Equal(t, 1, d)
22+
d = <-v
23+
require.Equal(t, 2, d)
24+
err = q.Submit(func() { v <- 3; v <- 4 })
25+
require.NoError(t, err)
26+
d = <-v
27+
require.Equal(t, 3, d)
28+
q.Release()
29+
d = <-v
30+
require.Equal(t, 4, d)
31+
}

0 commit comments

Comments
 (0)