-
Notifications
You must be signed in to change notification settings - Fork 6
/
TicketsPool.go
97 lines (84 loc) · 1.71 KB
/
TicketsPool.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
package ConcurrencyCron
import "errors"
/**
*@author wxn
*@project ConcurrencyCron
*@package ConcurrencyCron
*@date 19-8-2 上午10:02
*/
var MAX_POOL_CAPITION uint32 = 10000
//Control the number of concurrent ticket pools
type TicketsPool interface {
//take a ticket
Take()
//return a ticket
Return()
//get the ticket pools' status
Active() bool
//total tickets
Total() uint32
//remain tickets
Remain() uint32
//close pool
Close()
}
type tickets struct {
total uint32 //total tickets
ticket chan struct{} //ticket
active bool //Whether the ticket pool has been activated
}
//Set the maximum number of concurrent
func SetMaxConcurrent(max uint32) (err error) {
if max == 0 {
return errors.New("max concurrent must >0")
}
MAX_POOL_CAPITION = max
return
}
//create a tickets pool
func NewTicketsPool(total uint32) (TicketsPool, error) {
tp := tickets{}
if err := tp.init(total); err != nil {
return nil, err
}
return &tp, nil
}
func (tp *tickets) init(total uint32) (err error) {
if tp.active {
return errors.New("tickets pool is already active")
}
if total == 0 {
return errors.New("tickets num must >0")
}
if total > MAX_POOL_CAPITION {
total = MAX_POOL_CAPITION
}
ch := make(chan struct{}, total)
n := int(total)
for i := 0; i < n; i++ {
ch <- struct{}{}
}
tp.ticket = ch
tp.total = total
tp.active = true
return err
}
func (tp *tickets) Take() {
<-tp.ticket
}
func (tp *tickets) Return() {
tp.ticket <- struct{}{}
}
func (tp *tickets) Active() bool {
return tp.active
}
func (tp *tickets) Total() uint32 {
return tp.total
}
func (tp *tickets) Remain() uint32 {
return uint32(len(tp.ticket))
}
func (tp *tickets) Close() {
tp.active = false
close(tp.ticket)
}