• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

HDT3213 / godis / 15238419529

25 May 2025 01:32PM UTC coverage: 72.019% (-3.7%) from 75.704%
15238419529

push

github

HDT3213
update github actions go version

1 of 1 new or added line in 1 file covered. (100.0%)

1149 existing lines in 29 files now uncovered.

8473 of 11765 relevant lines covered (72.02%)

0.8 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.62
/lib/pool/pool.go
1
package pool
2

3
import (
4
        "errors"
5
        "sync"
6
)
7

8
var (
9
        ErrClosed = errors.New("pool closed")
10
        ErrMax    = errors.New("reach max connection limit")
11
)
12

13
type request chan interface{}
14

15
type Config struct {
16
        MaxIdle   uint
17
        MaxActive uint
18
}
19

20
// Pool stores object for reusing, such as redis connection
21
type Pool struct {
22
        Config
23
        factory     func() (interface{}, error)
24
        finalizer   func(x interface{})
25
        idles       chan interface{}
26
        waitingReqs []request
27
        activeCount uint // increases during creating connection, decrease during destroying connection
28
        mu          sync.Mutex
29
        closed      bool
30
}
31

32
func New(factory func() (interface{}, error), finalizer func(x interface{}), cfg Config) *Pool {
1✔
33
        return &Pool{
1✔
34
                factory:     factory,
1✔
35
                finalizer:   finalizer,
1✔
36
                idles:       make(chan interface{}, cfg.MaxIdle),
1✔
37
                waitingReqs: make([]request, 0),
1✔
38
                Config:      cfg,
1✔
39
        }
1✔
40
}
1✔
41

42
// getOnNoIdle try to create a new connection or waiting for connection being returned
43
// invoker should have pool.mu
44
func (pool *Pool) getOnNoIdle() (interface{}, error) {
1✔
45
        pool.mu.Lock()
1✔
46
        if pool.activeCount >= pool.MaxActive {
2✔
47
                // waiting for connection being returned
1✔
48
                req := make(chan interface{}, 1)
1✔
49
                pool.waitingReqs = append(pool.waitingReqs, req)
1✔
50
                pool.mu.Unlock()
1✔
51
                x, ok := <-req
1✔
52
                if !ok {
1✔
53
                        return nil, ErrMax
×
UNCOV
54
                }
×
55
                return x, nil
1✔
56
        }
57

58
        // create a new connection
59
        pool.activeCount++ // hold a place for new connection
1✔
60
        pool.mu.Unlock()
1✔
61
        x, err := pool.factory()
1✔
62
        if err != nil {
2✔
63
                // create failed return token
1✔
64
                pool.mu.Lock()
1✔
65
                pool.activeCount-- // release the holding place
1✔
66
                pool.mu.Unlock()
1✔
67
                return nil, err
1✔
68
        }
1✔
69
        return x, nil
1✔
70
}
71

72
func (pool *Pool) Get() (interface{}, error) {
1✔
73
        pool.mu.Lock()
1✔
74
        if pool.closed {
2✔
75
                pool.mu.Unlock()
1✔
76
                return nil, ErrClosed
1✔
77
        }
1✔
78
        pool.mu.Unlock()
1✔
79

1✔
80
        select {
1✔
81
        case item := <-pool.idles:
1✔
82
                return item, nil
1✔
83
        default:
1✔
84
                // no pooled item, create one
1✔
85
                return pool.getOnNoIdle()
1✔
86
        }
87
}
88

89
func (pool *Pool) Put(x interface{}) {
1✔
90
        pool.mu.Lock()
1✔
91

1✔
92
        if pool.closed {
2✔
93
                pool.mu.Unlock()
1✔
94
                pool.finalizer(x)
1✔
95
                return
1✔
96
        }
1✔
97

98
        if len(pool.waitingReqs) > 0 {
2✔
99
                req := pool.waitingReqs[0]
1✔
100
                copy(pool.waitingReqs, pool.waitingReqs[1:])
1✔
101
                pool.waitingReqs = pool.waitingReqs[:len(pool.waitingReqs)-1]
1✔
102
                req <- x
1✔
103
                pool.mu.Unlock()
1✔
104
                return
1✔
105
        }
1✔
106

107
        select {
1✔
108
        case pool.idles <- x:
1✔
109
                pool.mu.Unlock()
1✔
110
                return
1✔
111
        default:
1✔
112
                // reach max idle, destroy redundant item
1✔
113
                pool.mu.Unlock()
1✔
114
                pool.activeCount--
1✔
115
                pool.finalizer(x)
1✔
116
        }
117
}
118

119
func (pool *Pool) Close() {
1✔
120
        pool.mu.Lock()
1✔
121
        if pool.closed {
2✔
122
                pool.mu.Unlock()
1✔
123
                return
1✔
124
        }
1✔
125
        pool.closed = true
1✔
126
        close(pool.idles)
1✔
127
        pool.mu.Unlock()
1✔
128

1✔
129
        for x := range pool.idles {
2✔
130
                pool.finalizer(x)
1✔
131
        }
1✔
132
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc