forked from anakin/gopool
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpool.go
110 lines (99 loc) · 1.94 KB
/
pool.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
98
99
100
101
102
103
104
105
106
107
108
109
110
package gopool
import (
"container/list"
"github.com/pkg/errors"
"sync"
)
type Config struct {
InitCount int
MaxCount int
Factory func() (interface{}, error)
Close func(interface{}) error
}
type listPool struct {
mu sync.Mutex
conns *list.List
factory func() (interface{}, error)
close func(interface{}) error
}
type GoPool interface {
Get() (interface{}, error)
Put(interface{}) error
Close(interface{}) error
Release()
Len() int
}
var (
conn interface{}
)
func NewListPool(config *Config) (GoPool, error) {
if config.InitCount < 0 || config.MaxCount <= 0 || config.InitCount > config.MaxCount {
return nil, errors.New("invalid config param")
}
if config.Factory == nil || config.Close == nil {
return nil, errors.New("method invalid")
}
l := &listPool{
conns: list.New(),
factory: config.Factory,
close: config.Close,
}
for i := 0; i < config.InitCount; i++ {
conn, err := l.factory()
if err != nil {
l.Release()
return nil, errors.New("init error")
}
l.conns.PushBack(conn)
}
return l, nil
}
func (l *listPool) getall() *list.List {
l.mu.Lock()
all := l.conns
l.mu.Unlock()
return all
}
func (l *listPool) Get() (interface{}, error) {
ll := l.conns
if ll.Len() <= 0 {
return nil, errors.New("empty list")
}
l.mu.Lock()
conn := ll.Front()
ll.Remove(conn)
l.mu.Unlock()
return conn, nil
}
func (l *listPool) Put(conn interface{}) error {
if conn == nil {
return errors.New("conn error")
}
l.mu.Lock()
l.conns.PushBack(conn)
l.mu.Unlock()
return nil
}
func (l *listPool) Close(conn interface{}) error {
if conn == nil {
return errors.New("conn error")
}
err := l.Close(conn)
if err != nil {
return errors.New("close error")
}
l.mu.Lock()
l.conns.Remove(&list.Element{Value: conn})
l.mu.Unlock()
return nil
}
func (l *listPool) Len() int {
return l.conns.Len()
}
func (l *listPool) Release() {
l.mu.Lock()
l.conns = nil
l.factory = nil
l.close = nil
l.mu.Unlock()
}